Merge commit '2d60444331fca1910510038dd3817bea885c2367'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 17 Jul 2014 21:27:40 +0000 (23:27 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 17 Jul 2014 21:27:40 +0000 (23:27 +0200)
* commit '2d60444331fca1910510038dd3817bea885c2367':
  dsputil: Split motion estimation compare bits off into their own context

Conflicts:
configure
libavcodec/Makefile
libavcodec/arm/Makefile
libavcodec/dvenc.c
libavcodec/error_resilience.c
libavcodec/h264.h
libavcodec/h264_slice.c
libavcodec/me_cmp.c
libavcodec/me_cmp.h
libavcodec/motion_est.c
libavcodec/motion_est_template.c
libavcodec/mpeg4videoenc.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo_enc.c
libavcodec/x86/Makefile
libavcodec/x86/me_cmp_init.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
51 files changed:
1  2 
configure
libavcodec/Makefile
libavcodec/ac3enc.c
libavcodec/ac3enc.h
libavcodec/arm/Makefile
libavcodec/arm/me_cmp_armv6.S
libavcodec/arm/me_cmp_init_arm.c
libavcodec/dirac_dwt.c
libavcodec/diracdsp.c
libavcodec/dv.h
libavcodec/dvd_nav_parser.c
libavcodec/dvenc.c
libavcodec/error_resilience.c
libavcodec/error_resilience.h
libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_slice.c
libavcodec/libavcodec.v
libavcodec/me_cmp.c
libavcodec/me_cmp.h
libavcodec/motion-test.c
libavcodec/motion_est.c
libavcodec/motion_est_template.c
libavcodec/mpeg4videoenc.c
libavcodec/mpegvideo.c
libavcodec/mpegvideo.h
libavcodec/mpegvideo_enc.c
libavcodec/mpegvideoencdsp.c
libavcodec/ppc/Makefile
libavcodec/ppc/me_cmp.c
libavcodec/proresdec.h
libavcodec/proresdec2.c
libavcodec/proresdsp.h
libavcodec/proresenc_anatoliy.c
libavcodec/snow.c
libavcodec/snow.h
libavcodec/snow_dwt.c
libavcodec/snowdec.c
libavcodec/snowenc.c
libavcodec/svq1enc.c
libavcodec/svq1enc.h
libavcodec/utils.c
libavcodec/x86/Makefile
libavcodec/x86/me_cmp.asm
libavcodec/x86/me_cmp_init.c
libavfilter/deshake.h
libavfilter/f_select.c
libavfilter/libmpcodecs/vf_fspp.c
libavfilter/vf_deshake.c
libavfilter/vf_mpdecimate.c
libavfilter/vf_spp.c

diff --cc configure
+++ b/configure
@@@ -1804,11 -1533,8 +1804,10 @@@ CONFIG_EXTRA=
      blockdsp
      bswapdsp
      cabac
-     dsputil
      dvprofile
 +    exif
      fdctdsp
 +    frame_thread_encoder
      gcrypt
      golomb
      gplv3
      idctdsp
      intrax8
      lgplv3
 +    llauddsp
 +    llviddsp
      lpc
+     me_cmp
      mpeg_er
      mpegaudio
      mpegaudiodsp
@@@ -2002,9 -1707,7 +2002,8 @@@ threads_if_any="$THREADS_LIST
  
  # subsystems
  dct_select="rdft"
- dsputil_select="fdctdsp idctdsp pixblockdsp"
- error_resilience_select="dsputil"
+ error_resilience_select="me_cmp"
 +frame_thread_encoder_deps="encoders threads"
  intrax8_select="error_resilience"
  mdct_select="fft"
  rdft_select="fft"
@@@ -2011,17 -1715,16 +2011,17 @@@ me_cmp_select="fdctdsp idctdsp pixblock
  mpeg_er_select="error_resilience"
  mpegaudio_select="mpegaudiodsp"
  mpegaudiodsp_select="dct"
- mpegvideo_select="blockdsp dsputil h264chroma hpeldsp idctdsp videodsp"
- mpegvideoenc_select="dsputil mpegvideo pixblockdsp qpeldsp"
 -mpegvideo_select="blockdsp hpeldsp idctdsp me_cmp videodsp"
++mpegvideo_select="blockdsp h264chroma hpeldsp idctdsp me_cmp videodsp"
+ mpegvideoenc_select="me_cmp mpegvideo pixblockdsp qpeldsp"
  
  # 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="ac3_parser ac3dsp bswapdsp mdct"
- ac3_encoder_select="ac3dsp audiodsp dsputil mdct"
- ac3_fixed_encoder_select="ac3dsp audiodsp dsputil mdct"
 +ac3_fixed_decoder_select="ac3_parser ac3dsp bswapdsp mdct"
+ ac3_encoder_select="ac3dsp audiodsp mdct me_cmp"
+ ac3_fixed_encoder_select="ac3dsp audiodsp mdct me_cmp"
  aic_decoder_select="golomb idctdsp"
  alac_encoder_select="lpc"
  als_decoder_select="bswapdsp"
@@@ -2048,12 -1749,11 +2048,12 @@@ cook_decoder_select="audiodsp mdct sine
  cscd_decoder_select="lzo"
  cscd_decoder_suggest="zlib"
  dca_decoder_select="mdct"
- dirac_decoder_select="dsputil dwt golomb videodsp mpegvideoenc"
++dirac_decoder_select="dwt golomb videodsp mpegvideoenc"
  dnxhd_decoder_select="blockdsp idctdsp"
  dnxhd_encoder_select="aandcttables blockdsp fdctdsp idctdsp mpegvideoenc pixblockdsp"
  dvvideo_decoder_select="dvprofile idctdsp"
- dvvideo_encoder_select="dsputil dvprofile fdctdsp pixblockdsp"
+ dvvideo_encoder_select="dvprofile fdctdsp me_cmp pixblockdsp"
 -dxa_decoder_deps="zlib"
 +dxa_decoder_select="zlib"
  eac3_decoder_select="ac3_decoder"
  eac3_encoder_select="ac3_encoder"
  eamad_decoder_select="aandcttables blockdsp bswapdsp idctdsp mpegvideo"
@@@ -2144,11 -1844,8 +2144,11 @@@ prores_decoder_select="blockdsp idctdsp
  prores_encoder_select="fdctdsp"
  qcelp_decoder_select="lsp"
  qdm2_decoder_select="mdct rdft mpegaudiodsp"
 -ra_144_encoder_select="audio_frame_queue lpc"
 +ra_144_encoder_select="audio_frame_queue lpc audiodsp"
 +ra_144_decoder_select="audiodsp"
  ralf_decoder_select="golomb"
- rawvideo_decoder_select="dsputil bswapdsp"
- rtjpeg_decoder_select="dsputil"
++rawvideo_decoder_select="bswapdsp"
++rtjpeg_decoder_select="me_cmp"
  rv10_decoder_select="error_resilience h263_decoder h263dsp mpeg_er"
  rv10_encoder_select="h263_encoder"
  rv20_decoder_select="error_resilience h263_decoder h263dsp mpeg_er"
@@@ -2157,14 -1854,9 +2157,14 @@@ rv30_decoder_select="error_resilience g
  rv40_decoder_select="error_resilience golomb h264chroma h264pred h264qpel mpeg_er mpegvideo videodsp"
  shorten_decoder_select="golomb"
  sipr_decoder_select="lsp"
- snow_decoder_select="dsputil dwt h264qpel hpeldsp rangecoder"
- snow_encoder_select="aandcttables dsputil dwt h264qpel hpeldsp mpegvideoenc rangecoder"
++snow_decoder_select="dwt h264qpel hpeldsp rangecoder"
++snow_encoder_select="aandcttables dwt h264qpel hpeldsp me_cmp mpegvideoenc rangecoder"
 +sonic_decoder_select="golomb rangecoder"
 +sonic_encoder_select="golomb rangecoder"
 +sonic_ls_encoder_select="golomb rangecoder"
  sp5x_decoder_select="mjpeg_decoder"
  svq1_decoder_select="hpeldsp"
- svq1_encoder_select="aandcttables dsputil hpeldsp mpegvideoenc"
+ svq1_encoder_select="aandcttables hpeldsp me_cmp mpegvideoenc"
  svq3_decoder_select="h264_decoder hpeldsp tpeldsp"
  svq3_decoder_suggest="zlib"
  tak_decoder_select="audiodsp"
@@@ -2511,76 -2116,25 +2511,76 @@@ azmq_filter_deps="libzmq
  blackframe_filter_deps="gpl"
  boxblur_filter_deps="gpl"
  bs2b_filter_deps="libbs2b"
 +colormatrix_filter_deps="gpl"
  cropdetect_filter_deps="gpl"
 +dctdnoiz_filter_deps="avcodec"
 +dctdnoiz_filter_select="dct"
  delogo_filter_deps="gpl"
- deshake_filter_select="dsputil"
 +deshake_filter_deps="avcodec"
++deshake_filter_select="me_cmp"
  drawtext_filter_deps="libfreetype"
 +ebur128_filter_deps="gpl"
 +flite_filter_deps="libflite"
  frei0r_filter_deps="frei0r dlopen"
  frei0r_filter_extralibs='$ldl'
  frei0r_src_filter_deps="frei0r dlopen"
  frei0r_src_filter_extralibs='$ldl'
 +geq_filter_deps="gpl"
 +histeq_filter_deps="gpl"
  hqdn3d_filter_deps="gpl"
  interlace_filter_deps="gpl"
- mpdecimate_filter_select="dsputil pixblockdsp"
 +kerndeint_filter_deps="gpl"
 +ladspa_filter_deps="ladspa dlopen"
 +ladspa_filter_extralibs='$ldl'
 +mcdeint_filter_deps="avcodec gpl"
 +movie_filter_deps="avcodec avformat"
 +mp_filter_deps="gpl avcodec swscale inline_asm"
 +mpdecimate_filter_deps="gpl avcodec"
++mpdecimate_filter_select="me_cmp pixblockdsp"
 +mptestsrc_filter_deps="gpl"
 +negate_filter_deps="lut_filter"
 +perspective_filter_deps="gpl"
  ocv_filter_deps="libopencv"
 +owdenoise_filter_deps="gpl"
 +pan_filter_deps="swresample"
 +phase_filter_deps="gpl"
 +pp_filter_deps="gpl postproc"
 +pullup_filter_deps="gpl"
 +removelogo_filter_deps="avcodec avformat swscale"
  resample_filter_deps="avresample"
 +sab_filter_deps="gpl swscale"
  scale_filter_deps="swscale"
- spp_filter_select="dsputil fft idctdsp fdctdsp pixblockdsp"
 +smartblur_filter_deps="gpl swscale"
 +showspectrum_filter_deps="avcodec"
 +showspectrum_filter_select="rdft"
 +spp_filter_deps="gpl avcodec"
++spp_filter_select="fft idctdsp fdctdsp me_cmp pixblockdsp"
 +stereo3d_filter_deps="gpl"
 +subtitles_filter_deps="avformat avcodec libass"
 +super2xsai_filter_deps="gpl"
 +tinterlace_filter_deps="gpl"
 +vidstabdetect_filter_deps="libvidstab"
 +vidstabtransform_filter_deps="libvidstab"
 +pixfmts_super2xsai_test_deps="super2xsai_filter"
 +tinterlace_merge_test_deps="tinterlace_filter"
 +tinterlace_pad_test_deps="tinterlace_filter"
 +zmq_filter_deps="libzmq"
 +zoompan_filter_deps="swscale"
  
  # examples
 +avio_reading="avformat avcodec avutil"
  avcodec_example_deps="avcodec avutil"
 +demuxing_decoding_example_deps="avcodec avformat avutil"
  filter_audio_example_deps="avfilter avutil"
 +filtering_audio_example_deps="avfilter avcodec avformat avutil"
 +filtering_video_example_deps="avfilter avcodec avformat avutil"
  metadata_example_deps="avformat avutil"
 -output_example_deps="avcodec avformat avutil swscale"
 -transcode_aac_example_deps="avcodec avformat avresample"
 +muxing_example_deps="avcodec avformat avutil swscale"
 +remuxing_example_deps="avcodec avformat avutil"
 +resampling_audio_example_deps="avutil swresample"
 +scaling_video_example_deps="avutil swscale"
 +transcode_aac_example_deps="avcodec avformat swresample"
 +transcoding_example_deps="avfilter avcodec avformat avutil"
  
  # libraries, in linking order
  avcodec_deps="avutil"
@@@ -39,12 -34,9 +39,11 @@@ OBJS-$(CONFIG_AUDIODSP)                
  OBJS-$(CONFIG_BLOCKDSP)                += blockdsp.o
  OBJS-$(CONFIG_BSWAPDSP)                += bswapdsp.o
  OBJS-$(CONFIG_CABAC)                   += cabac.o
 +OBJS-$(CONFIG_CRYSTALHD)               += crystalhd.o
  OBJS-$(CONFIG_DCT)                     += dct.o dct32_fixed.o dct32_float.o
- OBJS-$(CONFIG_DSPUTIL)                 += dsputil.o
  OBJS-$(CONFIG_DXVA2)                   += dxva2.o
  OBJS-$(CONFIG_ERROR_RESILIENCE)        += error_resilience.o
 +OBJS-$(CONFIG_EXIF)                    += exif.o tiff_common.o
  OBJS-$(CONFIG_FDCTDSP)                 += fdctdsp.o faandct.o           \
                                            jfdctfst.o jfdctint.o
  FFT-OBJS-$(CONFIG_HARDCODED_TABLES)    += cos_tables.o cos_fixed_tables.o
@@@ -65,11 -56,10 +64,12 @@@ OBJS-$(CONFIG_IDCTDSP)                 
                                            simple_idct.o jrevdct.o
  OBJS-$(CONFIG_INTRAX8)                 += intrax8.o intrax8dsp.o
  OBJS-$(CONFIG_LIBXVID)                 += libxvid_rc.o
 +OBJS-$(CONFIG_LLAUDDSP)                += lossless_audiodsp.o
 +OBJS-$(CONFIG_LLVIDDSP)                += lossless_videodsp.o
  OBJS-$(CONFIG_LPC)                     += lpc.o
  OBJS-$(CONFIG_LSP)                     += lsp.o
 -OBJS-$(CONFIG_MDCT)                    += mdct_fixed.o mdct_float.o
 +OBJS-$(CONFIG_MDCT)                    += mdct_fixed.o mdct_float.o mdct_fixed_32.o
+ OBJS-$(CONFIG_ME_CMP)                  += me_cmp.o
  OBJS-$(CONFIG_MPEG_ER)                 += mpeg_er.o
  OBJS-$(CONFIG_MPEGAUDIO)               += mpegaudio.o mpegaudiodata.o   \
                                            mpegaudiodecheader.o
Simple merge
Simple merge
@@@ -19,7 -18,7 +18,8 @@@ OBJS-$(CONFIG_IDCTDSP)                 
                                            arm/idctdsp_arm.o             \
                                            arm/jrevdct_arm.o             \
                                            arm/simple_idct_arm.o
 +OBJS-$(CONFIG_LLAUDDSP)                += arm/lossless_audiodsp_init_arm.o
+ OBJS-$(CONFIG_ME_CMP)                  += arm/me_cmp_init_arm.o
  OBJS-$(CONFIG_MPEGAUDIODSP)            += arm/mpegaudiodsp_init_arm.o
  OBJS-$(CONFIG_MPEGVIDEO)               += arm/mpegvideo_arm.o
  OBJS-$(CONFIG_MPEGVIDEOENC)            += arm/mpegvideoencdsp_init_arm.o
@@@ -54,8 -53,7 +54,7 @@@ ARMV5TE-OBJS-$(CONFIG_VIDEODSP)        
  ARMV5TE-OBJS-$(CONFIG_MLP_DECODER)     += arm/mlpdsp_armv5te.o
  
  ARMV6-OBJS-$(CONFIG_AC3DSP)            += arm/ac3dsp_armv6.o
- ARMV6-OBJS-$(CONFIG_DSPUTIL)           += arm/dsputil_armv6.o
 -ARMV6-OBJS-$(CONFIG_H264DSP)           += arm/h264dsp_armv6.o
 +ARMV6-OBJS-$(CONFIG_H264DSP)           += arm/startcode_armv6.o
  ARMV6-OBJS-$(CONFIG_HPELDSP)           += arm/hpeldsp_init_armv6.o      \
                                            arm/hpeldsp_armv6.o
  ARMV6-OBJS-$(CONFIG_IDCTDSP)           += arm/idctdsp_init_armv6.o      \
index 0000000,436e20d..fa5a823
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,244 +1,244 @@@
 - * This file is part of Libav.
+ /*
+  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "libavutil/arm/asm.S"
+ function ff_pix_abs16_armv6, export=1
+         ldr             r0,  [sp]
+         push            {r4-r9, lr}
+         mov             r12, #0
+         mov             lr,  #0
+         ldm             r1,  {r4-r7}
+         ldr             r8,  [r2]
+ 1:
+         ldr             r9,  [r2, #4]
+         pld             [r1, r3]
+         usada8          r12, r4,  r8,  r12
+         ldr             r8,  [r2, #8]
+         pld             [r2, r3]
+         usada8          lr,  r5,  r9,  lr
+         ldr             r9,  [r2, #12]
+         usada8          r12, r6,  r8,  r12
+         subs            r0,  r0,  #1
+         usada8          lr,  r7,  r9,  lr
+         beq             2f
+         add             r1,  r1,  r3
+         ldm             r1,  {r4-r7}
+         add             r2,  r2,  r3
+         ldr             r8,  [r2]
+         b               1b
+ 2:
+         add             r0,  r12, lr
+         pop             {r4-r9, pc}
+ endfunc
+ function ff_pix_abs16_x2_armv6, export=1
+         ldr             r12, [sp]
+         push            {r4-r11, lr}
+         mov             r0,  #0
+         mov             lr,  #1
+         orr             lr,  lr,  lr,  lsl #8
+         orr             lr,  lr,  lr,  lsl #16
+ 1:
+         ldr             r8,  [r2]
+         ldr             r9,  [r2, #4]
+         lsr             r10, r8,  #8
+         ldr             r4,  [r1]
+         lsr             r6,  r9,  #8
+         orr             r10, r10, r9,  lsl #24
+         ldr             r5,  [r2, #8]
+         eor             r11, r8,  r10
+         uhadd8          r7,  r8,  r10
+         orr             r6,  r6,  r5,  lsl #24
+         and             r11, r11, lr
+         uadd8           r7,  r7,  r11
+         ldr             r8,  [r1, #4]
+         usada8          r0,  r4,  r7,  r0
+         eor             r7,  r9,  r6
+         lsr             r10, r5,  #8
+         and             r7,  r7,  lr
+         uhadd8          r4,  r9,  r6
+         ldr             r6,  [r2, #12]
+         uadd8           r4,  r4,  r7
+         pld             [r1, r3]
+         orr             r10, r10, r6,  lsl #24
+         usada8          r0,  r8,  r4,  r0
+         ldr             r4,  [r1, #8]
+         eor             r11, r5,  r10
+         ldrb            r7,  [r2, #16]
+         and             r11, r11, lr
+         uhadd8          r8,  r5,  r10
+         ldr             r5,  [r1, #12]
+         uadd8           r8,  r8,  r11
+         pld             [r2, r3]
+         lsr             r10, r6,  #8
+         usada8          r0,  r4,  r8,  r0
+         orr             r10, r10, r7,  lsl #24
+         subs            r12,  r12,  #1
+         eor             r11, r6,  r10
+         add             r1,  r1,  r3
+         uhadd8          r9,  r6,  r10
+         and             r11, r11, lr
+         uadd8           r9,  r9,  r11
+         add             r2,  r2,  r3
+         usada8          r0,  r5,  r9,  r0
+         bgt             1b
+         pop             {r4-r11, pc}
+ endfunc
+ .macro  usad_y2         p0,  p1,  p2,  p3,  n0,  n1,  n2,  n3
+         ldr             \n0, [r2]
+         eor             \n1, \p0, \n0
+         uhadd8          \p0, \p0, \n0
+         and             \n1, \n1, lr
+         ldr             \n2, [r1]
+         uadd8           \p0, \p0, \n1
+         ldr             \n1, [r2, #4]
+         usada8          r0,  \p0, \n2, r0
+         pld             [r1,  r3]
+         eor             \n3, \p1, \n1
+         uhadd8          \p1, \p1, \n1
+         and             \n3, \n3, lr
+         ldr             \p0, [r1, #4]
+         uadd8           \p1, \p1, \n3
+         ldr             \n2, [r2, #8]
+         usada8          r0,  \p1, \p0, r0
+         pld             [r2,  r3]
+         eor             \p0, \p2, \n2
+         uhadd8          \p2, \p2, \n2
+         and             \p0, \p0, lr
+         ldr             \p1, [r1, #8]
+         uadd8           \p2, \p2, \p0
+         ldr             \n3, [r2, #12]
+         usada8          r0,  \p2, \p1, r0
+         eor             \p1, \p3, \n3
+         uhadd8          \p3, \p3, \n3
+         and             \p1, \p1, lr
+         ldr             \p0,  [r1, #12]
+         uadd8           \p3, \p3, \p1
+         add             r1,  r1,  r3
+         usada8          r0,  \p3, \p0,  r0
+         add             r2,  r2,  r3
+ .endm
+ function ff_pix_abs16_y2_armv6, export=1
+         pld             [r1]
+         pld             [r2]
+         ldr             r12, [sp]
+         push            {r4-r11, lr}
+         mov             r0,  #0
+         mov             lr,  #1
+         orr             lr,  lr,  lr,  lsl #8
+         orr             lr,  lr,  lr,  lsl #16
+         ldr             r4,  [r2]
+         ldr             r5,  [r2, #4]
+         ldr             r6,  [r2, #8]
+         ldr             r7,  [r2, #12]
+         add             r2,  r2,  r3
+ 1:
+         usad_y2         r4,  r5,  r6,  r7,  r8,  r9,  r10, r11
+         subs            r12, r12, #2
+         usad_y2         r8,  r9,  r10, r11, r4,  r5,  r6,  r7
+         bgt             1b
+         pop             {r4-r11, pc}
+ endfunc
+ function ff_pix_abs8_armv6, export=1
+         pld             [r2, r3]
+         ldr             r12, [sp]
+         push            {r4-r9, lr}
+         mov             r0,  #0
+         mov             lr,  #0
+         ldrd_post       r4,  r5,  r1,  r3
+ 1:
+         subs            r12, r12, #2
+         ldr             r7,  [r2, #4]
+         ldr_post        r6,  r2,  r3
+         ldrd_post       r8,  r9,  r1,  r3
+         usada8          r0,  r4,  r6,  r0
+         pld             [r2, r3]
+         usada8          lr,  r5,  r7,  lr
+         ldr             r7,  [r2, #4]
+         ldr_post        r6,  r2,  r3
+         beq             2f
+         ldrd_post       r4,  r5,  r1,  r3
+         usada8          r0,  r8,  r6,  r0
+         pld             [r2, r3]
+         usada8          lr,  r9,  r7,  lr
+         b               1b
+ 2:
+         usada8          r0,  r8,  r6,  r0
+         usada8          lr,  r9,  r7,  lr
+         add             r0,  r0,  lr
+         pop             {r4-r9, pc}
+ endfunc
+ function ff_sse16_armv6, export=1
+         ldr             r12, [sp]
+         push            {r4-r9, lr}
+         mov             r0,  #0
+ 1:
+         ldrd            r4,  r5,  [r1]
+         ldr             r8,  [r2]
+         uxtb16          lr,  r4
+         uxtb16          r4,  r4,  ror #8
+         uxtb16          r9,  r8
+         uxtb16          r8,  r8,  ror #8
+         ldr             r7,  [r2, #4]
+         usub16          lr,  lr,  r9
+         usub16          r4,  r4,  r8
+         smlad           r0,  lr,  lr,  r0
+         uxtb16          r6,  r5
+         uxtb16          lr,  r5,  ror #8
+         uxtb16          r8,  r7
+         uxtb16          r9,  r7,  ror #8
+         smlad           r0,  r4,  r4,  r0
+         ldrd            r4,  r5,  [r1, #8]
+         usub16          r6,  r6,  r8
+         usub16          r8,  lr,  r9
+         ldr             r7,  [r2, #8]
+         smlad           r0,  r6,  r6,  r0
+         uxtb16          lr,  r4
+         uxtb16          r4,  r4,  ror #8
+         uxtb16          r9,  r7
+         uxtb16          r7,  r7, ror #8
+         smlad           r0,  r8,  r8,  r0
+         ldr             r8,  [r2, #12]
+         usub16          lr,  lr,  r9
+         usub16          r4,  r4,  r7
+         smlad           r0,  lr,  lr,  r0
+         uxtb16          r6,  r5
+         uxtb16          r5,  r5,  ror #8
+         uxtb16          r9,  r8
+         uxtb16          r8,  r8,  ror #8
+         smlad           r0,  r4,  r4,  r0
+         usub16          r6,  r6,  r9
+         usub16          r5,  r5,  r8
+         smlad           r0,  r6,  r6,  r0
+         add             r1,  r1,  r3
+         add             r2,  r2,  r3
+         subs            r12, r12, #1
+         smlad           r0,  r5,  r5,  r0
+         bgt             1b
+         pop             {r4-r9, pc}
+ endfunc
index 0000000,819d901..eb48b38
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,57 +1,57 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <stdint.h>
+ #include "libavutil/attributes.h"
+ #include "libavutil/cpu.h"
+ #include "libavutil/arm/cpu.h"
+ #include "libavcodec/avcodec.h"
+ #include "libavcodec/me_cmp.h"
+ #include "libavcodec/mpegvideo.h"
+ int ff_pix_abs16_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+                        int line_size, int h);
+ int ff_pix_abs16_x2_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+                           int line_size, int h);
+ int ff_pix_abs16_y2_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+                           int line_size, int h);
+ int ff_pix_abs8_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+                       int line_size, int h);
+ int ff_sse16_armv6(MpegEncContext *s, uint8_t *blk1, uint8_t *blk2,
+                    int line_size, int h);
+ av_cold void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx)
+ {
+     int cpu_flags = av_get_cpu_flags();
+     if (have_armv6(cpu_flags)) {
+         c->pix_abs[0][0] = ff_pix_abs16_armv6;
+         c->pix_abs[0][1] = ff_pix_abs16_x2_armv6;
+         c->pix_abs[0][2] = ff_pix_abs16_y2_armv6;
+         c->pix_abs[1][0] = ff_pix_abs8_armv6;
+         c->sad[0] = ff_pix_abs16_armv6;
+         c->sad[1] = ff_pix_abs8_armv6;
+         c->sse[0] = ff_sse16_armv6;
+     }
+ }
index 51a924b,0000000..96d8bae
mode 100644,000000..100644
--- /dev/null
@@@ -1,572 -1,0 +1,571 @@@
- #include "dsputil.h"
 +/*
 + * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
 + * Copyright (C) 2008 David Conrad
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#include "libavutil/attributes.h"
 +#include "libavutil/avassert.h"
 +#include "libavutil/common.h"
 +#include "dirac_dwt.h"
 +#include "libavcodec/x86/dirac_dwt.h"
 +
 +
 +static inline int mirror(int v, int m)
 +{
 +    while ((unsigned)v > (unsigned)m) {
 +        v = -v;
 +        if (v < 0)
 +            v += 2 * m;
 +    }
 +    return v;
 +}
 +
 +static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
 +                                  int width)
 +{
 +    int i;
 +
 +    for (i = 0; i < width; i++)
 +        b1[i] -= (b0[i] + b2[i] + 2) >> 2;
 +}
 +
 +
 +static av_always_inline
 +void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift)
 +{
 +    int i;
 +    for (i = 0; i < w2; i++) {
 +        dst[2*i  ] = (src0[i] + add) >> shift;
 +        dst[2*i+1] = (src1[i] + add) >> shift;
 +    }
 +}
 +
 +static void horizontal_compose_dirac53i(IDWTELEM *b, IDWTELEM *temp, int w)
 +{
 +    const int w2 = w >> 1;
 +    int x;
 +
 +    temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
 +    for (x = 1; x < w2; x++) {
 +        temp[x     ] = COMPOSE_53iL0     (b[x+w2-1], b[x     ], b[x+w2]);
 +        temp[x+w2-1] = COMPOSE_DIRAC53iH0(temp[x-1], b[x+w2-1], temp[x]);
 +    }
 +    temp[w-1] = COMPOSE_DIRAC53iH0(temp[w2-1], b[w-1], temp[w2-1]);
 +
 +    interleave(b, temp, temp+w2, w2, 1, 1);
 +}
 +
 +static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w)
 +{
 +    const int w2 = w >> 1;
 +    int x;
 +
 +    tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
 +    for (x = 1; x < w2; x++)
 +        tmp[x] = COMPOSE_53iL0(b[x+w2-1], b[x], b[x+w2]);
 +
 +    // extend the edges
 +    tmp[-1]   = tmp[0];
 +    tmp[w2+1] = tmp[w2] = tmp[w2-1];
 +
 +    for (x = 0; x < w2; x++) {
 +        b[2*x  ] = (tmp[x] + 1)>>1;
 +        b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
 +    }
 +}
 +
 +static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w)
 +{
 +    const int w2 = w >> 1;
 +    int x;
 +
 +    tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2  ], b[w2+1]);
 +    tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2+1], b[w2+2]);
 +    for (x = 2; x < w2-1; x++)
 +        tmp[x] = COMPOSE_DD137iL0(b[x+w2-2], b[x+w2-1], b[x], b[x+w2], b[x+w2+1]);
 +    tmp[w2-1] = COMPOSE_DD137iL0(b[w-3], b[w-2], b[w2-1], b[w-1], b[w-1]);
 +
 +    // extend the edges
 +    tmp[-1]   = tmp[0];
 +    tmp[w2+1] = tmp[w2] = tmp[w2-1];
 +
 +    for (x = 0; x < w2; x++) {
 +        b[2*x  ] = (tmp[x] + 1)>>1;
 +        b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
 +    }
 +}
 +
 +static av_always_inline
 +void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *temp, int w, int shift)
 +{
 +    const int w2 = w >> 1;
 +    int x;
 +
 +    for (x = 0; x < w2; x++) {
 +        temp[x   ] = COMPOSE_HAARiL0(b[x   ], b[x+w2]);
 +        temp[x+w2] = COMPOSE_HAARiH0(b[x+w2], temp[x]);
 +    }
 +
 +    interleave(b, temp, temp+w2, w2, shift, shift);
 +}
 +
 +static void horizontal_compose_haar0i(IDWTELEM *b, IDWTELEM *temp, int w)
 +{
 +    horizontal_compose_haari(b, temp, w, 0);
 +}
 +
 +static void horizontal_compose_haar1i(IDWTELEM *b, IDWTELEM *temp, int w)
 +{
 +    horizontal_compose_haari(b, temp, w, 1);
 +}
 +
 +static void horizontal_compose_fidelityi(IDWTELEM *b, IDWTELEM *tmp, int w)
 +{
 +    const int w2 = w >> 1;
 +    int i, x;
 +    IDWTELEM v[8];
 +
 +    for (x = 0; x < w2; x++) {
 +        for (i = 0; i < 8; i++)
 +            v[i] = b[av_clip(x-3+i, 0, w2-1)];
 +        tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x+w2], v[4], v[5], v[6], v[7]);
 +    }
 +
 +    for (x = 0; x < w2; x++) {
 +        for (i = 0; i < 8; i++)
 +            v[i] = tmp[av_clip(x-4+i, 0, w2-1)];
 +        tmp[x+w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], v[5], v[6], v[7]);
 +    }
 +
 +    interleave(b, tmp+w2, tmp, w2, 0, 0);
 +}
 +
 +static void horizontal_compose_daub97i(IDWTELEM *b, IDWTELEM *temp, int w)
 +{
 +    const int w2 = w >> 1;
 +    int x, b0, b1, b2;
 +
 +    temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]);
 +    for (x = 1; x < w2; x++) {
 +        temp[x     ] = COMPOSE_DAUB97iL1(b[x+w2-1], b[x     ], b[x+w2]);
 +        temp[x+w2-1] = COMPOSE_DAUB97iH1(temp[x-1], b[x+w2-1], temp[x]);
 +    }
 +    temp[w-1] = COMPOSE_DAUB97iH1(temp[w2-1], b[w-1], temp[w2-1]);
 +
 +    // second stage combined with interleave and shift
 +    b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]);
 +    b[0] = (b0 + 1) >> 1;
 +    for (x = 1; x < w2; x++) {
 +        b2 = COMPOSE_DAUB97iL0(temp[x+w2-1], temp[x     ], temp[x+w2]);
 +        b1 = COMPOSE_DAUB97iH0(          b0, temp[x+w2-1], b2        );
 +        b[2*x-1] = (b1 + 1) >> 1;
 +        b[2*x  ] = (b2 + 1) >> 1;
 +        b0 = b2;
 +    }
 +    b[w-1] = (COMPOSE_DAUB97iH0(b2, temp[w-1], b2) + 1) >> 1;
 +}
 +
 +static void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
 +{
 +    int i;
 +
 +    for(i=0; i<width; i++){
 +        b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]);
 +    }
 +}
 +
 +static void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
 +                                  IDWTELEM *b3, IDWTELEM *b4, int width)
 +{
 +    int i;
 +
 +    for(i=0; i<width; i++){
 +        b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]);
 +    }
 +}
 +
 +static void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
 +                                      IDWTELEM *b3, IDWTELEM *b4, int width)
 +{
 +    int i;
 +
 +    for(i=0; i<width; i++){
 +        b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]);
 +    }
 +}
 +
 +static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
 +{
 +    int i;
 +
 +    for (i = 0; i < width; i++) {
 +        b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]);
 +        b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]);
 +    }
 +}
 +
 +static void vertical_compose_fidelityiH0(IDWTELEM *dst, IDWTELEM *b[8], int width)
 +{
 +    int i;
 +
 +    for(i=0; i<width; i++){
 +        dst[i] = COMPOSE_FIDELITYiH0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
 +    }
 +}
 +
 +static void vertical_compose_fidelityiL0(IDWTELEM *dst, IDWTELEM *b[8], int width)
 +{
 +    int i;
 +
 +    for(i=0; i<width; i++){
 +        dst[i] = COMPOSE_FIDELITYiL0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
 +    }
 +}
 +
 +static void vertical_compose_daub97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
 +{
 +    int i;
 +
 +    for(i=0; i<width; i++){
 +        b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]);
 +    }
 +}
 +
 +static void vertical_compose_daub97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
 +{
 +    int i;
 +
 +    for(i=0; i<width; i++){
 +        b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]);
 +    }
 +}
 +
 +static void vertical_compose_daub97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
 +{
 +    int i;
 +
 +    for(i=0; i<width; i++){
 +        b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]);
 +    }
 +}
 +
 +static void vertical_compose_daub97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
 +{
 +    int i;
 +
 +    for(i=0; i<width; i++){
 +        b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]);
 +    }
 +}
 +
 +
 +static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, int height, int stride)
 +{
 +    vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
 +    vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
 +    DWTCompose *cs = d->cs + level;
 +
 +    int i, y = cs->y;
 +    IDWTELEM *b[8];
 +    for (i = 0; i < 6; i++)
 +        b[i] = cs->b[i];
 +    b[6] = d->buffer + av_clip(y+5, 0, height-2)*stride;
 +    b[7] = d->buffer + av_clip(y+6, 1, height-1)*stride;
 +
 +        if(y+5<(unsigned)height) vertical_compose_l0(      b[5], b[6], b[7],       width);
 +        if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
 +
 +        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
 +        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
 +
 +    for (i = 0; i < 6; i++)
 +        cs->b[i] = b[i+2];
 +    cs->y += 2;
 +}
 +
 +static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, int height, int stride)
 +{
 +    vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
 +    vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
 +    DWTCompose *cs = d->cs + level;
 +
 +    int y= cs->y;
 +    IDWTELEM *b[4] = { cs->b[0], cs->b[1] };
 +    b[2] = d->buffer + mirror(y+1, height-1)*stride;
 +    b[3] = d->buffer + mirror(y+2, height-1)*stride;
 +
 +        if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
 +        if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
 +
 +        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
 +        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
 +
 +    cs->b[0] = b[2];
 +    cs->b[1] = b[3];
 +    cs->y += 2;
 +}
 +
 +
 +static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, int height, int stride)
 +{
 +    vertical_compose_5tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
 +    vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
 +    DWTCompose *cs = d->cs + level;
 +
 +    int i, y = cs->y;
 +    IDWTELEM *b[10];
 +    for (i = 0; i < 8; i++)
 +        b[i] = cs->b[i];
 +    b[8] = d->buffer + av_clip(y+7, 0, height-2)*stride;
 +    b[9] = d->buffer + av_clip(y+8, 1, height-1)*stride;
 +
 +        if(y+5<(unsigned)height) vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width);
 +        if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
 +
 +        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
 +        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
 +
 +    for (i = 0; i < 8; i++)
 +        cs->b[i] = b[i+2];
 +    cs->y += 2;
 +}
 +
 +// haar makes the assumption that height is even (always true for dirac)
 +static void spatial_compose_haari_dy(DWTContext *d, int level, int width, int height, int stride)
 +{
 +    vertical_compose_2tap vertical_compose = (void*)d->vertical_compose;
 +    int y = d->cs[level].y;
 +    IDWTELEM *b0 = d->buffer + (y-1)*stride;
 +    IDWTELEM *b1 = d->buffer + (y  )*stride;
 +
 +    vertical_compose(b0, b1, width);
 +    d->horizontal_compose(b0, d->temp, width);
 +    d->horizontal_compose(b1, d->temp, width);
 +
 +    d->cs[level].y += 2;
 +}
 +
 +// Don't do sliced idwt for fidelity; the 9 tap filter makes it a bit annoying
 +// Fortunately, this filter isn't used in practice.
 +static void spatial_compose_fidelity(DWTContext *d, int level, int width, int height, int stride)
 +{
 +    vertical_compose_9tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
 +    vertical_compose_9tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
 +    int i, y;
 +    IDWTELEM *b[8];
 +
 +    for (y = 1; y < height; y += 2) {
 +        for (i = 0; i < 8; i++)
 +            b[i] = d->buffer + av_clip((y-7 + 2*i), 0, height-2)*stride;
 +        vertical_compose_h0(d->buffer + y*stride, b, width);
 +    }
 +
 +    for (y = 0; y < height; y += 2) {
 +        for (i = 0; i < 8; i++)
 +            b[i] = d->buffer + av_clip((y-7 + 2*i), 1, height-1)*stride;
 +        vertical_compose_l0(d->buffer + y*stride, b, width);
 +    }
 +
 +    for (y = 0; y < height; y++)
 +        d->horizontal_compose(d->buffer + y*stride, d->temp, width);
 +
 +    d->cs[level].y = height+1;
 +}
 +
 +static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, int height, int stride)
 +{
 +    vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
 +    vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
 +    vertical_compose_3tap vertical_compose_l1 = (void*)d->vertical_compose_l1;
 +    vertical_compose_3tap vertical_compose_h1 = (void*)d->vertical_compose_h1;
 +    DWTCompose *cs = d->cs + level;
 +
 +    int i, y = cs->y;
 +    IDWTELEM *b[6];
 +    for (i = 0; i < 4; i++)
 +        b[i] = cs->b[i];
 +    b[4] = d->buffer + mirror(y+3, height-1)*stride;
 +    b[5] = d->buffer + mirror(y+4, height-1)*stride;
 +
 +        if(y+3<(unsigned)height) vertical_compose_l1(b[3], b[4], b[5], width);
 +        if(y+2<(unsigned)height) vertical_compose_h1(b[2], b[3], b[4], width);
 +        if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
 +        if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
 +
 +        if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
 +        if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
 +
 +    for (i = 0; i < 4; i++)
 +        cs->b[i] = b[i+2];
 +    cs->y += 2;
 +}
 +
 +
 +static void spatial_compose97i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
 +{
 +    cs->b[0] = buffer + mirror(-3-1, height-1)*stride;
 +    cs->b[1] = buffer + mirror(-3  , height-1)*stride;
 +    cs->b[2] = buffer + mirror(-3+1, height-1)*stride;
 +    cs->b[3] = buffer + mirror(-3+2, height-1)*stride;
 +    cs->y = -3;
 +}
 +
 +static void spatial_compose53i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
 +{
 +    cs->b[0] = buffer + mirror(-1-1, height-1)*stride;
 +    cs->b[1] = buffer + mirror(-1  , height-1)*stride;
 +    cs->y = -1;
 +}
 +
 +static void spatial_compose_dd97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
 +{
 +    cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
 +    cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
 +    cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
 +    cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
 +    cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
 +    cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
 +    cs->y = -5;
 +}
 +
 +static void spatial_compose_dd137i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
 +{
 +    cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
 +    cs->b[1] = buffer + av_clip(-5  , 1, height-1)*stride;
 +    cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
 +    cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
 +    cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
 +    cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
 +    cs->b[6] = buffer + av_clip(-5+5, 0, height-2)*stride;
 +    cs->b[7] = buffer + av_clip(-5+6, 1, height-1)*stride;
 +    cs->y = -5;
 +}
 +
 +int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
 +                          int stride, enum dwt_type type, int decomposition_count,
 +                          IDWTELEM *temp)
 +{
 +    int level;
 +
 +    d->buffer = buffer;
 +    d->width = width;
 +    d->height = height;
 +    d->stride = stride;
 +    d->decomposition_count = decomposition_count;
 +    d->temp = temp + 8;
 +
 +    for(level=decomposition_count-1; level>=0; level--){
 +        int hl = height >> level;
 +        int stride_l = stride << level;
 +
 +        switch(type){
 +        case DWT_DIRAC_DD9_7:
 +            spatial_compose_dd97i_init(d->cs+level, buffer, hl, stride_l);
 +            break;
 +        case DWT_DIRAC_LEGALL5_3:
 +            spatial_compose53i_init2(d->cs+level, buffer, hl, stride_l);
 +            break;
 +        case DWT_DIRAC_DD13_7:
 +            spatial_compose_dd137i_init(d->cs+level, buffer, hl, stride_l);
 +            break;
 +        case DWT_DIRAC_HAAR0:
 +        case DWT_DIRAC_HAAR1:
 +            d->cs[level].y = 1;
 +            break;
 +        case DWT_DIRAC_DAUB9_7:
 +            spatial_compose97i_init2(d->cs+level, buffer, hl, stride_l);
 +            break;
 +        default:
 +            d->cs[level].y = 0;
 +            break;
 +        }
 +    }
 +
 +    switch (type) {
 +    case DWT_DIRAC_DD9_7:
 +        d->spatial_compose = spatial_compose_dd97i_dy;
 +        d->vertical_compose_l0 = (void*)vertical_compose53iL0;
 +        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
 +        d->horizontal_compose = horizontal_compose_dd97i;
 +        d->support = 7;
 +        break;
 +    case DWT_DIRAC_LEGALL5_3:
 +        d->spatial_compose = spatial_compose_dirac53i_dy;
 +        d->vertical_compose_l0 = (void*)vertical_compose53iL0;
 +        d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0;
 +        d->horizontal_compose = horizontal_compose_dirac53i;
 +        d->support = 3;
 +        break;
 +    case DWT_DIRAC_DD13_7:
 +        d->spatial_compose = spatial_compose_dd137i_dy;
 +        d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0;
 +        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
 +        d->horizontal_compose = horizontal_compose_dd137i;
 +        d->support = 7;
 +        break;
 +    case DWT_DIRAC_HAAR0:
 +    case DWT_DIRAC_HAAR1:
 +        d->spatial_compose = spatial_compose_haari_dy;
 +        d->vertical_compose = (void*)vertical_compose_haar;
 +        if (type == DWT_DIRAC_HAAR0)
 +            d->horizontal_compose = horizontal_compose_haar0i;
 +        else
 +            d->horizontal_compose = horizontal_compose_haar1i;
 +        d->support = 1;
 +        break;
 +    case DWT_DIRAC_FIDELITY:
 +        d->spatial_compose = spatial_compose_fidelity;
 +        d->vertical_compose_l0 = (void*)vertical_compose_fidelityiL0;
 +        d->vertical_compose_h0 = (void*)vertical_compose_fidelityiH0;
 +        d->horizontal_compose = horizontal_compose_fidelityi;
 +        d->support = 0; // not really used
 +        break;
 +    case DWT_DIRAC_DAUB9_7:
 +        d->spatial_compose = spatial_compose_daub97i_dy;
 +        d->vertical_compose_l0 = (void*)vertical_compose_daub97iL0;
 +        d->vertical_compose_h0 = (void*)vertical_compose_daub97iH0;
 +        d->vertical_compose_l1 = (void*)vertical_compose_daub97iL1;
 +        d->vertical_compose_h1 = (void*)vertical_compose_daub97iH1;
 +        d->horizontal_compose = horizontal_compose_daub97i;
 +        d->support = 5;
 +        break;
 +    default:
 +        av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type);
 +        return -1;
 +    }
 +
 +    if (HAVE_MMX) ff_spatial_idwt_init_mmx(d, type);
 +
 +    return 0;
 +}
 +
 +void ff_spatial_idwt_slice2(DWTContext *d, int y)
 +{
 +    int level, support = d->support;
 +
 +    for (level = d->decomposition_count-1; level >= 0; level--) {
 +        int wl = d->width  >> level;
 +        int hl = d->height >> level;
 +        int stride_l = d->stride << level;
 +
 +        while (d->cs[level].y <= FFMIN((y>>level)+support, hl))
 +            d->spatial_compose(d, level, wl, hl, stride_l);
 +    }
 +}
 +
index 429241d,0000000..3b8c39d
mode 100644,000000..100644
--- /dev/null
@@@ -1,201 -1,0 +1,201 @@@
- #include "dsputil.h"
 +/*
 + * Copyright (C) 2009 David Conrad
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
++#include "avcodec.h"
 +#include "diracdsp.h"
 +#include "libavcodec/x86/diracdsp_mmx.h"
 +
 +#define FILTER(src, stride)                                     \
 +    ((21*((src)[ 0*stride] + (src)[1*stride])                   \
 +      -7*((src)[-1*stride] + (src)[2*stride])                   \
 +      +3*((src)[-2*stride] + (src)[3*stride])                   \
 +      -1*((src)[-3*stride] + (src)[4*stride]) + 16) >> 5)
 +
 +static void dirac_hpel_filter(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, const uint8_t *src,
 +                              int stride, int width, int height)
 +{
 +    int x, y;
 +
 +    for (y = 0; y < height; y++) {
 +        for (x = -3; x < width+5; x++)
 +            dstv[x] = av_clip_uint8(FILTER(src+x, stride));
 +
 +        for (x = 0; x < width; x++)
 +            dstc[x] = av_clip_uint8(FILTER(dstv+x, 1));
 +
 +        for (x = 0; x < width; x++)
 +            dsth[x] = av_clip_uint8(FILTER(src+x, 1));
 +
 +        src  += stride;
 +        dsth += stride;
 +        dstv += stride;
 +        dstc += stride;
 +    }
 +}
 +
 +#define PIXOP_BILINEAR(PFX, OP, WIDTH)                                  \
 +    static void ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c(uint8_t *dst, const uint8_t *src[5], int stride, int h) \
 +    {                                                                   \
 +        int x;                                                          \
 +        const uint8_t *s0 = src[0];                                     \
 +        const uint8_t *s1 = src[1];                                     \
 +        const uint8_t *s2 = src[2];                                     \
 +        const uint8_t *s3 = src[3];                                     \
 +        const uint8_t *w  = src[4];                                     \
 +                                                                        \
 +        while (h--) {                                                   \
 +            for (x = 0; x < WIDTH; x++) {                               \
 +                OP(dst[x], (s0[x]*w[0] + s1[x]*w[1] + s2[x]*w[2] + s3[x]*w[3] + 8) >> 4); \
 +            }                                                           \
 +                                                                        \
 +            dst += stride;                                              \
 +            s0 += stride;                                               \
 +            s1 += stride;                                               \
 +            s2 += stride;                                               \
 +            s3 += stride;                                               \
 +        }                                                               \
 +    }
 +
 +#define OP_PUT(dst, val) (dst) = (val)
 +#define OP_AVG(dst, val) (dst) = (((dst) + (val) + 1)>>1)
 +
 +PIXOP_BILINEAR(put, OP_PUT, 8)
 +PIXOP_BILINEAR(put, OP_PUT, 16)
 +PIXOP_BILINEAR(put, OP_PUT, 32)
 +PIXOP_BILINEAR(avg, OP_AVG, 8)
 +PIXOP_BILINEAR(avg, OP_AVG, 16)
 +PIXOP_BILINEAR(avg, OP_AVG, 32)
 +
 +#define op_scale1(x)  block[x] = av_clip_uint8( (block[x]*weight + (1<<(log2_denom-1))) >> log2_denom)
 +#define op_scale2(x)  dst[x] = av_clip_uint8( (src[x]*weights + dst[x]*weightd + (1<<(log2_denom-1))) >> log2_denom)
 +
 +#define DIRAC_WEIGHT(W)                                                 \
 +    static void weight_dirac_pixels ## W ## _c(uint8_t *block, int stride, int log2_denom, \
 +                                               int weight, int h) {     \
 +        int x;                                                          \
 +        while (h--) {                                                   \
 +            for (x = 0; x < W; x++) {                                   \
 +                op_scale1(x);                                           \
 +                op_scale1(x+1);                                         \
 +            }                                                           \
 +            block += stride;                                            \
 +        }                                                               \
 +    }                                                                   \
 +    static void biweight_dirac_pixels ## W ## _c(uint8_t *dst, const uint8_t *src, int stride, int log2_denom, \
 +                                                 int weightd, int weights, int h) { \
 +        int x;                                                          \
 +        while (h--) {                                                   \
 +            for (x = 0; x < W; x++) {                                   \
 +                op_scale2(x);                                           \
 +                op_scale2(x+1);                                         \
 +            }                                                           \
 +            dst += stride;                                              \
 +            src += stride;                                              \
 +        }                                                               \
 +    }
 +
 +DIRAC_WEIGHT(8)
 +DIRAC_WEIGHT(16)
 +DIRAC_WEIGHT(32)
 +
 +#define ADD_OBMC(xblen)                                                 \
 +    static void add_obmc ## xblen ## _c(uint16_t *dst, const uint8_t *src, int stride, \
 +                                        const uint8_t *obmc_weight, int yblen) \
 +    {                                                                   \
 +        int x;                                                          \
 +        while (yblen--) {                                               \
 +            for (x = 0; x < xblen; x += 2) {                            \
 +                dst[x  ] += src[x  ] * obmc_weight[x  ];                \
 +                dst[x+1] += src[x+1] * obmc_weight[x+1];                \
 +            }                                                           \
 +            dst += stride;                                              \
 +            src += stride;                                              \
 +            obmc_weight += 32;                                          \
 +        }                                                               \
 +    }
 +
 +ADD_OBMC(8)
 +ADD_OBMC(16)
 +ADD_OBMC(32)
 +
 +static void put_signed_rect_clamped_c(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height)
 +{
 +    int x, y;
 +    for (y = 0; y < height; y++) {
 +        for (x = 0; x < width; x+=4) {
 +            dst[x  ] = av_clip_uint8(src[x  ] + 128);
 +            dst[x+1] = av_clip_uint8(src[x+1] + 128);
 +            dst[x+2] = av_clip_uint8(src[x+2] + 128);
 +            dst[x+3] = av_clip_uint8(src[x+3] + 128);
 +        }
 +        dst += dst_stride;
 +        src += src_stride;
 +    }
 +}
 +
 +static void add_rect_clamped_c(uint8_t *dst, const uint16_t *src, int stride,
 +                               const int16_t *idwt, int idwt_stride,
 +                               int width, int height)
 +{
 +    int x, y;
 +
 +    for (y = 0; y < height; y++) {
 +        for (x = 0; x < width; x+=2) {
 +            dst[x  ] = av_clip_uint8(((src[x  ]+32)>>6) + idwt[x  ]);
 +            dst[x+1] = av_clip_uint8(((src[x+1]+32)>>6) + idwt[x+1]);
 +        }
 +        dst += stride;
 +        src += stride;
 +        idwt += idwt_stride;
 +    }
 +}
 +
 +#define PIXFUNC(PFX, WIDTH)                                             \
 +    c->PFX ## _dirac_pixels_tab[WIDTH>>4][0] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _c; \
 +    c->PFX ## _dirac_pixels_tab[WIDTH>>4][1] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l2_c; \
 +    c->PFX ## _dirac_pixels_tab[WIDTH>>4][2] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l4_c; \
 +    c->PFX ## _dirac_pixels_tab[WIDTH>>4][3] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c
 +
 +void ff_diracdsp_init(DiracDSPContext *c)
 +{
 +    c->dirac_hpel_filter = dirac_hpel_filter;
 +    c->add_rect_clamped = add_rect_clamped_c;
 +    c->put_signed_rect_clamped = put_signed_rect_clamped_c;
 +
 +    c->add_dirac_obmc[0] = add_obmc8_c;
 +    c->add_dirac_obmc[1] = add_obmc16_c;
 +    c->add_dirac_obmc[2] = add_obmc32_c;
 +
 +    c->weight_dirac_pixels_tab[0] = weight_dirac_pixels8_c;
 +    c->weight_dirac_pixels_tab[1] = weight_dirac_pixels16_c;
 +    c->weight_dirac_pixels_tab[2] = weight_dirac_pixels32_c;
 +    c->biweight_dirac_pixels_tab[0] = biweight_dirac_pixels8_c;
 +    c->biweight_dirac_pixels_tab[1] = biweight_dirac_pixels16_c;
 +    c->biweight_dirac_pixels_tab[2] = biweight_dirac_pixels32_c;
 +
 +    PIXFUNC(put, 8);
 +    PIXFUNC(put, 16);
 +    PIXFUNC(put, 32);
 +    PIXFUNC(avg, 8);
 +    PIXFUNC(avg, 16);
 +    PIXFUNC(avg, 32);
 +
 +    if (HAVE_MMX && HAVE_YASM) ff_diracdsp_init_mmx(c);
 +}
diff --cc libavcodec/dv.h
Simple merge
index 4b03e39,0000000..6e2352d
mode 100644,000000..100644
--- /dev/null
@@@ -1,116 -1,0 +1,115 @@@
- #include "dsputil.h"
 +/*
 + * DVD navigation block parser for FFmpeg
 + * Copyright (c) 2013 The FFmpeg Project
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +#include "avcodec.h"
 +#include "get_bits.h"
 +#include "parser.h"
 +
 +#define PCI_SIZE  980
 +#define DSI_SIZE 1018
 +
 +/* parser definition */
 +typedef struct DVDNavParseContext {
 +    uint32_t     lba;
 +    uint8_t      buffer[PCI_SIZE+DSI_SIZE];
 +    int          copied;
 +} DVDNavParseContext;
 +
 +static av_cold int dvd_nav_parse_init(AVCodecParserContext *s)
 +{
 +    DVDNavParseContext *pc = s->priv_data;
 +
 +    pc->lba    = 0xFFFFFFFF;
 +    pc->copied = 0;
 +    return 0;
 +}
 +
 +static int dvd_nav_parse(AVCodecParserContext *s,
 +                         AVCodecContext *avctx,
 +                         const uint8_t **poutbuf, int *poutbuf_size,
 +                         const uint8_t *buf, int buf_size)
 +{
 +    DVDNavParseContext *pc1 = s->priv_data;
 +    int lastPacket          = 0;
 +    int valid               = 0;
 +
 +    s->pict_type = AV_PICTURE_TYPE_NONE;
 +
 +    avctx->time_base.num = 1;
 +    avctx->time_base.den = 90000;
 +
 +    if (buf && buf_size) {
 +        switch(buf[0]) {
 +            case 0x00:
 +                if (buf_size == PCI_SIZE) {
 +                    /* PCI */
 +                    uint32_t lba      = AV_RB32(&buf[0x01]);
 +                    uint32_t startpts = AV_RB32(&buf[0x0D]);
 +                    uint32_t endpts   = AV_RB32(&buf[0x11]);
 +
 +                    if (endpts > startpts) {
 +                        pc1->lba    = lba;
 +                        s->pts      = (int64_t)startpts;
 +                        s->duration = endpts - startpts;
 +
 +                        memcpy(pc1->buffer, buf, PCI_SIZE);
 +                        pc1->copied = PCI_SIZE;
 +                        valid       = 1;
 +                    }
 +                }
 +                break;
 +
 +            case 0x01:
 +                if ((buf_size == DSI_SIZE) && (pc1->copied == PCI_SIZE)) {
 +                    /* DSI */
 +                    uint32_t lba = AV_RB32(&buf[0x05]);
 +
 +                    if (lba == pc1->lba) {
 +                        memcpy(pc1->buffer + pc1->copied, buf, DSI_SIZE);
 +                        lastPacket  = 1;
 +                        valid       = 1;
 +                    }
 +                }
 +                break;
 +        }
 +    }
 +
 +    if (!valid || lastPacket) {
 +        pc1->copied = 0;
 +        pc1->lba    = 0xFFFFFFFF;
 +    }
 +
 +    if (lastPacket) {
 +        *poutbuf      = pc1->buffer;
 +        *poutbuf_size = sizeof(pc1->buffer);
 +    } else {
 +        *poutbuf      = NULL;
 +        *poutbuf_size = 0;
 +    }
 +
 +    return buf_size;
 +}
 +
 +AVCodecParser ff_dvd_nav_parser = {
 +    .codec_ids      = { AV_CODEC_ID_DVD_NAV },
 +    .priv_data_size = sizeof(DVDNavParseContext),
 +    .parser_init    = dvd_nav_parse_init,
 +    .parser_parse   = dvd_nav_parse,
 +};
@@@ -69,14 -65,13 +69,14 @@@ static av_cold int dvvideo_encode_init(
  
      dv_vlc_map_tableinit();
  
-     memset(&dsp,0, sizeof(dsp));
-     ff_dsputil_init(&dsp, avctx);
++    memset(&mecc,0, sizeof(mecc));
      ff_fdctdsp_init(&fdsp, avctx);
+     ff_me_cmp_init(&mecc, avctx);
      ff_pixblockdsp_init(&pdsp, avctx);
-     ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp);
+     ff_set_cmp(&mecc, mecc.ildct_cmp, avctx->ildct_cmp);
  
      s->get_pixels = pdsp.get_pixels;
-     s->ildct_cmp  = dsp.ildct_cmp[5];
+     s->ildct_cmp  = mecc.ildct_cmp[5];
  
      s->fdct[0]    = fdsp.fdct;
      s->fdct[1]    = fdsp.fdct248;
@@@ -739,12 -715,11 +739,12 @@@ static int is_intra_more_likely(ERConte
                  } else {
                      ff_thread_await_progress(s->last_pic.tf, mb_y, 0);
                  }
-                 is_intra_likely += s->dsp->sad[0](NULL, last_mb_ptr, mb_ptr,
-                                                  linesize[0], 16);
+                 is_intra_likely += s->mecc->sad[0](NULL, last_mb_ptr, mb_ptr,
+                                                    linesize[0], 16);
 +                // FIXME need await_progress() here
-                 is_intra_likely -= s->dsp->sad[0](NULL, last_mb_ptr,
-                                                  last_mb_ptr + linesize[0] * 16,
-                                                  linesize[0], 16);
+                 is_intra_likely -= s->mecc->sad[0](NULL, last_mb_ptr,
+                                                    last_mb_ptr + linesize[0] * 16,
+                                                    linesize[0], 16);
              } else {
                  if (IS_INTRA(s->cur_pic.mb_type[mb_xy]))
                     is_intra_likely++;
Simple merge
@@@ -1264,9 -1233,8 +1264,9 @@@ int ff_h264_set_parameter_from_sps(H264
              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);
 +
              if (CONFIG_ERROR_RESILIENCE)
-                 ff_dsputil_init(&h->dsp, h->avctx);
+                 ff_me_cmp_init(&h->mecc, h->avctx);
              ff_videodsp_init(&h->vdsp, h->sps.bit_depth_luma);
          } else {
              av_log(h->avctx, AV_LOG_ERROR, "Unsupported bit depth %d\n",
Simple merge
@@@ -1202,9 -1118,7 +1201,9 @@@ static int h264_slice_header_init(H264C
              if (!c)
                  return AVERROR(ENOMEM);
              c->avctx             = h->avctx;
 -            c->mecc              = h->mecc;
 +            if (CONFIG_ERROR_RESILIENCE) {
-                 c->dsp               = h->dsp;
++                c->mecc              = h->mecc;
 +            }
              c->vdsp              = h->vdsp;
              c->h264dsp           = h->h264dsp;
              c->h264qpel          = h->h264qpel;
@@@ -1,34 -1,4 +1,33 @@@
  LIBAVCODEC_$MAJOR {
          global: av*;
-                 dsputil_init;
-                 ff_dsputil_init;
 +                #deprecated, remove after next bump
 +                audio_resample;
 +                audio_resample_close;
 +                ff_find_pix_fmt;
 +                ff_framenum_to_drop_timecode;
 +                ff_framenum_to_smtpe_timecode;
 +                ff_raw_pix_fmt_tags;
 +                ff_init_smtpe_timecode;
 +                ff_fft*;
 +                ff_mdct*;
 +                ff_dct*;
 +                ff_rdft*;
 +                ff_prores_idct_put_10_sse2;
 +                ff_simple_idct*;
 +                ff_aanscales;
 +                ff_faan*;
 +                ff_mmx_idct;
 +                ff_fdct*;
 +                fdct_ifast;
 +                j_rev_dct;
 +                ff_mmxext_idct;
 +                ff_idct_xvid*;
 +                ff_jpeg_fdct*;
 +                ff_dnxhd_get_cid_table;
 +                ff_dnxhd_cid_table;
 +                ff_idctdsp_init;
 +                ff_fdctdsp_init;
 +                ff_pixblockdsp_init;
++                ff_me_cmp_init;
          local:  *;
  };
index 0000000,9fcc937..7923c58
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,942 +1,988 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
 -    assert(h == 8);
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "libavutil/attributes.h"
++#include "libavutil/internal.h"
+ #include "avcodec.h"
+ #include "copy_block.h"
+ #include "simple_idct.h"
+ #include "me_cmp.h"
+ #include "mpegvideo.h"
+ #include "config.h"
+ uint32_t ff_square_tab[512] = { 0, };
+ static int sse4_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                   int line_size, int h)
+ {
+     int s = 0, i;
+     uint32_t *sq = ff_square_tab + 256;
+     for (i = 0; i < h; i++) {
+         s    += sq[pix1[0] - pix2[0]];
+         s    += sq[pix1[1] - pix2[1]];
+         s    += sq[pix1[2] - pix2[2]];
+         s    += sq[pix1[3] - pix2[3]];
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     return s;
+ }
+ static int sse8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                   int line_size, int h)
+ {
+     int s = 0, i;
+     uint32_t *sq = ff_square_tab + 256;
+     for (i = 0; i < h; i++) {
+         s    += sq[pix1[0] - pix2[0]];
+         s    += sq[pix1[1] - pix2[1]];
+         s    += sq[pix1[2] - pix2[2]];
+         s    += sq[pix1[3] - pix2[3]];
+         s    += sq[pix1[4] - pix2[4]];
+         s    += sq[pix1[5] - pix2[5]];
+         s    += sq[pix1[6] - pix2[6]];
+         s    += sq[pix1[7] - pix2[7]];
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     return s;
+ }
+ static int sse16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                    int line_size, int h)
+ {
+     int s = 0, i;
+     uint32_t *sq = ff_square_tab + 256;
+     for (i = 0; i < h; i++) {
+         s += sq[pix1[0]  - pix2[0]];
+         s += sq[pix1[1]  - pix2[1]];
+         s += sq[pix1[2]  - pix2[2]];
+         s += sq[pix1[3]  - pix2[3]];
+         s += sq[pix1[4]  - pix2[4]];
+         s += sq[pix1[5]  - pix2[5]];
+         s += sq[pix1[6]  - pix2[6]];
+         s += sq[pix1[7]  - pix2[7]];
+         s += sq[pix1[8]  - pix2[8]];
+         s += sq[pix1[9]  - pix2[9]];
+         s += sq[pix1[10] - pix2[10]];
+         s += sq[pix1[11] - pix2[11]];
+         s += sq[pix1[12] - pix2[12]];
+         s += sq[pix1[13] - pix2[13]];
+         s += sq[pix1[14] - pix2[14]];
+         s += sq[pix1[15] - pix2[15]];
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     return s;
+ }
+ static int sum_abs_dctelem_c(int16_t *block)
+ {
+     int sum = 0, i;
+     for (i = 0; i < 64; i++)
+         sum += FFABS(block[i]);
+     return sum;
+ }
+ #define avg2(a, b) ((a + b + 1) >> 1)
+ #define avg4(a, b, c, d) ((a + b + c + d + 2) >> 2)
+ static inline int pix_abs16_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                               int line_size, int h)
+ {
+     int s = 0, i;
+     for (i = 0; i < h; i++) {
+         s    += abs(pix1[0]  - pix2[0]);
+         s    += abs(pix1[1]  - pix2[1]);
+         s    += abs(pix1[2]  - pix2[2]);
+         s    += abs(pix1[3]  - pix2[3]);
+         s    += abs(pix1[4]  - pix2[4]);
+         s    += abs(pix1[5]  - pix2[5]);
+         s    += abs(pix1[6]  - pix2[6]);
+         s    += abs(pix1[7]  - pix2[7]);
+         s    += abs(pix1[8]  - pix2[8]);
+         s    += abs(pix1[9]  - pix2[9]);
+         s    += abs(pix1[10] - pix2[10]);
+         s    += abs(pix1[11] - pix2[11]);
+         s    += abs(pix1[12] - pix2[12]);
+         s    += abs(pix1[13] - pix2[13]);
+         s    += abs(pix1[14] - pix2[14]);
+         s    += abs(pix1[15] - pix2[15]);
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     return s;
+ }
+ static int pix_abs16_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                           int line_size, int h)
+ {
+     int s = 0, i;
+     for (i = 0; i < h; i++) {
+         s    += abs(pix1[0]  - avg2(pix2[0],  pix2[1]));
+         s    += abs(pix1[1]  - avg2(pix2[1],  pix2[2]));
+         s    += abs(pix1[2]  - avg2(pix2[2],  pix2[3]));
+         s    += abs(pix1[3]  - avg2(pix2[3],  pix2[4]));
+         s    += abs(pix1[4]  - avg2(pix2[4],  pix2[5]));
+         s    += abs(pix1[5]  - avg2(pix2[5],  pix2[6]));
+         s    += abs(pix1[6]  - avg2(pix2[6],  pix2[7]));
+         s    += abs(pix1[7]  - avg2(pix2[7],  pix2[8]));
+         s    += abs(pix1[8]  - avg2(pix2[8],  pix2[9]));
+         s    += abs(pix1[9]  - avg2(pix2[9],  pix2[10]));
+         s    += abs(pix1[10] - avg2(pix2[10], pix2[11]));
+         s    += abs(pix1[11] - avg2(pix2[11], pix2[12]));
+         s    += abs(pix1[12] - avg2(pix2[12], pix2[13]));
+         s    += abs(pix1[13] - avg2(pix2[13], pix2[14]));
+         s    += abs(pix1[14] - avg2(pix2[14], pix2[15]));
+         s    += abs(pix1[15] - avg2(pix2[15], pix2[16]));
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     return s;
+ }
+ static int pix_abs16_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                           int line_size, int h)
+ {
+     int s = 0, i;
+     uint8_t *pix3 = pix2 + line_size;
+     for (i = 0; i < h; i++) {
+         s    += abs(pix1[0]  - avg2(pix2[0],  pix3[0]));
+         s    += abs(pix1[1]  - avg2(pix2[1],  pix3[1]));
+         s    += abs(pix1[2]  - avg2(pix2[2],  pix3[2]));
+         s    += abs(pix1[3]  - avg2(pix2[3],  pix3[3]));
+         s    += abs(pix1[4]  - avg2(pix2[4],  pix3[4]));
+         s    += abs(pix1[5]  - avg2(pix2[5],  pix3[5]));
+         s    += abs(pix1[6]  - avg2(pix2[6],  pix3[6]));
+         s    += abs(pix1[7]  - avg2(pix2[7],  pix3[7]));
+         s    += abs(pix1[8]  - avg2(pix2[8],  pix3[8]));
+         s    += abs(pix1[9]  - avg2(pix2[9],  pix3[9]));
+         s    += abs(pix1[10] - avg2(pix2[10], pix3[10]));
+         s    += abs(pix1[11] - avg2(pix2[11], pix3[11]));
+         s    += abs(pix1[12] - avg2(pix2[12], pix3[12]));
+         s    += abs(pix1[13] - avg2(pix2[13], pix3[13]));
+         s    += abs(pix1[14] - avg2(pix2[14], pix3[14]));
+         s    += abs(pix1[15] - avg2(pix2[15], pix3[15]));
+         pix1 += line_size;
+         pix2 += line_size;
+         pix3 += line_size;
+     }
+     return s;
+ }
+ static int pix_abs16_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                            int line_size, int h)
+ {
+     int s = 0, i;
+     uint8_t *pix3 = pix2 + line_size;
+     for (i = 0; i < h; i++) {
+         s    += abs(pix1[0]  - avg4(pix2[0],  pix2[1],  pix3[0],  pix3[1]));
+         s    += abs(pix1[1]  - avg4(pix2[1],  pix2[2],  pix3[1],  pix3[2]));
+         s    += abs(pix1[2]  - avg4(pix2[2],  pix2[3],  pix3[2],  pix3[3]));
+         s    += abs(pix1[3]  - avg4(pix2[3],  pix2[4],  pix3[3],  pix3[4]));
+         s    += abs(pix1[4]  - avg4(pix2[4],  pix2[5],  pix3[4],  pix3[5]));
+         s    += abs(pix1[5]  - avg4(pix2[5],  pix2[6],  pix3[5],  pix3[6]));
+         s    += abs(pix1[6]  - avg4(pix2[6],  pix2[7],  pix3[6],  pix3[7]));
+         s    += abs(pix1[7]  - avg4(pix2[7],  pix2[8],  pix3[7],  pix3[8]));
+         s    += abs(pix1[8]  - avg4(pix2[8],  pix2[9],  pix3[8],  pix3[9]));
+         s    += abs(pix1[9]  - avg4(pix2[9],  pix2[10], pix3[9],  pix3[10]));
+         s    += abs(pix1[10] - avg4(pix2[10], pix2[11], pix3[10], pix3[11]));
+         s    += abs(pix1[11] - avg4(pix2[11], pix2[12], pix3[11], pix3[12]));
+         s    += abs(pix1[12] - avg4(pix2[12], pix2[13], pix3[12], pix3[13]));
+         s    += abs(pix1[13] - avg4(pix2[13], pix2[14], pix3[13], pix3[14]));
+         s    += abs(pix1[14] - avg4(pix2[14], pix2[15], pix3[14], pix3[15]));
+         s    += abs(pix1[15] - avg4(pix2[15], pix2[16], pix3[15], pix3[16]));
+         pix1 += line_size;
+         pix2 += line_size;
+         pix3 += line_size;
+     }
+     return s;
+ }
+ static inline int pix_abs8_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                              int line_size, int h)
+ {
+     int s = 0, i;
+     for (i = 0; i < h; i++) {
+         s    += abs(pix1[0] - pix2[0]);
+         s    += abs(pix1[1] - pix2[1]);
+         s    += abs(pix1[2] - pix2[2]);
+         s    += abs(pix1[3] - pix2[3]);
+         s    += abs(pix1[4] - pix2[4]);
+         s    += abs(pix1[5] - pix2[5]);
+         s    += abs(pix1[6] - pix2[6]);
+         s    += abs(pix1[7] - pix2[7]);
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     return s;
+ }
+ static int pix_abs8_x2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                          int line_size, int h)
+ {
+     int s = 0, i;
+     for (i = 0; i < h; i++) {
+         s    += abs(pix1[0] - avg2(pix2[0], pix2[1]));
+         s    += abs(pix1[1] - avg2(pix2[1], pix2[2]));
+         s    += abs(pix1[2] - avg2(pix2[2], pix2[3]));
+         s    += abs(pix1[3] - avg2(pix2[3], pix2[4]));
+         s    += abs(pix1[4] - avg2(pix2[4], pix2[5]));
+         s    += abs(pix1[5] - avg2(pix2[5], pix2[6]));
+         s    += abs(pix1[6] - avg2(pix2[6], pix2[7]));
+         s    += abs(pix1[7] - avg2(pix2[7], pix2[8]));
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     return s;
+ }
+ static int pix_abs8_y2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                          int line_size, int h)
+ {
+     int s = 0, i;
+     uint8_t *pix3 = pix2 + line_size;
+     for (i = 0; i < h; i++) {
+         s    += abs(pix1[0] - avg2(pix2[0], pix3[0]));
+         s    += abs(pix1[1] - avg2(pix2[1], pix3[1]));
+         s    += abs(pix1[2] - avg2(pix2[2], pix3[2]));
+         s    += abs(pix1[3] - avg2(pix2[3], pix3[3]));
+         s    += abs(pix1[4] - avg2(pix2[4], pix3[4]));
+         s    += abs(pix1[5] - avg2(pix2[5], pix3[5]));
+         s    += abs(pix1[6] - avg2(pix2[6], pix3[6]));
+         s    += abs(pix1[7] - avg2(pix2[7], pix3[7]));
+         pix1 += line_size;
+         pix2 += line_size;
+         pix3 += line_size;
+     }
+     return s;
+ }
+ static int pix_abs8_xy2_c(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                           int line_size, int h)
+ {
+     int s = 0, i;
+     uint8_t *pix3 = pix2 + line_size;
+     for (i = 0; i < h; i++) {
+         s    += abs(pix1[0] - avg4(pix2[0], pix2[1], pix3[0], pix3[1]));
+         s    += abs(pix1[1] - avg4(pix2[1], pix2[2], pix3[1], pix3[2]));
+         s    += abs(pix1[2] - avg4(pix2[2], pix2[3], pix3[2], pix3[3]));
+         s    += abs(pix1[3] - avg4(pix2[3], pix2[4], pix3[3], pix3[4]));
+         s    += abs(pix1[4] - avg4(pix2[4], pix2[5], pix3[4], pix3[5]));
+         s    += abs(pix1[5] - avg4(pix2[5], pix2[6], pix3[5], pix3[6]));
+         s    += abs(pix1[6] - avg4(pix2[6], pix2[7], pix3[6], pix3[7]));
+         s    += abs(pix1[7] - avg4(pix2[7], pix2[8], pix3[7], pix3[8]));
+         pix1 += line_size;
+         pix2 += line_size;
+         pix3 += line_size;
+     }
+     return s;
+ }
+ static int nsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int h)
+ {
+     int score1 = 0, score2 = 0, x, y;
+     for (y = 0; y < h; y++) {
+         for (x = 0; x < 16; x++)
+             score1 += (s1[x] - s2[x]) * (s1[x] - s2[x]);
+         if (y + 1 < h) {
+             for (x = 0; x < 15; x++)
+                 score2 += FFABS(s1[x]     - s1[x + stride] -
+                                 s1[x + 1] + s1[x + stride + 1]) -
+                           FFABS(s2[x]     - s2[x + stride] -
+                                 s2[x + 1] + s2[x + stride + 1]);
+         }
+         s1 += stride;
+         s2 += stride;
+     }
+     if (c)
+         return score1 + FFABS(score2) * c->avctx->nsse_weight;
+     else
+         return score1 + FFABS(score2) * 8;
+ }
+ static int nsse8_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2, int stride, int h)
+ {
+     int score1 = 0, score2 = 0, x, y;
+     for (y = 0; y < h; y++) {
+         for (x = 0; x < 8; x++)
+             score1 += (s1[x] - s2[x]) * (s1[x] - s2[x]);
+         if (y + 1 < h) {
+             for (x = 0; x < 7; x++)
+                 score2 += FFABS(s1[x]     - s1[x + stride] -
+                                 s1[x + 1] + s1[x + stride + 1]) -
+                           FFABS(s2[x]     - s2[x + stride] -
+                                 s2[x + 1] + s2[x + stride + 1]);
+         }
+         s1 += stride;
+         s2 += stride;
+     }
+     if (c)
+         return score1 + FFABS(score2) * c->avctx->nsse_weight;
+     else
+         return score1 + FFABS(score2) * 8;
+ }
+ static int zero_cmp(MpegEncContext *s, uint8_t *a, uint8_t *b,
+                     int stride, int h)
+ {
+     return 0;
+ }
+ void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type)
+ {
+     int i;
+     memset(cmp, 0, sizeof(void *) * 6);
+     for (i = 0; i < 6; i++) {
+         switch (type & 0xFF) {
+         case FF_CMP_SAD:
+             cmp[i] = c->sad[i];
+             break;
+         case FF_CMP_SATD:
+             cmp[i] = c->hadamard8_diff[i];
+             break;
+         case FF_CMP_SSE:
+             cmp[i] = c->sse[i];
+             break;
+         case FF_CMP_DCT:
+             cmp[i] = c->dct_sad[i];
+             break;
+         case FF_CMP_DCT264:
+             cmp[i] = c->dct264_sad[i];
+             break;
+         case FF_CMP_DCTMAX:
+             cmp[i] = c->dct_max[i];
+             break;
+         case FF_CMP_PSNR:
+             cmp[i] = c->quant_psnr[i];
+             break;
+         case FF_CMP_BIT:
+             cmp[i] = c->bit[i];
+             break;
+         case FF_CMP_RD:
+             cmp[i] = c->rd[i];
+             break;
+         case FF_CMP_VSAD:
+             cmp[i] = c->vsad[i];
+             break;
+         case FF_CMP_VSSE:
+             cmp[i] = c->vsse[i];
+             break;
+         case FF_CMP_ZERO:
+             cmp[i] = zero_cmp;
+             break;
+         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");
+         }
+     }
+ }
+ #define BUTTERFLY2(o1, o2, i1, i2)              \
+     o1 = (i1) + (i2);                           \
+     o2 = (i1) - (i2);
+ #define BUTTERFLY1(x, y)                        \
+     {                                           \
+         int a, b;                               \
+         a = x;                                  \
+         b = y;                                  \
+         x = a + b;                              \
+         y = a - b;                              \
+     }
+ #define BUTTERFLYA(x, y) (FFABS((x) + (y)) + FFABS((x) - (y)))
+ static int hadamard8_diff8x8_c(MpegEncContext *s, uint8_t *dst,
+                                uint8_t *src, int stride, int h)
+ {
+     int i, temp[64], sum = 0;
 -    assert(h == 8);
++    av_assert2(h == 8);
+     for (i = 0; i < 8; i++) {
+         // FIXME: try pointer walks
+         BUTTERFLY2(temp[8 * i + 0], temp[8 * i + 1],
+                    src[stride * i + 0] - dst[stride * i + 0],
+                    src[stride * i + 1] - dst[stride * i + 1]);
+         BUTTERFLY2(temp[8 * i + 2], temp[8 * i + 3],
+                    src[stride * i + 2] - dst[stride * i + 2],
+                    src[stride * i + 3] - dst[stride * i + 3]);
+         BUTTERFLY2(temp[8 * i + 4], temp[8 * i + 5],
+                    src[stride * i + 4] - dst[stride * i + 4],
+                    src[stride * i + 5] - dst[stride * i + 5]);
+         BUTTERFLY2(temp[8 * i + 6], temp[8 * i + 7],
+                    src[stride * i + 6] - dst[stride * i + 6],
+                    src[stride * i + 7] - dst[stride * i + 7]);
+         BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 2]);
+         BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 3]);
+         BUTTERFLY1(temp[8 * i + 4], temp[8 * i + 6]);
+         BUTTERFLY1(temp[8 * i + 5], temp[8 * i + 7]);
+         BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 4]);
+         BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 5]);
+         BUTTERFLY1(temp[8 * i + 2], temp[8 * i + 6]);
+         BUTTERFLY1(temp[8 * i + 3], temp[8 * i + 7]);
+     }
+     for (i = 0; i < 8; i++) {
+         BUTTERFLY1(temp[8 * 0 + i], temp[8 * 1 + i]);
+         BUTTERFLY1(temp[8 * 2 + i], temp[8 * 3 + i]);
+         BUTTERFLY1(temp[8 * 4 + i], temp[8 * 5 + i]);
+         BUTTERFLY1(temp[8 * 6 + i], temp[8 * 7 + i]);
+         BUTTERFLY1(temp[8 * 0 + i], temp[8 * 2 + i]);
+         BUTTERFLY1(temp[8 * 1 + i], temp[8 * 3 + i]);
+         BUTTERFLY1(temp[8 * 4 + i], temp[8 * 6 + i]);
+         BUTTERFLY1(temp[8 * 5 + i], temp[8 * 7 + i]);
+         sum += BUTTERFLYA(temp[8 * 0 + i], temp[8 * 4 + i]) +
+                BUTTERFLYA(temp[8 * 1 + i], temp[8 * 5 + i]) +
+                BUTTERFLYA(temp[8 * 2 + i], temp[8 * 6 + i]) +
+                BUTTERFLYA(temp[8 * 3 + i], temp[8 * 7 + i]);
+     }
+     return sum;
+ }
+ static int hadamard8_intra8x8_c(MpegEncContext *s, uint8_t *src,
+                                 uint8_t *dummy, int stride, int h)
+ {
+     int i, temp[64], sum = 0;
 -    assert(h == 8);
++    av_assert2(h == 8);
+     for (i = 0; i < 8; i++) {
+         // FIXME: try pointer walks
+         BUTTERFLY2(temp[8 * i + 0], temp[8 * i + 1],
+                    src[stride * i + 0], src[stride * i + 1]);
+         BUTTERFLY2(temp[8 * i + 2], temp[8 * i + 3],
+                    src[stride * i + 2], src[stride * i + 3]);
+         BUTTERFLY2(temp[8 * i + 4], temp[8 * i + 5],
+                    src[stride * i + 4], src[stride * i + 5]);
+         BUTTERFLY2(temp[8 * i + 6], temp[8 * i + 7],
+                    src[stride * i + 6], src[stride * i + 7]);
+         BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 2]);
+         BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 3]);
+         BUTTERFLY1(temp[8 * i + 4], temp[8 * i + 6]);
+         BUTTERFLY1(temp[8 * i + 5], temp[8 * i + 7]);
+         BUTTERFLY1(temp[8 * i + 0], temp[8 * i + 4]);
+         BUTTERFLY1(temp[8 * i + 1], temp[8 * i + 5]);
+         BUTTERFLY1(temp[8 * i + 2], temp[8 * i + 6]);
+         BUTTERFLY1(temp[8 * i + 3], temp[8 * i + 7]);
+     }
+     for (i = 0; i < 8; i++) {
+         BUTTERFLY1(temp[8 * 0 + i], temp[8 * 1 + i]);
+         BUTTERFLY1(temp[8 * 2 + i], temp[8 * 3 + i]);
+         BUTTERFLY1(temp[8 * 4 + i], temp[8 * 5 + i]);
+         BUTTERFLY1(temp[8 * 6 + i], temp[8 * 7 + i]);
+         BUTTERFLY1(temp[8 * 0 + i], temp[8 * 2 + i]);
+         BUTTERFLY1(temp[8 * 1 + i], temp[8 * 3 + i]);
+         BUTTERFLY1(temp[8 * 4 + i], temp[8 * 6 + i]);
+         BUTTERFLY1(temp[8 * 5 + i], temp[8 * 7 + i]);
+         sum +=
+             BUTTERFLYA(temp[8 * 0 + i], temp[8 * 4 + i])
+             + BUTTERFLYA(temp[8 * 1 + i], temp[8 * 5 + i])
+             + BUTTERFLYA(temp[8 * 2 + i], temp[8 * 6 + i])
+             + BUTTERFLYA(temp[8 * 3 + i], temp[8 * 7 + i]);
+     }
+     sum -= FFABS(temp[8 * 0] + temp[8 * 4]); // -mean
+     return sum;
+ }
+ static int dct_sad8x8_c(MpegEncContext *s, uint8_t *src1,
+                         uint8_t *src2, int stride, int h)
+ {
+     LOCAL_ALIGNED_16(int16_t, temp, [64]);
 -    assert(h == 8);
++    av_assert2(h == 8);
+     s->pdsp.diff_pixels(temp, src1, src2, stride);
+     s->fdsp.fdct(temp);
+     return s->mecc.sum_abs_dctelem(temp);
+ }
+ #if CONFIG_GPL
+ #define DCT8_1D                                         \
+     {                                                   \
+         const int s07 = SRC(0) + SRC(7);                \
+         const int s16 = SRC(1) + SRC(6);                \
+         const int s25 = SRC(2) + SRC(5);                \
+         const int s34 = SRC(3) + SRC(4);                \
+         const int a0  = s07 + s34;                      \
+         const int a1  = s16 + s25;                      \
+         const int a2  = s07 - s34;                      \
+         const int a3  = s16 - s25;                      \
+         const int d07 = SRC(0) - SRC(7);                \
+         const int d16 = SRC(1) - SRC(6);                \
+         const int d25 = SRC(2) - SRC(5);                \
+         const int d34 = SRC(3) - SRC(4);                \
+         const int a4  = d16 + d25 + (d07 + (d07 >> 1)); \
+         const int a5  = d07 - d34 - (d25 + (d25 >> 1)); \
+         const int a6  = d07 + d34 - (d16 + (d16 >> 1)); \
+         const int a7  = d16 - d25 + (d34 + (d34 >> 1)); \
+         DST(0, a0 + a1);                                \
+         DST(1, a4 + (a7 >> 2));                         \
+         DST(2, a2 + (a3 >> 1));                         \
+         DST(3, a5 + (a6 >> 2));                         \
+         DST(4, a0 - a1);                                \
+         DST(5, a6 - (a5 >> 2));                         \
+         DST(6, (a2 >> 1) - a3);                         \
+         DST(7, (a4 >> 2) - a7);                         \
+     }
+ static int dct264_sad8x8_c(MpegEncContext *s, uint8_t *src1,
+                            uint8_t *src2, int stride, int h)
+ {
+     int16_t dct[8][8];
+     int i, sum = 0;
+     s->pdsp.diff_pixels(dct[0], src1, src2, stride);
+ #define SRC(x) dct[i][x]
+ #define DST(x, v) dct[i][x] = v
+     for (i = 0; i < 8; i++)
+         DCT8_1D
+ #undef SRC
+ #undef DST
+ #define SRC(x) dct[x][i]
+ #define DST(x, v) sum += FFABS(v)
+         for (i = 0; i < 8; i++)
+             DCT8_1D
+ #undef SRC
+ #undef DST
+             return sum;
+ }
+ #endif
+ static int dct_max8x8_c(MpegEncContext *s, uint8_t *src1,
+                         uint8_t *src2, int stride, int h)
+ {
+     LOCAL_ALIGNED_16(int16_t, temp, [64]);
+     int sum = 0, i;
 -    assert(h == 8);
++    av_assert2(h == 8);
+     s->pdsp.diff_pixels(temp, src1, src2, stride);
+     s->fdsp.fdct(temp);
+     for (i = 0; i < 64; i++)
+         sum = FFMAX(sum, FFABS(temp[i]));
+     return sum;
+ }
+ static int quant_psnr8x8_c(MpegEncContext *s, uint8_t *src1,
+                            uint8_t *src2, int stride, int h)
+ {
+     LOCAL_ALIGNED_16(int16_t, temp, [64 * 2]);
+     int16_t *const bak = temp + 64;
+     int sum = 0, i;
 -    assert(h == 8);
++    av_assert2(h == 8);
+     s->mb_intra = 0;
+     s->pdsp.diff_pixels(temp, src1, src2, stride);
+     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);
+     ff_simple_idct_8(temp); // FIXME
+     for (i = 0; i < 64; i++)
+         sum += (temp[i] - bak[i]) * (temp[i] - bak[i]);
+     return sum;
+ }
+ static int rd8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2,
+                    int stride, int h)
+ {
+     const uint8_t *scantable = s->intra_scantable.permutated;
+     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;
+     const int esc_length = s->ac_esc_length;
+     uint8_t *length, *last_length;
 -        assert(level - 64);
++    av_assert2(h == 8);
+     copy_block8(lsrc1, src1, 8, stride, 8);
+     copy_block8(lsrc2, src2, 8, stride, 8);
+     s->pdsp.diff_pixels(temp, lsrc1, lsrc2, 8);
+     s->block_last_index[0 /* FIXME */] =
+     last                               =
+         s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i);
+     bits = 0;
+     if (s->mb_intra) {
+         start_i     = 1;
+         length      = s->intra_ac_vlc_length;
+         last_length = s->intra_ac_vlc_last_length;
+         bits       += s->luma_dc_vlc_length[temp[0] + 256]; // FIXME: chroma
+     } else {
+         start_i     = 0;
+         length      = s->inter_ac_vlc_length;
+         last_length = s->inter_ac_vlc_last_length;
+     }
+     if (last >= start_i) {
+         run = 0;
+         for (i = start_i; i < last; i++) {
+             int j = scantable[i];
+             level = temp[j];
+             if (level) {
+                 level += 64;
+                 if ((level & (~127)) == 0)
+                     bits += length[UNI_AC_ENC_INDEX(run, level)];
+                 else
+                     bits += esc_length;
+                 run = 0;
+             } else
+                 run++;
+         }
+         i = scantable[last];
+         level = temp[i] + 64;
 -    assert(h == 8);
++        av_assert2(level - 64);
+         if ((level & (~127)) == 0) {
+             bits += last_length[UNI_AC_ENC_INDEX(run, level)];
+         } else
+             bits += esc_length;
+     }
+     if (last >= 0) {
+         if (s->mb_intra)
+             s->dct_unquantize_intra(s, temp, 0, s->qscale);
+         else
+             s->dct_unquantize_inter(s, temp, 0, s->qscale);
+     }
+     s->idsp.idct_add(lsrc2, 8, temp);
+     distortion = s->mecc.sse[1](NULL, lsrc2, lsrc1, 8, 8);
+     return distortion + ((bits * s->qscale * s->qscale * 109 + 64) >> 7);
+ }
+ static int bit8x8_c(MpegEncContext *s, uint8_t *src1, uint8_t *src2,
+                     int stride, int h)
+ {
+     const uint8_t *scantable = s->intra_scantable.permutated;
+     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, *last_length;
 -        assert(level - 64);
++    av_assert2(h == 8);
+     s->pdsp.diff_pixels(temp, src1, src2, stride);
+     s->block_last_index[0 /* FIXME */] =
+     last                               =
+         s->fast_dct_quantize(s, temp, 0 /* FIXME */, s->qscale, &i);
+     bits = 0;
+     if (s->mb_intra) {
+         start_i     = 1;
+         length      = s->intra_ac_vlc_length;
+         last_length = s->intra_ac_vlc_last_length;
+         bits       += s->luma_dc_vlc_length[temp[0] + 256]; // FIXME: chroma
+     } else {
+         start_i     = 0;
+         length      = s->inter_ac_vlc_length;
+         last_length = s->inter_ac_vlc_last_length;
+     }
+     if (last >= start_i) {
+         run = 0;
+         for (i = start_i; i < last; i++) {
+             int j = scantable[i];
+             level = temp[j];
+             if (level) {
+                 level += 64;
+                 if ((level & (~127)) == 0)
+                     bits += length[UNI_AC_ENC_INDEX(run, level)];
+                 else
+                     bits += esc_length;
+                 run = 0;
+             } else
+                 run++;
+         }
+         i = scantable[last];
+         level = temp[i] + 64;
 -static int vsad16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2,
 -                    int stride, int h)
 -{
 -    int score = 0, x, y;
 -
 -    for (y = 1; y < h; y++) {
 -        for (x = 0; x < 16; x++)
 -            score += FFABS(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]);
 -        s1 += stride;
 -        s2 += stride;
 -    }
 -
 -    return score;
++        av_assert2(level - 64);
+         if ((level & (~127)) == 0)
+             bits += last_length[UNI_AC_ENC_INDEX(run, level)];
+         else
+             bits += esc_length;
+     }
+     return bits;
+ }
+ #define VSAD_INTRA(size)                                                \
+ static int vsad_intra ## size ## _c(MpegEncContext *c,                  \
+                                     uint8_t *s, uint8_t *dummy,         \
+                                     int stride, int h)                  \
+ {                                                                       \
+     int score = 0, x, y;                                                \
+                                                                         \
+     for (y = 1; y < h; y++) {                                           \
+         for (x = 0; x < size; x += 4) {                                 \
+             score += FFABS(s[x]     - s[x + stride])     +              \
+                      FFABS(s[x + 1] - s[x + stride + 1]) +              \
+                      FFABS(s[x + 2] - s[x + 2 + stride]) +              \
+                      FFABS(s[x + 3] - s[x + 3 + stride]);               \
+         }                                                               \
+         s += stride;                                                    \
+     }                                                                   \
+                                                                         \
+     return score;                                                       \
+ }
+ VSAD_INTRA(8)
+ VSAD_INTRA(16)
 -static int vsse16_c(MpegEncContext *c, uint8_t *s1, uint8_t *s2,
 -                    int stride, int h)
 -{
 -    int score = 0, x, y;
 -
 -    for (y = 1; y < h; y++) {
 -        for (x = 0; x < 16; x++)
 -            score += SQ(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]);
 -        s1 += stride;
 -        s2 += stride;
 -    }
 -
 -    return score;
++#define VSAD(size)                                                             \
++static int vsad ## size ## _c(MpegEncContext *c,                               \
++                              uint8_t *s1, uint8_t *s2,                        \
++                              int stride, int h)                               \
++{                                                                              \
++    int score = 0, x, y;                                                       \
++                                                                               \
++    for (y = 1; y < h; y++) {                                                  \
++        for (x = 0; x < size; x++)                                             \
++            score += FFABS(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]);   \
++        s1 += stride;                                                          \
++        s2 += stride;                                                          \
++    }                                                                          \
++                                                                               \
++    return score;                                                              \
+ }
++VSAD(8)
++VSAD(16)
+ #define SQ(a) ((a) * (a))
+ #define VSSE_INTRA(size)                                                \
+ static int vsse_intra ## size ## _c(MpegEncContext *c,                  \
+                                     uint8_t *s, uint8_t *dummy,         \
+                                     int stride, int h)                  \
+ {                                                                       \
+     int score = 0, x, y;                                                \
+                                                                         \
+     for (y = 1; y < h; y++) {                                           \
+         for (x = 0; x < size; x += 4) {                                 \
+             score += SQ(s[x]     - s[x + stride]) +                     \
+                      SQ(s[x + 1] - s[x + stride + 1]) +                 \
+                      SQ(s[x + 2] - s[x + stride + 2]) +                 \
+                      SQ(s[x + 3] - s[x + stride + 3]);                  \
+         }                                                               \
+         s += stride;                                                    \
+     }                                                                   \
+                                                                         \
+     return score;                                                       \
+ }
+ VSSE_INTRA(8)
+ VSSE_INTRA(16)
++#define VSSE(size)                                                             \
++static int vsse ## size ## _c(MpegEncContext *c, uint8_t *s1, uint8_t *s2,     \
++                    int stride, int h)                                         \
++{                                                                              \
++    int score = 0, x, y;                                                       \
++                                                                               \
++    for (y = 1; y < h; y++) {                                                  \
++        for (x = 0; x < size; x++)                                             \
++            score += SQ(s1[x] - s2[x] - s1[x + stride] + s2[x + stride]);      \
++        s1 += stride;                                                          \
++        s2 += stride;                                                          \
++    }                                                                          \
++                                                                               \
++    return score;                                                              \
+ }
++VSSE(8)
++VSSE(16)
+ #define WRAPPER8_16_SQ(name8, name16)                                   \
+ static int name16(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)
+ #if CONFIG_GPL
+ WRAPPER8_16_SQ(dct264_sad8x8_c, dct264_sad16_c)
+ #endif
+ WRAPPER8_16_SQ(dct_max8x8_c, dct_max16_c)
+ WRAPPER8_16_SQ(quant_psnr8x8_c, quant_psnr16_c)
+ WRAPPER8_16_SQ(rd8x8_c, rd16_c)
+ WRAPPER8_16_SQ(bit8x8_c, bit16_c)
+ av_cold void ff_me_cmp_init_static(void)
+ {
+     int i;
+     for (i = 0; i < 512; i++)
+         ff_square_tab[i] = (i - 256) * (i - 256);
+ }
++int ff_check_alignment(void)
++{
++    static int did_fail = 0;
++    LOCAL_ALIGNED_16(int, aligned, [4]);
++
++    if ((intptr_t)aligned & 15) {
++        if (!did_fail) {
++#if HAVE_MMX || HAVE_ALTIVEC
++            av_log(NULL, AV_LOG_ERROR,
++                "Compiler did not align stack variables. Libavcodec has been miscompiled\n"
++                "and may be very slow or crash. This is not a bug in libavcodec,\n"
++                "but in the compiler. You may try recompiling using gcc >= 4.2.\n"
++                "Do not report crashes to FFmpeg developers.\n");
++#endif
++            did_fail=1;
++        }
++        return -1;
++    }
++    return 0;
++}
++
+ av_cold void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx)
+ {
++    ff_check_alignment();
++
+     c->sum_abs_dctelem = sum_abs_dctelem_c;
+     /* TODO [0] 16  [1] 8 */
+     c->pix_abs[0][0] = pix_abs16_c;
+     c->pix_abs[0][1] = pix_abs16_x2_c;
+     c->pix_abs[0][2] = pix_abs16_y2_c;
+     c->pix_abs[0][3] = pix_abs16_xy2_c;
+     c->pix_abs[1][0] = pix_abs8_c;
+     c->pix_abs[1][1] = pix_abs8_x2_c;
+     c->pix_abs[1][2] = pix_abs8_y2_c;
+     c->pix_abs[1][3] = pix_abs8_xy2_c;
+ #define SET_CMP_FUNC(name)                      \
+     c->name[0] = name ## 16_c;                  \
+     c->name[1] = name ## 8x8_c;
+     SET_CMP_FUNC(hadamard8_diff)
+     c->hadamard8_diff[4] = hadamard8_intra16_c;
+     c->hadamard8_diff[5] = hadamard8_intra8x8_c;
+     SET_CMP_FUNC(dct_sad)
+     SET_CMP_FUNC(dct_max)
+ #if CONFIG_GPL
+     SET_CMP_FUNC(dct264_sad)
+ #endif
+     c->sad[0] = pix_abs16_c;
+     c->sad[1] = pix_abs8_c;
+     c->sse[0] = sse16_c;
+     c->sse[1] = sse8_c;
+     c->sse[2] = sse4_c;
+     SET_CMP_FUNC(quant_psnr)
+     SET_CMP_FUNC(rd)
+     SET_CMP_FUNC(bit)
+     c->vsad[0] = vsad16_c;
++    c->vsad[1] = vsad8_c;
+     c->vsad[4] = vsad_intra16_c;
+     c->vsad[5] = vsad_intra8_c;
+     c->vsse[0] = vsse16_c;
++    c->vsse[1] = vsse8_c;
+     c->vsse[4] = vsse_intra16_c;
+     c->vsse[5] = vsse_intra8_c;
+     c->nsse[0] = nsse16_c;
+     c->nsse[1] = nsse8_c;
++#if CONFIG_SNOW_DECODER || CONFIG_SNOW_ENCODER
++    ff_dsputil_init_dwt(c);
++#endif
++    if (ARCH_ALPHA)
++        ff_me_cmp_init_alpha(c, avctx);
+     if (ARCH_ARM)
+         ff_me_cmp_init_arm(c, avctx);
+     if (ARCH_PPC)
+         ff_me_cmp_init_ppc(c, avctx);
+     if (ARCH_X86)
+         ff_me_cmp_init_x86(c, avctx);
+ }
index 0000000,05ae30b..0e3b922
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,73 +1,94 @@@
 - * This file is part of Libav.
+ /*
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #ifndef AVCODEC_ME_CMP_H
+ #define AVCODEC_ME_CMP_H
+ #include <stdint.h>
+ #include "avcodec.h"
+ extern uint32_t ff_square_tab[512];
++
++/* minimum alignment rules ;)
++ * If you notice errors in the align stuff, need more alignment for some ASM code
++ * for some CPU or need to use a function with less aligned data then send a mail
++ * to the ffmpeg-devel mailing list, ...
++ *
++ * !warning These alignments might not match reality, (missing attribute((align))
++ * stuff somewhere possible).
++ * I (Michael) did not check them, these are just the alignments which I think
++ * could be reached easily ...
++ *
++ * !future video codecs might need functions with less strict alignment
++ */
++
+ struct MpegEncContext;
+ /* 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. */
+ typedef int (*me_cmp_func)(struct MpegEncContext *c,
+                            uint8_t *blk1 /* align width (8 or 16) */,
+                            uint8_t *blk2 /* align 1 */, int line_size, int h);
+ typedef struct MECmpContext {
+     int (*sum_abs_dctelem)(int16_t *block /* align 16 */);
+     me_cmp_func sad[6]; /* identical to pix_absAxA except additional void * */
+     me_cmp_func sse[6];
+     me_cmp_func hadamard8_diff[6];
+     me_cmp_func dct_sad[6];
+     me_cmp_func quant_psnr[6];
+     me_cmp_func bit[6];
+     me_cmp_func rd[6];
+     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];
+     me_cmp_func me_pre_cmp[6];
+     me_cmp_func me_cmp[6];
+     me_cmp_func me_sub_cmp[6];
+     me_cmp_func mb_cmp[6];
+     me_cmp_func ildct_cmp[6]; // only width 16 used
+     me_cmp_func frame_skip_cmp[6]; // only width 8 used
+     me_cmp_func pix_abs[2][4];
+ } MECmpContext;
+ void ff_me_cmp_init_static(void);
++int ff_check_alignment(void);
++
+ void ff_me_cmp_init(MECmpContext *c, AVCodecContext *avctx);
++void ff_me_cmp_init_alpha(MECmpContext *c, AVCodecContext *avctx);
+ void ff_me_cmp_init_arm(MECmpContext *c, AVCodecContext *avctx);
+ void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx);
+ void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx);
+ void ff_set_cmp(MECmpContext *c, me_cmp_func *cmp, int type);
++void ff_dsputil_init_dwt(MECmpContext *c);
++
+ #endif /* AVCODEC_ME_CMP_H */
index 7308717,0000000..7cfe41c
mode 100644,000000..100644
--- /dev/null
@@@ -1,152 -1,0 +1,152 @@@
- #include "dsputil.h"
 +/*
 + * (c) 2001 Fabrice Bellard
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +/**
 + * @file
 + * motion test.
 + */
 +
 +#include <stdlib.h>
 +#include <stdio.h>
 +#include <string.h>
 +
 +#include "config.h"
-     DSPContext cctx, mmxctx;
++#include "me_cmp.h"
 +#include "libavutil/internal.h"
 +#include "libavutil/lfg.h"
 +#include "libavutil/mem.h"
 +#include "libavutil/time.h"
 +
 +#undef printf
 +
 +#define WIDTH 64
 +#define HEIGHT 64
 +
 +static uint8_t img1[WIDTH * HEIGHT];
 +static uint8_t img2[WIDTH * HEIGHT];
 +
 +static void fill_random(uint8_t *tab, int size)
 +{
 +    int i;
 +    AVLFG prng;
 +
 +    av_lfg_init(&prng, 1);
 +    for(i=0;i<size;i++) {
 +        tab[i] = av_lfg_get(&prng) % 256;
 +    }
 +}
 +
 +static void help(void)
 +{
 +    printf("motion-test [-h]\n"
 +           "test motion implementations\n");
 +}
 +
 +#define NB_ITS 500
 +
 +int dummy;
 +
 +static void test_motion(const char *name,
 +                 me_cmp_func test_func, me_cmp_func ref_func)
 +{
 +    int x, y, d1, d2, it;
 +    uint8_t *ptr;
 +    int64_t ti;
 +    printf("testing '%s'\n", name);
 +
 +    /* test correctness */
 +    for(it=0;it<20;it++) {
 +
 +        fill_random(img1, WIDTH * HEIGHT);
 +        fill_random(img2, WIDTH * HEIGHT);
 +
 +        for(y=0;y<HEIGHT-17;y++) {
 +            for(x=0;x<WIDTH-17;x++) {
 +                ptr = img2 + y * WIDTH + x;
 +                d1 = test_func(NULL, img1, ptr, WIDTH, 8);
 +                d2 = ref_func(NULL, img1, ptr, WIDTH, 8);
 +                if (d1 != d2) {
 +                    printf("error: mmx=%d c=%d\n", d1, d2);
 +                }
 +            }
 +        }
 +    }
 +    emms_c();
 +
 +    /* speed test */
 +    ti = av_gettime_relative();
 +    d1 = 0;
 +    for(it=0;it<NB_ITS;it++) {
 +        for(y=0;y<HEIGHT-17;y++) {
 +            for(x=0;x<WIDTH-17;x++) {
 +                ptr = img2 + y * WIDTH + x;
 +                d1 += test_func(NULL, img1, ptr, WIDTH, 8);
 +            }
 +        }
 +    }
 +    emms_c();
 +    dummy = d1; /* avoid optimization */
 +    ti = av_gettime_relative() - ti;
 +
 +    printf("  %0.0f kop/s\n",
 +           (double)NB_ITS * (WIDTH - 16) * (HEIGHT - 16) /
 +           (double)(ti / 1000.0));
 +}
 +
 +
 +int main(int argc, char **argv)
 +{
 +    AVCodecContext *ctx;
 +    int c;
-     ff_dsputil_init(&cctx, ctx);
++    MECmpContext cctx, mmxctx;
 +    int flags[2] = { AV_CPU_FLAG_MMX, AV_CPU_FLAG_MMXEXT };
 +    int flags_size = HAVE_MMXEXT ? 2 : 1;
 +
 +    if (argc > 1) {
 +        help();
 +        return 1;
 +    }
 +
 +    printf("ffmpeg motion test\n");
 +
 +    ctx = avcodec_alloc_context3(NULL);
 +    ctx->flags |= CODEC_FLAG_BITEXACT;
 +    av_force_cpu_flags(0);
 +    memset(&cctx, 0, sizeof(cctx));
-         ff_dsputil_init(&mmxctx, ctx);
++    ff_me_cmp_init(&cctx, ctx);
 +    for (c = 0; c < flags_size; c++) {
 +        int x;
 +        av_force_cpu_flags(flags[c]);
 +        memset(&mmxctx, 0, sizeof(mmxctx));
++        ff_me_cmp_init(&mmxctx, ctx);
 +
 +        for (x = 0; x < 2; x++) {
 +            printf("%s for %dx%d pixels\n", c ? "mmx2" : "mmx",
 +                   x ? 8 : 16, x ? 8 : 16);
 +            test_motion("mmx",     mmxctx.pix_abs[x][0], cctx.pix_abs[x][0]);
 +            test_motion("mmx_x2",  mmxctx.pix_abs[x][1], cctx.pix_abs[x][1]);
 +            test_motion("mmx_y2",  mmxctx.pix_abs[x][2], cctx.pix_abs[x][2]);
 +            test_motion("mmx_xy2", mmxctx.pix_abs[x][3], cctx.pix_abs[x][3]);
 +        }
 +    }
 +    av_free(ctx);
 +
 +    return 0;
 +}
@@@ -360,16 -361,12 +360,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;
-         }
 -    if ((c->avctx->me_cmp & FF_CMP_CHROMA) /* && !s->mecc.me_cmp[2] */)
 -        s->mecc.me_cmp[2] = zero_cmp;
 -    if ((c->avctx->me_sub_cmp & FF_CMP_CHROMA) && !s->mecc.me_sub_cmp[2])
 -        s->mecc.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_SNOW) {
++        if ((c->avctx->me_cmp & FF_CMP_CHROMA) /* && !s->mecc.me_cmp[2] */)
++            s->mecc.me_cmp[2] = zero_cmp;
++        if ((c->avctx->me_sub_cmp & FF_CMP_CHROMA) && !s->mecc.me_sub_cmp[2])
++            s->mecc.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;
@@@ -178,9 -178,12 +177,9 @@@ static inline int get_mb_score(MpegEncC
  
   //FIXME factorize
  
-     cmp_sub= s->dsp.mb_cmp[size];
-     chroma_cmp_sub= s->dsp.mb_cmp[size+1];
+     cmp_sub        = s->mecc.mb_cmp[size];
+     chroma_cmp_sub = s->mecc.mb_cmp[size + 1];
  
 -//    assert(!c->skip);
 -//    assert(c->avctx->me_sub_cmp != c->avctx->mb_cmp);
 -
      d= cmp(s, mx>>(qpel+1), my>>(qpel+1), mx&mask, my&mask, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
      //FIXME check cbp before adding penalty for (0,0) vector
      if(add_rate && (mx || my || size>0))
@@@ -690,10 -693,8 +689,10 @@@ static int sab_diamond_search(MpegEncCo
      LOAD_COMMON2
      unsigned map_generation = c->map_generation;
  
-     cmpf= s->dsp.me_cmp[size];
-     chroma_cmpf= s->dsp.me_cmp[size+1];
 +    av_assert1(minima_count <= MAX_SAB_SIZE);
 +
+     cmpf        = s->mecc.me_cmp[size];
+     chroma_cmpf = s->mecc.me_cmp[size + 1];
  
      /*Note j<MAX_SAB_SIZE is needed if MAX_SAB_SIZE < ME_MAP_SIZE as j can
        become larger due to MVs overflowing their ME_MAP_MV_BITS bits space in map
@@@ -685,21 -689,7 +685,21 @@@ void ff_mpeg4_encode_mb(MpegEncContext 
                          b_pic = pic->f->data[0] + offset;
                          if (!pic->shared)
                              b_pic += INPLACE_OFFSET;
 -                        diff = s->mecc.sad[0](NULL, p_pic, b_pic, s->linesize, 16);
 +
 +                        if (x + 16 > s->width || y + 16 > s->height) {
 +                            int x1, y1;
 +                            int xe = FFMIN(16, s->width - x);
 +                            int ye = FFMIN(16, s->height - y);
 +                            diff = 0;
 +                            for (y1 = 0; y1 < ye; y1++) {
 +                                for (x1 = 0; x1 < xe; x1++) {
 +                                    diff += FFABS(p_pic[x1 + y1 * s->linesize] - b_pic[x1 + y1 * s->linesize]);
 +                                }
 +                            }
 +                            diff = diff * 256 / (xe * ye);
 +                        } else {
-                             diff = s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16);
++                            diff = s->mecc.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;
@@@ -380,10 -378,9 +380,10 @@@ static void gray8(uint8_t *dst, const u
  av_cold int ff_dct_common_init(MpegEncContext *s)
  {
      ff_blockdsp_init(&s->bdsp, s->avctx);
-     ff_dsputil_init(&s->dsp, s->avctx);
 +    ff_h264chroma_init(&s->h264chroma, 8); //for lowres
      ff_hpeldsp_init(&s->hdsp, s->avctx->flags);
      ff_idctdsp_init(&s->idsp, s->avctx);
+     ff_me_cmp_init(&s->mecc, s->avctx);
      ff_mpegvideodsp_init(&s->mdsp);
      ff_videodsp_init(&s->vdsp, s->avctx->bits_per_raw_sample);
  
@@@ -365,11 -356,10 +365,11 @@@ typedef struct MpegEncContext 
      int h263_long_vectors;      ///< use horrible h263v1 long vector mode
  
      BlockDSPContext bdsp;
-     DSPContext dsp;             ///< pointers for accelerated dsp functions
      FDCTDSPContext fdsp;
 +    H264ChromaContext h264chroma;
      HpelDSPContext hdsp;
      IDCTDSPContext idsp;
+     MECmpContext mecc;
      MpegVideoDSPContext mdsp;
      MpegvideoEncDSPContext mpvencdsp;
      PixblockDSPContext pdsp;
@@@ -835,7 -698,11 +835,8 @@@ av_cold int ff_MPV_encode_init(AVCodecC
      if (ff_MPV_common_init(s) < 0)
          return -1;
  
 -    if (ARCH_X86)
 -        ff_MPV_encode_init_x86(s);
 -
      ff_fdctdsp_init(&s->fdsp, avctx);
+     ff_me_cmp_init(&s->mecc, avctx);
      ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
      ff_pixblockdsp_init(&s->pdsp, avctx);
      ff_qpeldsp_init(&s->qdsp);
@@@ -1205,14 -1054,14 +1206,14 @@@ static int skip_check(MpegEncContext *s
                  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);
+                 int v = s->mecc.frame_skip_cmp[1](s, dptr, rptr, stride, 8);
  
 -                switch (s->avctx->frame_skip_exp) {
 +                switch (FFABS(s->avctx->frame_skip_exp)) {
                  case 0: score    =  FFMAX(score, v);          break;
                  case 1: score   += FFABS(v);                  break;
 -                case 2: score   += v * v;                     break;
 -                case 3: score64 += FFABS(v * v * (int64_t)v); break;
 -                case 4: score64 += v * v * (int64_t)(v * v);  break;
 +                case 2: score64 += v * (int64_t)v;                       break;
 +                case 3: score64 += FFABS(v * (int64_t)v * v);            break;
 +                case 4: score64 += (v * (int64_t)v) * (v * (int64_t)v);  break;
                  }
              }
          }
@@@ -2223,33 -2046,28 +2220,28 @@@ static av_always_inline void encode_mb_
          if (s->current_picture.mc_mb_var[s->mb_stride * mb_y + mb_x] <
                  2 * s->qscale * s->qscale) {
              // FIXME optimize
-             if (s->dsp.sad[1](NULL, ptr_y , dest_y,
-                               wrap_y, 8) < 20 * s->qscale)
+             if (s->mecc.sad[1](NULL, ptr_y, dest_y, wrap_y, 8) < 20 * s->qscale)
                  skip_dct[0] = 1;
-             if (s->dsp.sad[1](NULL, ptr_y + 8,
-                               dest_y + 8, wrap_y, 8) < 20 * s->qscale)
+             if (s->mecc.sad[1](NULL, ptr_y + 8, dest_y + 8, wrap_y, 8) < 20 * s->qscale)
                  skip_dct[1] = 1;
-             if (s->dsp.sad[1](NULL, ptr_y + dct_offset,
-                               dest_y + dct_offset, wrap_y, 8) < 20 * s->qscale)
+             if (s->mecc.sad[1](NULL, ptr_y + dct_offset, dest_y + dct_offset,
+                                wrap_y, 8) < 20 * s->qscale)
                  skip_dct[2] = 1;
-             if (s->dsp.sad[1](NULL, ptr_y + dct_offset + 8,
-                               dest_y + dct_offset + 8,
-                               wrap_y, 8) < 20 * s->qscale)
+             if (s->mecc.sad[1](NULL, ptr_y + dct_offset + 8, dest_y + dct_offset + 8,
+                                wrap_y, 8) < 20 * s->qscale)
                  skip_dct[3] = 1;
-             if (s->dsp.sad[1](NULL, ptr_cb, dest_cb,
-                               wrap_c, 8) < 20 * s->qscale)
+             if (s->mecc.sad[1](NULL, ptr_cb, dest_cb, wrap_c, 8) < 20 * s->qscale)
                  skip_dct[4] = 1;
-             if (s->dsp.sad[1](NULL, ptr_cr, dest_cr,
-                               wrap_c, 8) < 20 * s->qscale)
+             if (s->mecc.sad[1](NULL, ptr_cr, dest_cr, wrap_c, 8) < 20 * s->qscale)
                  skip_dct[5] = 1;
              if (!s->chroma_y_shift) { /* 422 */
-                 if (s->dsp.sad[1](NULL, ptr_cb + uv_dct_offset,
-                                   dest_cb + uv_dct_offset,
-                                   wrap_c, 8) < 20 * s->qscale)
 -                if (s->mecc.sad[1](NULL, ptr_cb + (dct_offset >> 1),
 -                                   dest_cb + (dct_offset >> 1),
++                if (s->mecc.sad[1](NULL, ptr_cb + uv_dct_offset,
++                                   dest_cb + uv_dct_offset,
+                                    wrap_c, 8) < 20 * s->qscale)
                      skip_dct[6] = 1;
-                 if (s->dsp.sad[1](NULL, ptr_cr + uv_dct_offset,
-                                   dest_cr + uv_dct_offset,
-                                   wrap_c, 8) < 20 * s->qscale)
 -                if (s->mecc.sad[1](NULL, ptr_cr + (dct_offset >> 1),
 -                                   dest_cr + (dct_offset >> 1),
++                if (s->mecc.sad[1](NULL, ptr_cr + uv_dct_offset,
++                                   dest_cr + uv_dct_offset,
+                                    wrap_c, 8) < 20 * s->qscale)
                      skip_dct[7] = 1;
              }
          }
Simple merge
@@@ -2,10 -2,9 +2,9 @@@ OBJS                                   
  
  OBJS-$(CONFIG_AUDIODSP)                += ppc/audiodsp.o
  OBJS-$(CONFIG_BLOCKDSP)                += ppc/blockdsp.o
- OBJS-$(CONFIG_DSPUTIL)                 += ppc/dsputil_altivec.o
  OBJS-$(CONFIG_FFT)                     += ppc/fft_altivec.o
  OBJS-$(CONFIG_H264CHROMA)              += ppc/h264chroma_init.o
 -OBJS-$(CONFIG_H264DSP)                 += ppc/h264dsp.o
 +OBJS-$(CONFIG_H264DSP)                 += ppc/h264dsp.o ppc/hpeldsp_altivec.o
  OBJS-$(CONFIG_H264QPEL)                += ppc/h264qpel.o
  OBJS-$(CONFIG_HPELDSP)                 += ppc/hpeldsp_altivec.o
  OBJS-$(CONFIG_HUFFYUVDSP)              += ppc/huffyuvdsp_altivec.o
index 0000000,88c7fea..18f2c6e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,767 +1,767 @@@
 - * This file is part of Libav.
+ /*
+  * Copyright (c) 2002 Brian Foley
+  * Copyright (c) 2002 Dieter Shirley
+  * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org>
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "config.h"
+ #if HAVE_ALTIVEC_H
+ #include <altivec.h>
+ #endif
+ #include "libavutil/attributes.h"
+ #include "libavutil/cpu.h"
+ #include "libavutil/ppc/cpu.h"
+ #include "libavutil/ppc/types_altivec.h"
+ #include "libavutil/ppc/util_altivec.h"
+ #include "libavcodec/avcodec.h"
+ #include "libavcodec/mpegvideo.h"
+ #include "libavcodec/me_cmp.h"
+ #if HAVE_ALTIVEC
+ static int sad16_x2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                             int line_size, int h)
+ {
+     int i, s = 0;
+     const vector unsigned char zero =
+         (const vector unsigned char) vec_splat_u8(0);
+     vector unsigned char perm1 = vec_lvsl(0, pix2);
+     vector unsigned char perm2 = vec_add(perm1, vec_splat_u8(1));
+     vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
+     vector signed int sumdiffs;
+     for (i = 0; i < h; i++) {
+         /* Read unaligned pixels into our vectors. The vectors are as follows:
+          * pix1v: pix1[0] - pix1[15]
+          * pix2v: pix2[0] - pix2[15]      pix2iv: pix2[1] - pix2[16] */
+         vector unsigned char pix1v  = vec_ld(0,  pix1);
+         vector unsigned char pix2l  = vec_ld(0,  pix2);
+         vector unsigned char pix2r  = vec_ld(16, pix2);
+         vector unsigned char pix2v  = vec_perm(pix2l, pix2r, perm1);
+         vector unsigned char pix2iv = vec_perm(pix2l, pix2r, perm2);
+         /* Calculate the average vector. */
+         vector unsigned char avgv = vec_avg(pix2v, pix2iv);
+         /* Calculate a sum of abs differences vector. */
+         vector unsigned char t5 = vec_sub(vec_max(pix1v, avgv),
+                                           vec_min(pix1v, avgv));
+         /* Add each 4 pixel group together and put 4 results into sad. */
+         sad = vec_sum4s(t5, sad);
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     /* Sum up the four partial sums, and put the result into s. */
+     sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
+     sumdiffs = vec_splat(sumdiffs, 3);
+     vec_ste(sumdiffs, 0, &s);
+     return s;
+ }
+ static int sad16_y2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                             int line_size, int h)
+ {
+     int i, s = 0;
+     const vector unsigned char zero =
+         (const vector unsigned char) vec_splat_u8(0);
+     vector unsigned char perm = vec_lvsl(0, pix2);
+     vector unsigned char pix1v, pix3v, avgv, t5;
+     vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
+     vector signed int sumdiffs;
+     uint8_t *pix3 = pix2 + line_size;
+     /* Due to the fact that pix3 = pix2 + line_size, the pix3 of one
+      * iteration becomes pix2 in the next iteration. We can use this
+      * fact to avoid a potentially expensive unaligned read, each
+      * time around the loop.
+      * Read unaligned pixels into our vectors. The vectors are as follows:
+      * pix2v: pix2[0] - pix2[15]
+      * Split the pixel vectors into shorts. */
+     vector unsigned char pix2l = vec_ld(0,  pix2);
+     vector unsigned char pix2r = vec_ld(15, pix2);
+     vector unsigned char pix2v = vec_perm(pix2l, pix2r, perm);
+     for (i = 0; i < h; i++) {
+         /* Read unaligned pixels into our vectors. The vectors are as follows:
+          * pix1v: pix1[0] - pix1[15]
+          * pix3v: pix3[0] - pix3[15] */
+         pix1v = vec_ld(0,  pix1);
+         pix2l = vec_ld(0,  pix3);
+         pix2r = vec_ld(15, pix3);
+         pix3v = vec_perm(pix2l, pix2r, perm);
+         /* Calculate the average vector. */
+         avgv = vec_avg(pix2v, pix3v);
+         /* Calculate a sum of abs differences vector. */
+         t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv));
+         /* Add each 4 pixel group together and put 4 results into sad. */
+         sad = vec_sum4s(t5, sad);
+         pix1 += line_size;
+         pix2v = pix3v;
+         pix3 += line_size;
+     }
+     /* Sum up the four partial sums, and put the result into s. */
+     sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
+     sumdiffs = vec_splat(sumdiffs, 3);
+     vec_ste(sumdiffs, 0, &s);
+     return s;
+ }
+ static int sad16_xy2_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                              int line_size, int h)
+ {
+     int i, s = 0;
+     uint8_t *pix3 = pix2 + line_size;
+     const vector unsigned char zero =
+         (const vector unsigned char) vec_splat_u8(0);
+     const vector unsigned short two =
+         (const vector unsigned short) vec_splat_u16(2);
+     vector unsigned char avgv, t5;
+     vector unsigned char perm1 = vec_lvsl(0, pix2);
+     vector unsigned char perm2 = vec_add(perm1, vec_splat_u8(1));
+     vector unsigned char pix1v, pix3v, pix3iv;
+     vector unsigned short pix3lv, pix3hv, pix3ilv, pix3ihv;
+     vector unsigned short avghv, avglv;
+     vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
+     vector signed int sumdiffs;
+     /* Due to the fact that pix3 = pix2 + line_size, the pix3 of one
+      * iteration becomes pix2 in the next iteration. We can use this
+      * fact to avoid a potentially expensive unaligned read, as well
+      * as some splitting, and vector addition each time around the loop.
+      * Read unaligned pixels into our vectors. The vectors are as follows:
+      * pix2v: pix2[0] - pix2[15]  pix2iv: pix2[1] - pix2[16]
+      * Split the pixel vectors into shorts. */
+     vector unsigned char pix2l  = vec_ld(0,  pix2);
+     vector unsigned char pix2r  = vec_ld(16, pix2);
+     vector unsigned char pix2v  = vec_perm(pix2l, pix2r, perm1);
+     vector unsigned char pix2iv = vec_perm(pix2l, pix2r, perm2);
+     vector unsigned short pix2hv  =
+         (vector unsigned short) vec_mergeh(zero, pix2v);
+     vector unsigned short pix2lv  =
+         (vector unsigned short) vec_mergel(zero, pix2v);
+     vector unsigned short pix2ihv =
+         (vector unsigned short) vec_mergeh(zero, pix2iv);
+     vector unsigned short pix2ilv =
+         (vector unsigned short) vec_mergel(zero, pix2iv);
+     vector unsigned short t1 = vec_add(pix2hv, pix2ihv);
+     vector unsigned short t2 = vec_add(pix2lv, pix2ilv);
+     vector unsigned short t3, t4;
+     for (i = 0; i < h; i++) {
+         /* Read unaligned pixels into our vectors. The vectors are as follows:
+          * pix1v: pix1[0] - pix1[15]
+          * pix3v: pix3[0] - pix3[15]      pix3iv: pix3[1] - pix3[16] */
+         pix1v  = vec_ld(0, pix1);
+         pix2l  = vec_ld(0, pix3);
+         pix2r  = vec_ld(16, pix3);
+         pix3v  = vec_perm(pix2l, pix2r, perm1);
+         pix3iv = vec_perm(pix2l, pix2r, perm2);
+         /* Note that AltiVec does have vec_avg, but this works on vector pairs
+          * and rounds up. We could do avg(avg(a, b), avg(c, d)), but the
+          * rounding would mean that, for example, avg(3, 0, 0, 1) = 2, when
+          * it should be 1. Instead, we have to split the pixel vectors into
+          * vectors of shorts and do the averaging by hand. */
+         /* Split the pixel vectors into shorts. */
+         pix3hv  = (vector unsigned short) vec_mergeh(zero, pix3v);
+         pix3lv  = (vector unsigned short) vec_mergel(zero, pix3v);
+         pix3ihv = (vector unsigned short) vec_mergeh(zero, pix3iv);
+         pix3ilv = (vector unsigned short) vec_mergel(zero, pix3iv);
+         /* Do the averaging on them. */
+         t3 = vec_add(pix3hv, pix3ihv);
+         t4 = vec_add(pix3lv, pix3ilv);
+         avghv = vec_sr(vec_add(vec_add(t1, t3), two), two);
+         avglv = vec_sr(vec_add(vec_add(t2, t4), two), two);
+         /* Pack the shorts back into a result. */
+         avgv = vec_pack(avghv, avglv);
+         /* Calculate a sum of abs differences vector. */
+         t5 = vec_sub(vec_max(pix1v, avgv), vec_min(pix1v, avgv));
+         /* Add each 4 pixel group together and put 4 results into sad. */
+         sad = vec_sum4s(t5, sad);
+         pix1 += line_size;
+         pix3 += line_size;
+         /* Transfer the calculated values for pix3 into pix2. */
+         t1 = t3;
+         t2 = t4;
+     }
+     /* Sum up the four partial sums, and put the result into s. */
+     sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
+     sumdiffs = vec_splat(sumdiffs, 3);
+     vec_ste(sumdiffs, 0, &s);
+     return s;
+ }
+ static int sad16_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                          int line_size, int h)
+ {
+     int i, s;
+     const vector unsigned int zero =
+         (const vector unsigned int) vec_splat_u32(0);
+     vector unsigned char perm = vec_lvsl(0, pix2);
+     vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
+     vector signed int sumdiffs;
+     for (i = 0; i < h; i++) {
+         /* Read potentially unaligned pixels into t1 and t2. */
+         vector unsigned char pix2l = vec_ld(0,  pix2);
+         vector unsigned char pix2r = vec_ld(15, pix2);
+         vector unsigned char t1 = vec_ld(0, pix1);
+         vector unsigned char t2 = vec_perm(pix2l, pix2r, perm);
+         /* Calculate a sum of abs differences vector. */
+         vector unsigned char t3 = vec_max(t1, t2);
+         vector unsigned char t4 = vec_min(t1, t2);
+         vector unsigned char t5 = vec_sub(t3, t4);
+         /* Add each 4 pixel group together and put 4 results into sad. */
+         sad = vec_sum4s(t5, sad);
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     /* Sum up the four partial sums, and put the result into s. */
+     sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
+     sumdiffs = vec_splat(sumdiffs, 3);
+     vec_ste(sumdiffs, 0, &s);
+     return s;
+ }
+ static int sad8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                         int line_size, int h)
+ {
+     int i, s;
+     const vector unsigned int zero =
+         (const vector unsigned int) vec_splat_u32(0);
+     const vector unsigned char permclear =
+         (vector unsigned char)
+         { 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0 };
+     vector unsigned char perm1 = vec_lvsl(0, pix1);
+     vector unsigned char perm2 = vec_lvsl(0, pix2);
+     vector unsigned int sad = (vector unsigned int) vec_splat_u32(0);
+     vector signed int sumdiffs;
+     for (i = 0; i < h; i++) {
+         /* Read potentially unaligned pixels into t1 and t2.
+          * Since we're reading 16 pixels, and actually only want 8,
+          * mask out the last 8 pixels. The 0s don't change the sum. */
+         vector unsigned char pix1l = vec_ld(0, pix1);
+         vector unsigned char pix1r = vec_ld(7, pix1);
+         vector unsigned char pix2l = vec_ld(0, pix2);
+         vector unsigned char pix2r = vec_ld(7, pix2);
+         vector unsigned char t1 = vec_and(vec_perm(pix1l, pix1r, perm1),
+                                           permclear);
+         vector unsigned char t2 = vec_and(vec_perm(pix2l, pix2r, perm2),
+                                           permclear);
+         /* Calculate a sum of abs differences vector. */
+         vector unsigned char t3 = vec_max(t1, t2);
+         vector unsigned char t4 = vec_min(t1, t2);
+         vector unsigned char t5 = vec_sub(t3, t4);
+         /* Add each 4 pixel group together and put 4 results into sad. */
+         sad = vec_sum4s(t5, sad);
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     /* Sum up the four partial sums, and put the result into s. */
+     sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero);
+     sumdiffs = vec_splat(sumdiffs, 3);
+     vec_ste(sumdiffs, 0, &s);
+     return s;
+ }
+ /* Sum of Squared Errors for an 8x8 block, AltiVec-enhanced.
+  * It's the sad8_altivec code above w/ squaring added. */
+ static int sse8_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                         int line_size, int h)
+ {
+     int i, s;
+     const vector unsigned int zero =
+         (const vector unsigned int) vec_splat_u32(0);
+     const vector unsigned char permclear =
+         (vector unsigned char)
+         { 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0 };
+     vector unsigned char perm1 = vec_lvsl(0, pix1);
+     vector unsigned char perm2 = vec_lvsl(0, pix2);
+     vector unsigned int sum = (vector unsigned int) vec_splat_u32(0);
+     vector signed int sumsqr;
+     for (i = 0; i < h; i++) {
+         /* Read potentially unaligned pixels into t1 and t2.
+          * Since we're reading 16 pixels, and actually only want 8,
+          * mask out the last 8 pixels. The 0s don't change the sum. */
+         vector unsigned char pix1l = vec_ld(0, pix1);
+         vector unsigned char pix1r = vec_ld(7, pix1);
+         vector unsigned char pix2l = vec_ld(0, pix2);
+         vector unsigned char pix2r = vec_ld(7, pix2);
+         vector unsigned char t1 = vec_and(vec_perm(pix1l, pix1r, perm1),
+                                           permclear);
+         vector unsigned char t2 = vec_and(vec_perm(pix2l, pix2r, perm2),
+                                           permclear);
+         /* Since we want to use unsigned chars, we can take advantage
+          * of the fact that abs(a - b) ^ 2 = (a - b) ^ 2. */
+         /* Calculate abs differences vector. */
+         vector unsigned char t3 = vec_max(t1, t2);
+         vector unsigned char t4 = vec_min(t1, t2);
+         vector unsigned char t5 = vec_sub(t3, t4);
+         /* Square the values and add them to our sum. */
+         sum = vec_msum(t5, t5, sum);
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     /* Sum up the four partial sums, and put the result into s. */
+     sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);
+     sumsqr = vec_splat(sumsqr, 3);
+     vec_ste(sumsqr, 0, &s);
+     return s;
+ }
+ /* Sum of Squared Errors for a 16x16 block, AltiVec-enhanced.
+  * It's the sad16_altivec code above w/ squaring added. */
+ static int sse16_altivec(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2,
+                          int line_size, int h)
+ {
+     int i, s;
+     const vector unsigned int zero =
+         (const vector unsigned int) vec_splat_u32(0);
+     vector unsigned char perm = vec_lvsl(0, pix2);
+     vector unsigned int sum = (vector unsigned int) vec_splat_u32(0);
+     vector signed int sumsqr;
+     for (i = 0; i < h; i++) {
+         /* Read potentially unaligned pixels into t1 and t2. */
+         vector unsigned char pix2l = vec_ld(0,  pix2);
+         vector unsigned char pix2r = vec_ld(15, pix2);
+         vector unsigned char t1 = vec_ld(0, pix1);
+         vector unsigned char t2 = vec_perm(pix2l, pix2r, perm);
+         /* Since we want to use unsigned chars, we can take advantage
+          * of the fact that abs(a - b) ^ 2 = (a - b) ^ 2. */
+         /* Calculate abs differences vector. */
+         vector unsigned char t3 = vec_max(t1, t2);
+         vector unsigned char t4 = vec_min(t1, t2);
+         vector unsigned char t5 = vec_sub(t3, t4);
+         /* Square the values and add them to our sum. */
+         sum = vec_msum(t5, t5, sum);
+         pix1 += line_size;
+         pix2 += line_size;
+     }
+     /* Sum up the four partial sums, and put the result into s. */
+     sumsqr = vec_sums((vector signed int) sum, (vector signed int) zero);
+     sumsqr = vec_splat(sumsqr, 3);
+     vec_ste(sumsqr, 0, &s);
+     return s;
+ }
+ static int hadamard8_diff8x8_altivec(MpegEncContext *s, uint8_t *dst,
+                                      uint8_t *src, int stride, int h)
+ {
+     int sum;
+     register const vector unsigned char vzero =
+         (const vector unsigned char) vec_splat_u8(0);
+     register vector signed short temp0, temp1, temp2, temp3, temp4,
+                                  temp5, temp6, temp7;
+     {
+         register const vector signed short vprod1 =
+             (const vector signed short) { 1, -1, 1, -1, 1, -1, 1, -1 };
+         register const vector signed short vprod2 =
+             (const vector signed short) { 1, 1, -1, -1, 1, 1, -1, -1 };
+         register const vector signed short vprod3 =
+             (const vector signed short) { 1, 1, 1, 1, -1, -1, -1, -1 };
+         register const vector unsigned char perm1 =
+             (const vector unsigned char)
+             { 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05,
+               0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D };
+         register const vector unsigned char perm2 =
+             (const vector unsigned char)
+             { 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03,
+               0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B };
+         register const vector unsigned char perm3 =
+             (const vector unsigned char)
+             { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+               0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
+ #define ONEITERBUTTERFLY(i, res)                                            \
+     {                                                                       \
+         register vector unsigned char src1 = vec_ld(stride * i, src);       \
+         register vector unsigned char src2 = vec_ld(stride * i + 15, src);  \
+         register vector unsigned char srcO =                                \
+             vec_perm(src1, src2, vec_lvsl(stride * i, src));                \
+         register vector unsigned char dst1 = vec_ld(stride * i, dst);       \
+         register vector unsigned char dst2 = vec_ld(stride * i + 15, dst);  \
+         register vector unsigned char dstO =                                \
+             vec_perm(dst1, dst2, vec_lvsl(stride * i, dst));                \
+                                                                             \
+         /* Promote the unsigned chars to signed shorts. */                  \
+         /* We're in the 8x8 function, we only care for the first 8. */      \
+         register vector signed short srcV =                                 \
+             (vector signed short) vec_mergeh((vector signed char) vzero,    \
+                                              (vector signed char) srcO);    \
+         register vector signed short dstV =                                 \
+             (vector signed short) vec_mergeh((vector signed char) vzero,    \
+                                              (vector signed char) dstO);    \
+                                                                             \
+         /* subtractions inside the first butterfly */                       \
+         register vector signed short but0 = vec_sub(srcV, dstV);            \
+         register vector signed short op1  = vec_perm(but0, but0, perm1);    \
+         register vector signed short but1 = vec_mladd(but0, vprod1, op1);   \
+         register vector signed short op2  = vec_perm(but1, but1, perm2);    \
+         register vector signed short but2 = vec_mladd(but1, vprod2, op2);   \
+         register vector signed short op3  = vec_perm(but2, but2, perm3);    \
+         res  = vec_mladd(but2, vprod3, op3);                                \
+     }
+         ONEITERBUTTERFLY(0, temp0);
+         ONEITERBUTTERFLY(1, temp1);
+         ONEITERBUTTERFLY(2, temp2);
+         ONEITERBUTTERFLY(3, temp3);
+         ONEITERBUTTERFLY(4, temp4);
+         ONEITERBUTTERFLY(5, temp5);
+         ONEITERBUTTERFLY(6, temp6);
+         ONEITERBUTTERFLY(7, temp7);
+     }
+ #undef ONEITERBUTTERFLY
+     {
+         register vector signed int vsum;
+         register vector signed short line0  = vec_add(temp0, temp1);
+         register vector signed short line1  = vec_sub(temp0, temp1);
+         register vector signed short line2  = vec_add(temp2, temp3);
+         register vector signed short line3  = vec_sub(temp2, temp3);
+         register vector signed short line4  = vec_add(temp4, temp5);
+         register vector signed short line5  = vec_sub(temp4, temp5);
+         register vector signed short line6  = vec_add(temp6, temp7);
+         register vector signed short line7  = vec_sub(temp6, temp7);
+         register vector signed short line0B = vec_add(line0, line2);
+         register vector signed short line2B = vec_sub(line0, line2);
+         register vector signed short line1B = vec_add(line1, line3);
+         register vector signed short line3B = vec_sub(line1, line3);
+         register vector signed short line4B = vec_add(line4, line6);
+         register vector signed short line6B = vec_sub(line4, line6);
+         register vector signed short line5B = vec_add(line5, line7);
+         register vector signed short line7B = vec_sub(line5, line7);
+         register vector signed short line0C = vec_add(line0B, line4B);
+         register vector signed short line4C = vec_sub(line0B, line4B);
+         register vector signed short line1C = vec_add(line1B, line5B);
+         register vector signed short line5C = vec_sub(line1B, line5B);
+         register vector signed short line2C = vec_add(line2B, line6B);
+         register vector signed short line6C = vec_sub(line2B, line6B);
+         register vector signed short line3C = vec_add(line3B, line7B);
+         register vector signed short line7C = vec_sub(line3B, line7B);
+         vsum = vec_sum4s(vec_abs(line0C), vec_splat_s32(0));
+         vsum = vec_sum4s(vec_abs(line1C), vsum);
+         vsum = vec_sum4s(vec_abs(line2C), vsum);
+         vsum = vec_sum4s(vec_abs(line3C), vsum);
+         vsum = vec_sum4s(vec_abs(line4C), vsum);
+         vsum = vec_sum4s(vec_abs(line5C), vsum);
+         vsum = vec_sum4s(vec_abs(line6C), vsum);
+         vsum = vec_sum4s(vec_abs(line7C), vsum);
+         vsum = vec_sums(vsum, (vector signed int) vzero);
+         vsum = vec_splat(vsum, 3);
+         vec_ste(vsum, 0, &sum);
+     }
+     return sum;
+ }
+ /*
+  * 16x8 works with 16 elements; it allows to avoid replicating loads, and
+  * gives the compiler more room for scheduling. It's only used from
+  * inside hadamard8_diff16_altivec.
+  *
+  * Unfortunately, it seems gcc-3.3 is a bit dumb, and the compiled code has
+  * a LOT of spill code, it seems gcc (unlike xlc) cannot keep everything in
+  * registers by itself. The following code includes hand-made register
+  * allocation. It's not clean, but on a 7450 the resulting code is much faster
+  * (best case falls from 700+ cycles to 550).
+  *
+  * xlc doesn't add spill code, but it doesn't know how to schedule for the
+  * 7450, and its code isn't much faster than gcc-3.3 on the 7450 (but uses
+  * 25% fewer instructions...)
+  *
+  * On the 970, the hand-made RA is still a win (around 690 vs. around 780),
+  * but xlc goes to around 660 on the regular C code...
+  */
+ static int hadamard8_diff16x8_altivec(MpegEncContext *s, uint8_t *dst,
+                                       uint8_t *src, int stride, int h)
+ {
+     int sum;
+     register vector signed short
+         temp0 __asm__ ("v0"),
+         temp1 __asm__ ("v1"),
+         temp2 __asm__ ("v2"),
+         temp3 __asm__ ("v3"),
+         temp4 __asm__ ("v4"),
+         temp5 __asm__ ("v5"),
+         temp6 __asm__ ("v6"),
+         temp7 __asm__ ("v7");
+     register vector signed short
+         temp0S __asm__ ("v8"),
+         temp1S __asm__ ("v9"),
+         temp2S __asm__ ("v10"),
+         temp3S __asm__ ("v11"),
+         temp4S __asm__ ("v12"),
+         temp5S __asm__ ("v13"),
+         temp6S __asm__ ("v14"),
+         temp7S __asm__ ("v15");
+     register const vector unsigned char vzero __asm__ ("v31") =
+         (const vector unsigned char) vec_splat_u8(0);
+     {
+         register const vector signed short vprod1 __asm__ ("v16") =
+             (const vector signed short) { 1, -1, 1, -1, 1, -1, 1, -1 };
+         register const vector signed short vprod2 __asm__ ("v17") =
+             (const vector signed short) { 1, 1, -1, -1, 1, 1, -1, -1 };
+         register const vector signed short vprod3 __asm__ ("v18") =
+             (const vector signed short) { 1, 1, 1, 1, -1, -1, -1, -1 };
+         register const vector unsigned char perm1 __asm__ ("v19") =
+             (const vector unsigned char)
+             { 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05,
+               0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D };
+         register const vector unsigned char perm2 __asm__ ("v20") =
+             (const vector unsigned char)
+             { 0x04, 0x05, 0x06, 0x07, 0x00, 0x01, 0x02, 0x03,
+               0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B };
+         register const vector unsigned char perm3 __asm__ ("v21") =
+             (const vector unsigned char)
+             { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+               0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
+ #define ONEITERBUTTERFLY(i, res1, res2)                                     \
+     {                                                                       \
+         register vector unsigned char src1 __asm__ ("v22") =                \
+             vec_ld(stride * i, src);                                        \
+         register vector unsigned char src2 __asm__ ("v23") =                \
+             vec_ld(stride * i + 16, src);                                   \
+         register vector unsigned char srcO __asm__ ("v22") =                \
+             vec_perm(src1, src2, vec_lvsl(stride * i, src));                \
+         register vector unsigned char dst1 __asm__ ("v24") =                \
+             vec_ld(stride * i, dst);                                        \
+         register vector unsigned char dst2 __asm__ ("v25") =                \
+             vec_ld(stride * i + 16, dst);                                   \
+         register vector unsigned char dstO __asm__ ("v23") =                \
+             vec_perm(dst1, dst2, vec_lvsl(stride * i, dst));                \
+                                                                             \
+         /* Promote the unsigned chars to signed shorts. */                  \
+         register vector signed short srcV __asm__ ("v24") =                 \
+             (vector signed short) vec_mergeh((vector signed char) vzero,    \
+                                              (vector signed char) srcO);    \
+         register vector signed short dstV __asm__ ("v25") =                 \
+             (vector signed short) vec_mergeh((vector signed char) vzero,    \
+                                              (vector signed char) dstO);    \
+         register vector signed short srcW __asm__ ("v26") =                 \
+             (vector signed short) vec_mergel((vector signed char) vzero,    \
+                                              (vector signed char) srcO);    \
+         register vector signed short dstW __asm__ ("v27") =                 \
+             (vector signed short) vec_mergel((vector signed char) vzero,    \
+                                              (vector signed char) dstO);    \
+                                                                             \
+         /* subtractions inside the first butterfly */                       \
+         register vector signed short but0  __asm__ ("v28") =                \
+             vec_sub(srcV, dstV);                                            \
+         register vector signed short but0S __asm__ ("v29") =                \
+             vec_sub(srcW, dstW);                                            \
+         register vector signed short op1   __asm__ ("v30") =                \
+             vec_perm(but0, but0, perm1);                                    \
+         register vector signed short but1  __asm__ ("v22") =                \
+             vec_mladd(but0, vprod1, op1);                                   \
+         register vector signed short op1S  __asm__ ("v23") =                \
+             vec_perm(but0S, but0S, perm1);                                  \
+         register vector signed short but1S __asm__ ("v24") =                \
+             vec_mladd(but0S, vprod1, op1S);                                 \
+         register vector signed short op2   __asm__ ("v25") =                \
+             vec_perm(but1, but1, perm2);                                    \
+         register vector signed short but2  __asm__ ("v26") =                \
+             vec_mladd(but1, vprod2, op2);                                   \
+         register vector signed short op2S  __asm__ ("v27") =                \
+             vec_perm(but1S, but1S, perm2);                                  \
+         register vector signed short but2S __asm__ ("v28") =                \
+             vec_mladd(but1S, vprod2, op2S);                                 \
+         register vector signed short op3   __asm__ ("v29") =                \
+             vec_perm(but2, but2, perm3);                                    \
+         register vector signed short op3S  __asm__ ("v30") =                \
+             vec_perm(but2S, but2S, perm3);                                  \
+         res1 = vec_mladd(but2, vprod3, op3);                                \
+         res2 = vec_mladd(but2S, vprod3, op3S);                              \
+     }
+         ONEITERBUTTERFLY(0, temp0, temp0S);
+         ONEITERBUTTERFLY(1, temp1, temp1S);
+         ONEITERBUTTERFLY(2, temp2, temp2S);
+         ONEITERBUTTERFLY(3, temp3, temp3S);
+         ONEITERBUTTERFLY(4, temp4, temp4S);
+         ONEITERBUTTERFLY(5, temp5, temp5S);
+         ONEITERBUTTERFLY(6, temp6, temp6S);
+         ONEITERBUTTERFLY(7, temp7, temp7S);
+     }
+ #undef ONEITERBUTTERFLY
+     {
+         register vector signed int vsum;
+         register vector signed short line0  = vec_add(temp0, temp1);
+         register vector signed short line1  = vec_sub(temp0, temp1);
+         register vector signed short line2  = vec_add(temp2, temp3);
+         register vector signed short line3  = vec_sub(temp2, temp3);
+         register vector signed short line4  = vec_add(temp4, temp5);
+         register vector signed short line5  = vec_sub(temp4, temp5);
+         register vector signed short line6  = vec_add(temp6, temp7);
+         register vector signed short line7  = vec_sub(temp6, temp7);
+         register vector signed short line0B = vec_add(line0, line2);
+         register vector signed short line2B = vec_sub(line0, line2);
+         register vector signed short line1B = vec_add(line1, line3);
+         register vector signed short line3B = vec_sub(line1, line3);
+         register vector signed short line4B = vec_add(line4, line6);
+         register vector signed short line6B = vec_sub(line4, line6);
+         register vector signed short line5B = vec_add(line5, line7);
+         register vector signed short line7B = vec_sub(line5, line7);
+         register vector signed short line0C = vec_add(line0B, line4B);
+         register vector signed short line4C = vec_sub(line0B, line4B);
+         register vector signed short line1C = vec_add(line1B, line5B);
+         register vector signed short line5C = vec_sub(line1B, line5B);
+         register vector signed short line2C = vec_add(line2B, line6B);
+         register vector signed short line6C = vec_sub(line2B, line6B);
+         register vector signed short line3C = vec_add(line3B, line7B);
+         register vector signed short line7C = vec_sub(line3B, line7B);
+         register vector signed short line0S = vec_add(temp0S, temp1S);
+         register vector signed short line1S = vec_sub(temp0S, temp1S);
+         register vector signed short line2S = vec_add(temp2S, temp3S);
+         register vector signed short line3S = vec_sub(temp2S, temp3S);
+         register vector signed short line4S = vec_add(temp4S, temp5S);
+         register vector signed short line5S = vec_sub(temp4S, temp5S);
+         register vector signed short line6S = vec_add(temp6S, temp7S);
+         register vector signed short line7S = vec_sub(temp6S, temp7S);
+         register vector signed short line0BS = vec_add(line0S, line2S);
+         register vector signed short line2BS = vec_sub(line0S, line2S);
+         register vector signed short line1BS = vec_add(line1S, line3S);
+         register vector signed short line3BS = vec_sub(line1S, line3S);
+         register vector signed short line4BS = vec_add(line4S, line6S);
+         register vector signed short line6BS = vec_sub(line4S, line6S);
+         register vector signed short line5BS = vec_add(line5S, line7S);
+         register vector signed short line7BS = vec_sub(line5S, line7S);
+         register vector signed short line0CS = vec_add(line0BS, line4BS);
+         register vector signed short line4CS = vec_sub(line0BS, line4BS);
+         register vector signed short line1CS = vec_add(line1BS, line5BS);
+         register vector signed short line5CS = vec_sub(line1BS, line5BS);
+         register vector signed short line2CS = vec_add(line2BS, line6BS);
+         register vector signed short line6CS = vec_sub(line2BS, line6BS);
+         register vector signed short line3CS = vec_add(line3BS, line7BS);
+         register vector signed short line7CS = vec_sub(line3BS, line7BS);
+         vsum = vec_sum4s(vec_abs(line0C), vec_splat_s32(0));
+         vsum = vec_sum4s(vec_abs(line1C), vsum);
+         vsum = vec_sum4s(vec_abs(line2C), vsum);
+         vsum = vec_sum4s(vec_abs(line3C), vsum);
+         vsum = vec_sum4s(vec_abs(line4C), vsum);
+         vsum = vec_sum4s(vec_abs(line5C), vsum);
+         vsum = vec_sum4s(vec_abs(line6C), vsum);
+         vsum = vec_sum4s(vec_abs(line7C), vsum);
+         vsum = vec_sum4s(vec_abs(line0CS), vsum);
+         vsum = vec_sum4s(vec_abs(line1CS), vsum);
+         vsum = vec_sum4s(vec_abs(line2CS), vsum);
+         vsum = vec_sum4s(vec_abs(line3CS), vsum);
+         vsum = vec_sum4s(vec_abs(line4CS), vsum);
+         vsum = vec_sum4s(vec_abs(line5CS), vsum);
+         vsum = vec_sum4s(vec_abs(line6CS), vsum);
+         vsum = vec_sum4s(vec_abs(line7CS), vsum);
+         vsum = vec_sums(vsum, (vector signed int) vzero);
+         vsum = vec_splat(vsum, 3);
+         vec_ste(vsum, 0, &sum);
+     }
+     return sum;
+ }
+ static int hadamard8_diff16_altivec(MpegEncContext *s, uint8_t *dst,
+                                     uint8_t *src, int stride, int h)
+ {
+     int score = hadamard8_diff16x8_altivec(s, dst, src, stride, 8);
+     if (h == 16) {
+         dst   += 8 * stride;
+         src   += 8 * stride;
+         score += hadamard8_diff16x8_altivec(s, dst, src, stride, 8);
+     }
+     return score;
+ }
+ #endif /* HAVE_ALTIVEC */
+ av_cold void ff_me_cmp_init_ppc(MECmpContext *c, AVCodecContext *avctx)
+ {
+ #if HAVE_ALTIVEC
+     if (!PPC_ALTIVEC(av_get_cpu_flags()))
+         return;
+     c->pix_abs[0][1] = sad16_x2_altivec;
+     c->pix_abs[0][2] = sad16_y2_altivec;
+     c->pix_abs[0][3] = sad16_xy2_altivec;
+     c->pix_abs[0][0] = sad16_altivec;
+     c->pix_abs[1][0] = sad8_altivec;
+     c->sad[0] = sad16_altivec;
+     c->sad[1] = sad8_altivec;
+     c->sse[0] = sse16_altivec;
+     c->sse[1] = sse8_altivec;
+     c->hadamard8_diff[0] = hadamard8_diff16_altivec;
+     c->hadamard8_diff[1] = hadamard8_diff8x8_altivec;
+ #endif /* HAVE_ALTIVEC */
+ }
index cb72979,0000000..14ede5d
mode 100644,000000..100644
--- /dev/null
@@@ -1,57 -1,0 +1,55 @@@
- #include "dsputil.h"
 +/*
 + * Copyright (c) 2010-2011 Maxim Poliakovski
 + * Copyright (c) 2010-2011 Elvis Presley
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#ifndef AVCODEC_PRORESDEC_H
 +#define AVCODEC_PRORESDEC_H
 +
-     DSPContext dsp;
 +#include "blockdsp.h"
 +#include "proresdsp.h"
 +
 +typedef struct {
 +    const uint8_t *data;
 +    unsigned mb_x;
 +    unsigned mb_y;
 +    unsigned mb_count;
 +    unsigned data_size;
 +    int ret;
 +} SliceContext;
 +
 +typedef struct {
 +    BlockDSPContext bdsp;
 +    ProresDSPContext prodsp;
 +    AVFrame *frame;
 +    int frame_type;              ///< 0 = progressive, 1 = tff, 2 = bff
 +    uint8_t qmat_luma[64];
 +    uint8_t qmat_chroma[64];
 +    SliceContext *slices;
 +    int slice_count;             ///< number of slices in the current picture
 +    unsigned mb_width;           ///< width of the current picture in mb
 +    unsigned mb_height;          ///< height of the current picture in mb
 +    uint8_t progressive_scan[64];
 +    uint8_t interlaced_scan[64];
 +    const uint8_t *scan;
 +    int first_field;
 +    int alpha_info;
 +} ProresContext;
 +
 +#endif /* AVCODEC_PRORESDEC_H */
index d597114,0000000..4d04a0a
mode 100644,000000..100644
--- /dev/null
@@@ -1,690 -1,0 +1,689 @@@
-     ff_dsputil_init(&ctx->dsp, avctx);
 +/*
 + * Copyright (c) 2010-2011 Maxim Poliakovski
 + * Copyright (c) 2010-2011 Elvis Presley
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +/**
 + * @file
 + * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy), 'ap4h' (4444)
 + */
 +
 +//#define DEBUG
 +
 +#define LONG_BITSTREAM_READER
 +
 +#include "avcodec.h"
 +#include "get_bits.h"
 +#include "idctdsp.h"
 +#include "internal.h"
 +#include "simple_idct.h"
 +#include "proresdec.h"
 +#include "proresdata.h"
 +
 +static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64])
 +{
 +    int i;
 +    for (i = 0; i < 64; i++)
 +        dst[i] = permutation[src[i]];
 +}
 +
 +static av_cold int decode_init(AVCodecContext *avctx)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    uint8_t idct_permutation[64];
 +
 +    avctx->bits_per_raw_sample = 10;
 +
 +    ff_blockdsp_init(&ctx->bdsp, avctx);
 +    ff_proresdsp_init(&ctx->prodsp, avctx);
 +
 +    ff_init_scantable_permutation(idct_permutation,
 +                                  ctx->prodsp.idct_permutation_type);
 +
 +    permute(ctx->progressive_scan, ff_prores_progressive_scan, idct_permutation);
 +    permute(ctx->interlaced_scan, ff_prores_interlaced_scan, idct_permutation);
 +
 +    return 0;
 +}
 +
 +static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
 +                               const int data_size, AVCodecContext *avctx)
 +{
 +    int hdr_size, width, height, flags;
 +    int version;
 +    const uint8_t *ptr;
 +
 +    hdr_size = AV_RB16(buf);
 +    av_dlog(avctx, "header size %d\n", hdr_size);
 +    if (hdr_size > data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    version = AV_RB16(buf + 2);
 +    av_dlog(avctx, "%.4s version %d\n", buf+4, version);
 +    if (version > 1) {
 +        av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version);
 +        return AVERROR_PATCHWELCOME;
 +    }
 +
 +    width  = AV_RB16(buf + 8);
 +    height = AV_RB16(buf + 10);
 +    if (width != avctx->width || height != avctx->height) {
 +        av_log(avctx, AV_LOG_ERROR, "picture resolution change: %dx%d -> %dx%d\n",
 +               avctx->width, avctx->height, width, height);
 +        return AVERROR_PATCHWELCOME;
 +    }
 +
 +    ctx->frame_type = (buf[12] >> 2) & 3;
 +    ctx->alpha_info = buf[17] & 0xf;
 +
 +    if (ctx->alpha_info > 2) {
 +        av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info);
 +        return AVERROR_INVALIDDATA;
 +    }
 +    if (avctx->skip_alpha) ctx->alpha_info = 0;
 +
 +    av_dlog(avctx, "frame type %d\n", ctx->frame_type);
 +
 +    if (ctx->frame_type == 0) {
 +        ctx->scan = ctx->progressive_scan; // permuted
 +    } else {
 +        ctx->scan = ctx->interlaced_scan; // permuted
 +        ctx->frame->interlaced_frame = 1;
 +        ctx->frame->top_field_first = ctx->frame_type == 1;
 +    }
 +
 +    if (ctx->alpha_info) {
 +        avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUVA444P10 : AV_PIX_FMT_YUVA422P10;
 +    } else {
 +        avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10;
 +    }
 +
 +    ptr   = buf + 20;
 +    flags = buf[19];
 +    av_dlog(avctx, "flags %x\n", flags);
 +
 +    if (flags & 2) {
 +        if(buf + data_size - ptr < 64) {
 +            av_log(avctx, AV_LOG_ERROR, "Header truncated\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +        permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr);
 +        ptr += 64;
 +    } else {
 +        memset(ctx->qmat_luma, 4, 64);
 +    }
 +
 +    if (flags & 1) {
 +        if(buf + data_size - ptr < 64) {
 +            av_log(avctx, AV_LOG_ERROR, "Header truncated\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +        permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr);
 +    } else {
 +        memset(ctx->qmat_chroma, 4, 64);
 +    }
 +
 +    return hdr_size;
 +}
 +
 +static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, const int buf_size)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    int i, hdr_size, slice_count;
 +    unsigned pic_data_size;
 +    int log2_slice_mb_width, log2_slice_mb_height;
 +    int slice_mb_count, mb_x, mb_y;
 +    const uint8_t *data_ptr, *index_ptr;
 +
 +    hdr_size = buf[0] >> 3;
 +    if (hdr_size < 8 || hdr_size > buf_size) {
 +        av_log(avctx, AV_LOG_ERROR, "error, wrong picture header size\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    pic_data_size = AV_RB32(buf + 1);
 +    if (pic_data_size > buf_size) {
 +        av_log(avctx, AV_LOG_ERROR, "error, wrong picture data size\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    log2_slice_mb_width  = buf[7] >> 4;
 +    log2_slice_mb_height = buf[7] & 0xF;
 +    if (log2_slice_mb_width > 3 || log2_slice_mb_height) {
 +        av_log(avctx, AV_LOG_ERROR, "unsupported slice resolution: %dx%d\n",
 +               1 << log2_slice_mb_width, 1 << log2_slice_mb_height);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    ctx->mb_width  = (avctx->width  + 15) >> 4;
 +    if (ctx->frame_type)
 +        ctx->mb_height = (avctx->height + 31) >> 5;
 +    else
 +        ctx->mb_height = (avctx->height + 15) >> 4;
 +
 +    slice_count = AV_RB16(buf + 5);
 +
 +    if (ctx->slice_count != slice_count || !ctx->slices) {
 +        av_freep(&ctx->slices);
 +        ctx->slices = av_mallocz_array(slice_count, sizeof(*ctx->slices));
 +        if (!ctx->slices)
 +            return AVERROR(ENOMEM);
 +        ctx->slice_count = slice_count;
 +    }
 +
 +    if (!slice_count)
 +        return AVERROR(EINVAL);
 +
 +    if (hdr_size + slice_count*2 > buf_size) {
 +        av_log(avctx, AV_LOG_ERROR, "error, wrong slice count\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    // parse slice information
 +    index_ptr = buf + hdr_size;
 +    data_ptr  = index_ptr + slice_count*2;
 +
 +    slice_mb_count = 1 << log2_slice_mb_width;
 +    mb_x = 0;
 +    mb_y = 0;
 +
 +    for (i = 0; i < slice_count; i++) {
 +        SliceContext *slice = &ctx->slices[i];
 +
 +        slice->data = data_ptr;
 +        data_ptr += AV_RB16(index_ptr + i*2);
 +
 +        while (ctx->mb_width - mb_x < slice_mb_count)
 +            slice_mb_count >>= 1;
 +
 +        slice->mb_x = mb_x;
 +        slice->mb_y = mb_y;
 +        slice->mb_count = slice_mb_count;
 +        slice->data_size = data_ptr - slice->data;
 +
 +        if (slice->data_size < 6) {
 +            av_log(avctx, AV_LOG_ERROR, "error, wrong slice data size\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +
 +        mb_x += slice_mb_count;
 +        if (mb_x == ctx->mb_width) {
 +            slice_mb_count = 1 << log2_slice_mb_width;
 +            mb_x = 0;
 +            mb_y++;
 +        }
 +        if (data_ptr > buf + buf_size) {
 +            av_log(avctx, AV_LOG_ERROR, "error, slice out of bounds\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +    }
 +
 +    if (mb_x || mb_y != ctx->mb_height) {
 +        av_log(avctx, AV_LOG_ERROR, "error wrong mb count y %d h %d\n",
 +               mb_y, ctx->mb_height);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    return pic_data_size;
 +}
 +
 +#define DECODE_CODEWORD(val, codebook)                                  \
 +    do {                                                                \
 +        unsigned int rice_order, exp_order, switch_bits;                \
 +        unsigned int q, buf, bits;                                      \
 +                                                                        \
 +        UPDATE_CACHE(re, gb);                                           \
 +        buf = GET_CACHE(re, gb);                                        \
 +                                                                        \
 +        /* number of bits to switch between rice and exp golomb */      \
 +        switch_bits =  codebook & 3;                                    \
 +        rice_order  =  codebook >> 5;                                   \
 +        exp_order   = (codebook >> 2) & 7;                              \
 +                                                                        \
 +        q = 31 - av_log2(buf);                                          \
 +                                                                        \
 +        if (q > switch_bits) { /* exp golomb */                         \
 +            bits = exp_order - switch_bits + (q<<1);                    \
 +            val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) +         \
 +                ((switch_bits + 1) << rice_order);                      \
 +            SKIP_BITS(re, gb, bits);                                    \
 +        } else if (rice_order) {                                        \
 +            SKIP_BITS(re, gb, q+1);                                     \
 +            val = (q << rice_order) + SHOW_UBITS(re, gb, rice_order);   \
 +            SKIP_BITS(re, gb, rice_order);                              \
 +        } else {                                                        \
 +            val = q;                                                    \
 +            SKIP_BITS(re, gb, q+1);                                     \
 +        }                                                               \
 +    } while (0)
 +
 +#define TOSIGNED(x) (((x) >> 1) ^ (-((x) & 1)))
 +
 +#define FIRST_DC_CB 0xB8
 +
 +static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
 +
 +static av_always_inline void decode_dc_coeffs(GetBitContext *gb, int16_t *out,
 +                                              int blocks_per_slice)
 +{
 +    int16_t prev_dc;
 +    int code, i, sign;
 +
 +    OPEN_READER(re, gb);
 +
 +    DECODE_CODEWORD(code, FIRST_DC_CB);
 +    prev_dc = TOSIGNED(code);
 +    out[0] = prev_dc;
 +
 +    out += 64; // dc coeff for the next block
 +
 +    code = 5;
 +    sign = 0;
 +    for (i = 1; i < blocks_per_slice; i++, out += 64) {
 +        DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)]);
 +        if(code) sign ^= -(code & 1);
 +        else     sign  = 0;
 +        prev_dc += (((code + 1) >> 1) ^ sign) - sign;
 +        out[0] = prev_dc;
 +    }
 +    CLOSE_READER(re, gb);
 +}
 +
 +// adaptive codebook switching lut according to previous run/level values
 +static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
 +static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C };
 +
 +static av_always_inline int decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb,
 +                                             int16_t *out, int blocks_per_slice)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    int block_mask, sign;
 +    unsigned pos, run, level;
 +    int max_coeffs, i, bits_left;
 +    int log2_block_count = av_log2(blocks_per_slice);
 +
 +    OPEN_READER(re, gb);
 +    UPDATE_CACHE(re, gb);                                           \
 +    run   = 4;
 +    level = 2;
 +
 +    max_coeffs = 64 << log2_block_count;
 +    block_mask = blocks_per_slice - 1;
 +
 +    for (pos = block_mask;;) {
 +        bits_left = gb->size_in_bits - re_index;
 +        if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left)))
 +            break;
 +
 +        DECODE_CODEWORD(run, run_to_cb[FFMIN(run,  15)]);
 +        pos += run + 1;
 +        if (pos >= max_coeffs) {
 +            av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs);
 +            return AVERROR_INVALIDDATA;
 +        }
 +
 +        DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)]);
 +        level += 1;
 +
 +        i = pos >> log2_block_count;
 +
 +        sign = SHOW_SBITS(re, gb, 1);
 +        SKIP_BITS(re, gb, 1);
 +        out[((pos & block_mask) << 6) + ctx->scan[i]] = ((level ^ sign) - sign);
 +    }
 +
 +    CLOSE_READER(re, gb);
 +    return 0;
 +}
 +
 +static int decode_slice_luma(AVCodecContext *avctx, SliceContext *slice,
 +                             uint16_t *dst, int dst_stride,
 +                             const uint8_t *buf, unsigned buf_size,
 +                             const int16_t *qmat)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]);
 +    int16_t *block;
 +    GetBitContext gb;
 +    int i, blocks_per_slice = slice->mb_count<<2;
 +    int ret;
 +
 +    for (i = 0; i < blocks_per_slice; i++)
 +        ctx->bdsp.clear_block(blocks+(i<<6));
 +
 +    init_get_bits(&gb, buf, buf_size << 3);
 +
 +    decode_dc_coeffs(&gb, blocks, blocks_per_slice);
 +    if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0)
 +        return ret;
 +
 +    block = blocks;
 +    for (i = 0; i < slice->mb_count; i++) {
 +        ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat);
 +        ctx->prodsp.idct_put(dst             +8, dst_stride, block+(1<<6), qmat);
 +        ctx->prodsp.idct_put(dst+4*dst_stride  , dst_stride, block+(2<<6), qmat);
 +        ctx->prodsp.idct_put(dst+4*dst_stride+8, dst_stride, block+(3<<6), qmat);
 +        block += 4*64;
 +        dst += 16;
 +    }
 +    return 0;
 +}
 +
 +static int decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice,
 +                               uint16_t *dst, int dst_stride,
 +                               const uint8_t *buf, unsigned buf_size,
 +                               const int16_t *qmat, int log2_blocks_per_mb)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]);
 +    int16_t *block;
 +    GetBitContext gb;
 +    int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb;
 +    int ret;
 +
 +    for (i = 0; i < blocks_per_slice; i++)
 +        ctx->bdsp.clear_block(blocks+(i<<6));
 +
 +    init_get_bits(&gb, buf, buf_size << 3);
 +
 +    decode_dc_coeffs(&gb, blocks, blocks_per_slice);
 +    if ((ret = decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice)) < 0)
 +        return ret;
 +
 +    block = blocks;
 +    for (i = 0; i < slice->mb_count; i++) {
 +        for (j = 0; j < log2_blocks_per_mb; j++) {
 +            ctx->prodsp.idct_put(dst,              dst_stride, block+(0<<6), qmat);
 +            ctx->prodsp.idct_put(dst+4*dst_stride, dst_stride, block+(1<<6), qmat);
 +            block += 2*64;
 +            dst += 8;
 +        }
 +    }
 +    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)
 +                break;
 +        } while (get_bits_left(gb)>0 && get_bits1(gb));
 +        val = get_bits(gb, 4);
 +        if (!val)
 +            val = get_bits(gb, 11);
 +        if (idx + val > num_coeffs)
 +            val = num_coeffs - idx;
 +        if (num_bits == 16) {
 +            for (i = 0; i < val; i++)
 +                dst[idx++] = alpha_val >> 6;
 +        } else {
 +            for (i = 0; i < val; i++)
 +                dst[idx++] = (alpha_val << 2) | (alpha_val >> 6);
 +
 +        }
 +    } while (idx < num_coeffs);
 +}
 +
 +/**
 + * Decode alpha slice plane.
 + */
 +static void decode_slice_alpha(ProresContext *ctx,
 +                               uint16_t *dst, int dst_stride,
 +                               const uint8_t *buf, int buf_size,
 +                               int blocks_per_slice)
 +{
 +    GetBitContext gb;
 +    int i;
 +    LOCAL_ALIGNED_16(int16_t, blocks, [8*4*64]);
 +    int16_t *block;
 +
 +    for (i = 0; i < blocks_per_slice<<2; i++)
 +        ctx->bdsp.clear_block(blocks+(i<<6));
 +
 +    init_get_bits(&gb, buf, buf_size << 3);
 +
 +    if (ctx->alpha_info == 2) {
 +        unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 16);
 +    } else {
 +        unpack_alpha(&gb, blocks, blocks_per_slice * 4 * 64, 8);
 +    }
 +
 +    block = blocks;
 +    for (i = 0; i < 16; i++) {
 +        memcpy(dst, block, 16 * blocks_per_slice * sizeof(*dst));
 +        dst   += dst_stride >> 1;
 +        block += 16 * blocks_per_slice;
 +    }
 +}
 +
 +static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    SliceContext *slice = &ctx->slices[jobnr];
 +    const uint8_t *buf = slice->data;
 +    AVFrame *pic = ctx->frame;
 +    int i, hdr_size, qscale, log2_chroma_blocks_per_mb;
 +    int luma_stride, chroma_stride;
 +    int y_data_size, u_data_size, v_data_size, a_data_size;
 +    uint8_t *dest_y, *dest_u, *dest_v, *dest_a;
 +    int16_t qmat_luma_scaled[64];
 +    int16_t qmat_chroma_scaled[64];
 +    int mb_x_shift;
 +    int ret;
 +
 +    slice->ret = -1;
 +    //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n",
 +    //       jobnr, slice->mb_count, slice->mb_x, slice->mb_y);
 +
 +    // slice header
 +    hdr_size = buf[0] >> 3;
 +    qscale = av_clip(buf[1], 1, 224);
 +    qscale = qscale > 128 ? qscale - 96 << 2: qscale;
 +    y_data_size = AV_RB16(buf + 2);
 +    u_data_size = AV_RB16(buf + 4);
 +    v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size;
 +    if (hdr_size > 7) v_data_size = AV_RB16(buf + 6);
 +    a_data_size = slice->data_size - y_data_size - u_data_size -
 +                  v_data_size - hdr_size;
 +
 +    if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0
 +        || hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){
 +        av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    buf += hdr_size;
 +
 +    for (i = 0; i < 64; i++) {
 +        qmat_luma_scaled  [i] = ctx->qmat_luma  [i] * qscale;
 +        qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * qscale;
 +    }
 +
 +    if (ctx->frame_type == 0) {
 +        luma_stride   = pic->linesize[0];
 +        chroma_stride = pic->linesize[1];
 +    } else {
 +        luma_stride   = pic->linesize[0] << 1;
 +        chroma_stride = pic->linesize[1] << 1;
 +    }
 +
 +    if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
 +        mb_x_shift = 5;
 +        log2_chroma_blocks_per_mb = 2;
 +    } else {
 +        mb_x_shift = 4;
 +        log2_chroma_blocks_per_mb = 1;
 +    }
 +
 +    dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
 +    dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
 +    dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
 +    dest_a = pic->data[3] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
 +
 +    if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) {
 +        dest_y += pic->linesize[0];
 +        dest_u += pic->linesize[1];
 +        dest_v += pic->linesize[2];
 +        dest_a += pic->linesize[3];
 +    }
 +
 +    ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride,
 +                            buf, y_data_size, qmat_luma_scaled);
 +    if (ret < 0)
 +        return ret;
 +
 +    if (!(avctx->flags & CODEC_FLAG_GRAY)) {
 +        ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_u, chroma_stride,
 +                                  buf + y_data_size, u_data_size,
 +                                  qmat_chroma_scaled, log2_chroma_blocks_per_mb);
 +        if (ret < 0)
 +            return ret;
 +
 +        ret = decode_slice_chroma(avctx, slice, (uint16_t*)dest_v, chroma_stride,
 +                                  buf + y_data_size + u_data_size, v_data_size,
 +                                  qmat_chroma_scaled, log2_chroma_blocks_per_mb);
 +        if (ret < 0)
 +            return ret;
 +    }
 +    /* decode alpha plane if available */
 +    if (ctx->alpha_info && pic->data[3] && a_data_size)
 +        decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride,
 +                           buf + y_data_size + u_data_size + v_data_size,
 +                           a_data_size, slice->mb_count);
 +
 +    slice->ret = 0;
 +    return 0;
 +}
 +
 +static int decode_picture(AVCodecContext *avctx)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    int i;
 +
 +    avctx->execute2(avctx, decode_slice_thread, NULL, NULL, ctx->slice_count);
 +
 +    for (i = 0; i < ctx->slice_count; i++)
 +        if (ctx->slices[i].ret < 0)
 +            return ctx->slices[i].ret;
 +
 +    return 0;
 +}
 +
 +static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 +                        AVPacket *avpkt)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    AVFrame *frame = data;
 +    const uint8_t *buf = avpkt->data;
 +    int buf_size = avpkt->size;
 +    int frame_hdr_size, pic_size, ret;
 +
 +    if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) {
 +        av_log(avctx, AV_LOG_ERROR, "invalid frame header\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    ctx->frame = frame;
 +    ctx->frame->pict_type = AV_PICTURE_TYPE_I;
 +    ctx->frame->key_frame = 1;
 +    ctx->first_field = 1;
 +
 +    buf += 8;
 +    buf_size -= 8;
 +
 +    frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
 +    if (frame_hdr_size < 0)
 +        return frame_hdr_size;
 +
 +    buf += frame_hdr_size;
 +    buf_size -= frame_hdr_size;
 +
 +    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
 +        return ret;
 +
 + decode_picture:
 +    pic_size = decode_picture_header(avctx, buf, buf_size);
 +    if (pic_size < 0) {
 +        av_log(avctx, AV_LOG_ERROR, "error decoding picture header\n");
 +        return pic_size;
 +    }
 +
 +    if ((ret = decode_picture(avctx)) < 0) {
 +        av_log(avctx, AV_LOG_ERROR, "error decoding picture\n");
 +        return ret;
 +    }
 +
 +    buf += pic_size;
 +    buf_size -= pic_size;
 +
 +    if (ctx->frame_type && buf_size > 0 && ctx->first_field) {
 +        ctx->first_field = 0;
 +        goto decode_picture;
 +    }
 +
 +    *got_frame      = 1;
 +
 +    return avpkt->size;
 +}
 +
 +static av_cold int decode_close(AVCodecContext *avctx)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +
 +    av_freep(&ctx->slices);
 +
 +    return 0;
 +}
 +
 +AVCodec ff_prores_decoder = {
 +    .name           = "prores",
 +    .long_name      = NULL_IF_CONFIG_SMALL("ProRes"),
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_PRORES,
 +    .priv_data_size = sizeof(ProresContext),
 +    .init           = decode_init,
 +    .close          = decode_close,
 +    .decode         = decode_frame,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
 +};
Simple merge
index b2445ca,0000000..f471f49
mode 100644,000000..100644
--- /dev/null
@@@ -1,637 -1,0 +1,636 @@@
- #include "dsputil.h"
 +/*
 + * Apple ProRes encoder
 + *
 + * Copyright (c) 2011 Anatoliy Wasserman
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +/**
 + * @file
 + * Apple ProRes encoder (Anatoliy Wasserman version)
 + * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy)
 + */
 +
 +#include "avcodec.h"
 +#include "dct.h"
 +#include "internal.h"
 +#include "put_bits.h"
 +#include "bytestream.h"
 +#include "fdctdsp.h"
 +
 +#define DEFAULT_SLICE_MB_WIDTH 8
 +
 +#define FF_PROFILE_PRORES_PROXY     0
 +#define FF_PROFILE_PRORES_LT        1
 +#define FF_PROFILE_PRORES_STANDARD  2
 +#define FF_PROFILE_PRORES_HQ        3
 +
 +static const AVProfile profiles[] = {
 +    { FF_PROFILE_PRORES_PROXY,    "apco"},
 +    { FF_PROFILE_PRORES_LT,       "apcs"},
 +    { FF_PROFILE_PRORES_STANDARD, "apcn"},
 +    { FF_PROFILE_PRORES_HQ,       "apch"},
 +    { FF_PROFILE_UNKNOWN }
 +};
 +
 +static const int qp_start_table[4] = { 4, 1, 1, 1 };
 +static const int qp_end_table[4]   = { 8, 9, 6, 6 };
 +static const int bitrate_table[5]  = { 1000, 2100, 3500, 5400 };
 +
 +static const uint8_t progressive_scan[64] = {
 +     0,  1,  8,  9,  2,  3, 10, 11,
 +    16, 17, 24, 25, 18, 19, 26, 27,
 +     4,  5, 12, 20, 13,  6,  7, 14,
 +    21, 28, 29, 22, 15, 23, 30, 31,
 +    32, 33, 40, 48, 41, 34, 35, 42,
 +    49, 56, 57, 50, 43, 36, 37, 44,
 +    51, 58, 59, 52, 45, 38, 39, 46,
 +    53, 60, 61, 54, 47, 55, 62, 63
 +};
 +
 +static const uint8_t QMAT_LUMA[4][64] = {
 +    {
 +         4,  7,  9, 11, 13, 14, 15, 63,
 +         7,  7, 11, 12, 14, 15, 63, 63,
 +         9, 11, 13, 14, 15, 63, 63, 63,
 +        11, 11, 13, 14, 63, 63, 63, 63,
 +        11, 13, 14, 63, 63, 63, 63, 63,
 +        13, 14, 63, 63, 63, 63, 63, 63,
 +        13, 63, 63, 63, 63, 63, 63, 63,
 +        63, 63, 63, 63, 63, 63, 63, 63
 +    }, {
 +         4,  5,  6,  7,  9, 11, 13, 15,
 +         5,  5,  7,  8, 11, 13, 15, 17,
 +         6,  7,  9, 11, 13, 15, 15, 17,
 +         7,  7,  9, 11, 13, 15, 17, 19,
 +         7,  9, 11, 13, 14, 16, 19, 23,
 +         9, 11, 13, 14, 16, 19, 23, 29,
 +         9, 11, 13, 15, 17, 21, 28, 35,
 +        11, 13, 16, 17, 21, 28, 35, 41
 +    }, {
 +         4,  4,  5,  5,  6,  7,  7,  9,
 +         4,  4,  5,  6,  7,  7,  9,  9,
 +         5,  5,  6,  7,  7,  9,  9, 10,
 +         5,  5,  6,  7,  7,  9,  9, 10,
 +         5,  6,  7,  7,  8,  9, 10, 12,
 +         6,  7,  7,  8,  9, 10, 12, 15,
 +         6,  7,  7,  9, 10, 11, 14, 17,
 +         7,  7,  9, 10, 11, 14, 17, 21
 +    }, {
 +         4,  4,  4,  4,  4,  4,  4,  4,
 +         4,  4,  4,  4,  4,  4,  4,  4,
 +         4,  4,  4,  4,  4,  4,  4,  4,
 +         4,  4,  4,  4,  4,  4,  4,  5,
 +         4,  4,  4,  4,  4,  4,  5,  5,
 +         4,  4,  4,  4,  4,  5,  5,  6,
 +         4,  4,  4,  4,  5,  5,  6,  7,
 +         4,  4,  4,  4,  5,  6,  7,  7
 +    }
 +};
 +
 +static const uint8_t QMAT_CHROMA[4][64] = {
 +    {
 +         4,  7,  9, 11, 13, 14, 63, 63,
 +         7,  7, 11, 12, 14, 63, 63, 63,
 +         9, 11, 13, 14, 63, 63, 63, 63,
 +        11, 11, 13, 14, 63, 63, 63, 63,
 +        11, 13, 14, 63, 63, 63, 63, 63,
 +        13, 14, 63, 63, 63, 63, 63, 63,
 +        13, 63, 63, 63, 63, 63, 63, 63,
 +        63, 63, 63, 63, 63, 63, 63, 63
 +    }, {
 +         4,  5,  6,  7,  9, 11, 13, 15,
 +         5,  5,  7,  8, 11, 13, 15, 17,
 +         6,  7,  9, 11, 13, 15, 15, 17,
 +         7,  7,  9, 11, 13, 15, 17, 19,
 +         7,  9, 11, 13, 14, 16, 19, 23,
 +         9, 11, 13, 14, 16, 19, 23, 29,
 +         9, 11, 13, 15, 17, 21, 28, 35,
 +        11, 13, 16, 17, 21, 28, 35, 41
 +    }, {
 +         4,  4,  5,  5,  6,  7,  7,  9,
 +         4,  4,  5,  6,  7,  7,  9,  9,
 +         5,  5,  6,  7,  7,  9,  9, 10,
 +         5,  5,  6,  7,  7,  9,  9, 10,
 +         5,  6,  7,  7,  8,  9, 10, 12,
 +         6,  7,  7,  8,  9, 10, 12, 15,
 +         6,  7,  7,  9, 10, 11, 14, 17,
 +         7,  7,  9, 10, 11, 14, 17, 21
 +    }, {
 +         4,  4,  4,  4,  4,  4,  4,  4,
 +         4,  4,  4,  4,  4,  4,  4,  4,
 +         4,  4,  4,  4,  4,  4,  4,  4,
 +         4,  4,  4,  4,  4,  4,  4,  5,
 +         4,  4,  4,  4,  4,  4,  5,  5,
 +         4,  4,  4,  4,  4,  5,  5,  6,
 +         4,  4,  4,  4,  5,  5,  6,  7,
 +         4,  4,  4,  4,  5,  6,  7,  7
 +    }
 +};
 +
 +
 +typedef struct {
 +    FDCTDSPContext fdsp;
 +    uint8_t* fill_y;
 +    uint8_t* fill_u;
 +    uint8_t* fill_v;
 +
 +    int qmat_luma[16][64];
 +    int qmat_chroma[16][64];
 +} ProresContext;
 +
 +static void encode_codeword(PutBitContext *pb, int val, int codebook)
 +{
 +    unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros,
 +            mask;
 +
 +    /* number of bits to switch between rice and exp golomb */
 +    switch_bits = codebook & 3;
 +    rice_order  = codebook >> 5;
 +    exp_order   = (codebook >> 2) & 7;
 +
 +    first_exp = ((switch_bits + 1) << rice_order);
 +
 +    if (val >= first_exp) { /* exp golomb */
 +        val -= first_exp;
 +        val += (1 << exp_order);
 +        exp = av_log2(val);
 +        zeros = exp - exp_order + switch_bits + 1;
 +        put_bits(pb, zeros, 0);
 +        put_bits(pb, exp + 1, val);
 +    } else if (rice_order) {
 +        mask = (1 << rice_order) - 1;
 +        put_bits(pb, (val >> rice_order), 0);
 +        put_bits(pb, 1, 1);
 +        put_bits(pb, rice_order, val & mask);
 +    } else {
 +        put_bits(pb, val, 0);
 +        put_bits(pb, 1, 1);
 +    }
 +}
 +
 +#define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
 +#define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
 +#define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
 +#define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
 +#define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
 +
 +static av_always_inline int get_level(int val)
 +{
 +    int sign = (val >> 31);
 +    return (val ^ sign) - sign;
 +}
 +
 +#define FIRST_DC_CB 0xB8
 +
 +static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
 +
 +static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
 +        int blocks_per_slice, int *qmat)
 +{
 +    int prev_dc, code;
 +    int i, sign, idx;
 +    int new_dc, delta, diff_sign, new_code;
 +
 +    prev_dc = QSCALE(qmat, 0, in[0] - 16384);
 +    code = TO_GOLOMB(prev_dc);
 +    encode_codeword(pb, code, FIRST_DC_CB);
 +
 +    code = 5; sign = 0; idx = 64;
 +    for (i = 1; i < blocks_per_slice; i++, idx += 64) {
 +        new_dc    = QSCALE(qmat, 0, in[idx] - 16384);
 +        delta     = new_dc - prev_dc;
 +        diff_sign = DIFF_SIGN(delta, sign);
 +        new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
 +
 +        encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
 +
 +        code      = new_code;
 +        sign      = delta >> 31;
 +        prev_dc   = new_dc;
 +    }
 +}
 +
 +static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
 +        0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
 +static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
 +        0x28, 0x28, 0x28, 0x4C };
 +
 +static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb,
 +        int16_t *in, int blocks_per_slice, int *qmat)
 +{
 +    int prev_run = 4;
 +    int prev_level = 2;
 +
 +    int run = 0, level, code, i, j;
 +    for (i = 1; i < 64; i++) {
 +        int indp = progressive_scan[i];
 +        for (j = 0; j < blocks_per_slice; j++) {
 +            int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
 +            if (val) {
 +                encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
 +
 +                prev_run   = run;
 +                run        = 0;
 +                level      = get_level(val);
 +                code       = level - 1;
 +
 +                encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
 +
 +                prev_level = level;
 +
 +                put_bits(pb, 1, IS_NEGATIVE(val));
 +            } else {
 +                ++run;
 +            }
 +        }
 +    }
 +}
 +
 +static void get(uint8_t *pixels, int stride, int16_t* block)
 +{
 +    int i;
 +
 +    for (i = 0; i < 8; i++) {
 +        AV_WN64(block, AV_RN64(pixels));
 +        AV_WN64(block+4, AV_RN64(pixels+8));
 +        pixels += stride;
 +        block += 8;
 +    }
 +}
 +
 +static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
 +{
 +    get(pixels, stride, block);
 +    fdsp->fdct(block);
 +}
 +
 +static int encode_slice_plane(AVCodecContext *avctx, int mb_count,
 +        uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size,
 +        int *qmat, int chroma)
 +{
 +    ProresContext* ctx = avctx->priv_data;
 +    FDCTDSPContext *fdsp = &ctx->fdsp;
 +    DECLARE_ALIGNED(16, int16_t, blocks)[DEFAULT_SLICE_MB_WIDTH << 8], *block;
 +    int i, blocks_per_slice;
 +    PutBitContext pb;
 +
 +    block = blocks;
 +    for (i = 0; i < mb_count; i++) {
 +        fdct_get(fdsp, src,                  src_stride, block + (0 << 6));
 +        fdct_get(fdsp, src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
 +        if (!chroma) {
 +            fdct_get(fdsp, src + 16,                  src_stride, block + (1 << 6));
 +            fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
 +        }
 +
 +        block += (256 >> chroma);
 +        src   += (32  >> chroma);
 +    }
 +
 +    blocks_per_slice = mb_count << (2 - chroma);
 +    init_put_bits(&pb, buf, buf_size << 3);
 +
 +    encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
 +    encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat);
 +
 +    flush_put_bits(&pb);
 +    return put_bits_ptr(&pb) - pb.buf;
 +}
 +
 +static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
 +        uint8_t *dest_y, uint8_t *dest_u, uint8_t *dest_v, int luma_stride,
 +        int chroma_stride, unsigned mb_count, uint8_t *buf, unsigned data_size,
 +        unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
 +        int qp)
 +{
 +    ProresContext* ctx = avctx->priv_data;
 +
 +    *y_data_size = encode_slice_plane(avctx, mb_count, dest_y, luma_stride,
 +            buf, data_size, ctx->qmat_luma[qp - 1], 0);
 +
 +    if (!(avctx->flags & CODEC_FLAG_GRAY)) {
 +        *u_data_size = encode_slice_plane(avctx, mb_count, dest_u,
 +                chroma_stride, buf + *y_data_size, data_size - *y_data_size,
 +                ctx->qmat_chroma[qp - 1], 1);
 +
 +        *v_data_size = encode_slice_plane(avctx, mb_count, dest_v,
 +                chroma_stride, buf + *y_data_size + *u_data_size,
 +                data_size - *y_data_size - *u_data_size,
 +                ctx->qmat_chroma[qp - 1], 1);
 +    }
 +
 +    return *y_data_size + *u_data_size + *v_data_size;
 +}
 +
 +static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
 +        unsigned stride, unsigned width, unsigned height, uint16_t *dst,
 +        unsigned dst_width, unsigned dst_height)
 +{
 +
 +    int box_width = FFMIN(width - x, dst_width);
 +    int box_height = FFMIN(height - y, dst_height);
 +    int i, j, src_stride = stride >> 1;
 +    uint16_t last_pix, *last_line;
 +
 +    src += y * src_stride + x;
 +    for (i = 0; i < box_height; ++i) {
 +        for (j = 0; j < box_width; ++j) {
 +            dst[j] = src[j];
 +        }
 +        last_pix = dst[j - 1];
 +        for (; j < dst_width; j++)
 +            dst[j] = last_pix;
 +        src += src_stride;
 +        dst += dst_width;
 +    }
 +    last_line = dst - dst_width;
 +    for (; i < dst_height; i++) {
 +        for (j = 0; j < dst_width; ++j) {
 +            dst[j] = last_line[j];
 +        }
 +        dst += dst_width;
 +    }
 +}
 +
 +static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
 +        int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
 +        int unsafe, int *qp)
 +{
 +    int luma_stride, chroma_stride;
 +    int hdr_size = 6, slice_size;
 +    uint8_t *dest_y, *dest_u, *dest_v;
 +    unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
 +    ProresContext* ctx = avctx->priv_data;
 +    int tgt_bits   = (mb_count * bitrate_table[avctx->profile]) >> 2;
 +    int low_bytes  = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
 +    int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
 +
 +    luma_stride   = pic->linesize[0];
 +    chroma_stride = pic->linesize[1];
 +
 +    dest_y = pic->data[0] + (mb_y << 4) * luma_stride   + (mb_x << 5);
 +    dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4);
 +    dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4);
 +
 +    if (unsafe) {
 +
 +        subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
 +                luma_stride, avctx->width, avctx->height,
 +                (uint16_t *) ctx->fill_y, mb_count << 4, 16);
 +        subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4,
 +                chroma_stride, avctx->width >> 1, avctx->height,
 +                (uint16_t *) ctx->fill_u, mb_count << 3, 16);
 +        subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4,
 +                chroma_stride, avctx->width >> 1, avctx->height,
 +                (uint16_t *) ctx->fill_v, mb_count << 3, 16);
 +
 +        encode_slice_data(avctx, ctx->fill_y, ctx->fill_u, ctx->fill_v,
 +                mb_count << 5, mb_count << 4, mb_count, buf + hdr_size,
 +                data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
 +                *qp);
 +    } else {
 +        slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
 +                luma_stride, chroma_stride, mb_count, buf + hdr_size,
 +                data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
 +                *qp);
 +
 +        if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
 +            do {
 +                *qp += 1;
 +                slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
 +                        luma_stride, chroma_stride, mb_count, buf + hdr_size,
 +                        data_size - hdr_size, &y_data_size, &u_data_size,
 +                        &v_data_size, *qp);
 +            } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
 +        } else if (slice_size < low_bytes && *qp
 +                > qp_start_table[avctx->profile]) {
 +            do {
 +                *qp -= 1;
 +                slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
 +                        luma_stride, chroma_stride, mb_count, buf + hdr_size,
 +                        data_size - hdr_size, &y_data_size, &u_data_size,
 +                        &v_data_size, *qp);
 +            } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
 +        }
 +    }
 +
 +    buf[0] = hdr_size << 3;
 +    buf[1] = *qp;
 +    AV_WB16(buf + 2, y_data_size);
 +    AV_WB16(buf + 4, u_data_size);
 +
 +    return hdr_size + y_data_size + u_data_size + v_data_size;
 +}
 +
 +static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
 +        uint8_t *buf, const int buf_size)
 +{
 +    int mb_width = (avctx->width + 15) >> 4;
 +    int mb_height = (avctx->height + 15) >> 4;
 +    int hdr_size, sl_size, i;
 +    int mb_y, sl_data_size, qp;
 +    int unsafe_bot, unsafe_right;
 +    uint8_t *sl_data, *sl_data_sizes;
 +    int slice_per_line = 0, rem = mb_width;
 +
 +    for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
 +        slice_per_line += rem >> i;
 +        rem &= (1 << i) - 1;
 +    }
 +
 +    qp = qp_start_table[avctx->profile];
 +    hdr_size = 8; sl_data_size = buf_size - hdr_size;
 +    sl_data_sizes = buf + hdr_size;
 +    sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
 +    for (mb_y = 0; mb_y < mb_height; mb_y++) {
 +        int mb_x = 0;
 +        int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
 +        while (mb_x < mb_width) {
 +            while (mb_width - mb_x < slice_mb_count)
 +                slice_mb_count >>= 1;
 +
 +            unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
 +            unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
 +
 +            sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
 +                    sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
 +
 +            bytestream_put_be16(&sl_data_sizes, sl_size);
 +            sl_data           += sl_size;
 +            sl_data_size      -= sl_size;
 +            mb_x              += slice_mb_count;
 +        }
 +    }
 +
 +    buf[0] = hdr_size << 3;
 +    AV_WB32(buf + 1, sl_data - buf);
 +    AV_WB16(buf + 5, slice_per_line * mb_height);
 +    buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
 +
 +    return sl_data - buf;
 +}
 +
 +static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
 +                               const AVFrame *pict, int *got_packet)
 +{
 +    int header_size = 148;
 +    uint8_t *buf;
 +    int pic_size, ret;
 +    int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + FF_MIN_BUFFER_SIZE; //FIXME choose tighter limit
 +
 +
 +    if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + FF_MIN_BUFFER_SIZE)) < 0)
 +        return ret;
 +
 +    buf = pkt->data;
 +    pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
 +            pkt->size - header_size - 8);
 +
 +    bytestream_put_be32(&buf, pic_size + 8 + header_size);
 +    bytestream_put_buffer(&buf, "icpf", 4);
 +
 +    bytestream_put_be16(&buf, header_size);
 +    bytestream_put_be16(&buf, 0);
 +    bytestream_put_buffer(&buf, "fmpg", 4);
 +    bytestream_put_be16(&buf, avctx->width);
 +    bytestream_put_be16(&buf, avctx->height);
 +    *buf++ = 0x83; // {10}(422){00}{00}(frame){11}
 +    *buf++ = 0;
 +    *buf++ = 2;
 +    *buf++ = 2;
 +    *buf++ = 6;
 +    *buf++ = 32;
 +    *buf++ = 0;
 +    *buf++ = 3;
 +
 +    bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile],   64);
 +    bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
 +
 +    pkt->flags |= AV_PKT_FLAG_KEY;
 +    pkt->size = pic_size + 8 + header_size;
 +    *got_packet = 1;
 +
 +    return 0;
 +}
 +
 +static void scale_mat(const uint8_t* src, int* dst, int scale)
 +{
 +    int i;
 +    for (i = 0; i < 64; i++)
 +        dst[i] = src[i] * scale;
 +}
 +
 +static av_cold int prores_encode_init(AVCodecContext *avctx)
 +{
 +    int i;
 +    ProresContext* ctx = avctx->priv_data;
 +
 +    if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) {
 +        av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n");
 +        return -1;
 +    }
 +    avctx->bits_per_raw_sample = 10;
 +
 +    if (avctx->width & 0x1) {
 +        av_log(avctx, AV_LOG_ERROR,
 +                "frame width needs to be multiple of 2\n");
 +        return -1;
 +    }
 +
 +    if (avctx->width > 65534 || avctx->height > 65535) {
 +        av_log(avctx, AV_LOG_ERROR,
 +                "The maximum dimensions are 65534x65535\n");
 +        return AVERROR(EINVAL);
 +    }
 +
 +    if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
 +        ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
 +        if (!ctx->fill_y)
 +            return AVERROR(ENOMEM);
 +        ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
 +        ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
 +    }
 +
 +    if (avctx->profile == FF_PROFILE_UNKNOWN) {
 +        avctx->profile = FF_PROFILE_PRORES_STANDARD;
 +        av_log(avctx, AV_LOG_INFO,
 +                "encoding with ProRes standard (apcn) profile\n");
 +
 +    } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
 +            || avctx->profile > FF_PROFILE_PRORES_HQ) {
 +        av_log(
 +                avctx,
 +                AV_LOG_ERROR,
 +                "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n",
 +                avctx->profile);
 +        return -1;
 +    }
 +
 +    ff_fdctdsp_init(&ctx->fdsp, avctx);
 +
 +    avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
 +
 +    for (i = 1; i <= 16; i++) {
 +        scale_mat(QMAT_LUMA[avctx->profile]  , ctx->qmat_luma[i - 1]  , i);
 +        scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
 +    }
 +
 +    avctx->coded_frame = av_frame_alloc();
 +    avctx->coded_frame->key_frame = 1;
 +    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
 +
 +    return 0;
 +}
 +
 +static av_cold int prores_encode_close(AVCodecContext *avctx)
 +{
 +    ProresContext* ctx = avctx->priv_data;
 +    av_freep(&avctx->coded_frame);
 +    av_freep(&ctx->fill_y);
 +
 +    return 0;
 +}
 +
 +AVCodec ff_prores_aw_encoder = {
 +    .name           = "prores_aw",
 +    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_PRORES,
 +    .priv_data_size = sizeof(ProresContext),
 +    .init           = prores_encode_init,
 +    .close          = prores_encode_close,
 +    .encode2        = prores_encode_frame,
 +    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
 +    .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
 +    .profiles       = profiles
 +};
 +
 +AVCodec ff_prores_encoder = {
 +    .name           = "prores",
 +    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = AV_CODEC_ID_PRORES,
 +    .priv_data_size = sizeof(ProresContext),
 +    .init           = prores_encode_init,
 +    .close          = prores_encode_close,
 +    .encode2        = prores_encode_frame,
 +    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
 +    .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
 +    .profiles       = profiles
 +};
index 668fe72,0000000..dc80ce6
mode 100644,000000..100644
--- /dev/null
@@@ -1,723 -1,0 +1,723 @@@
- #include "dsputil.h"
 +/*
 + * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#include "libavutil/intmath.h"
 +#include "libavutil/log.h"
 +#include "libavutil/opt.h"
 +#include "avcodec.h"
-     ff_dsputil_init(&s->dsp, avctx);
++#include "me_cmp.h"
 +#include "snow_dwt.h"
 +#include "internal.h"
 +#include "snow.h"
 +#include "snowdata.h"
 +
 +#include "rangecoder.h"
 +#include "mathops.h"
 +#include "h263.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;
 +            }
 +        }
 +    }
 +}
 +
 +int ff_snow_get_buffer(SnowContext *s, AVFrame *frame)
 +{
 +    int ret, i;
 +    int edges_needed = av_codec_is_encoder(s->avctx->codec);
 +
 +    frame->width  = s->avctx->width ;
 +    frame->height = s->avctx->height;
 +    if (edges_needed) {
 +        frame->width  += 2 * EDGE_WIDTH;
 +        frame->height += 2 * EDGE_WIDTH;
 +    }
 +    if ((ret = ff_get_buffer(s->avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
 +        return ret;
 +    if (edges_needed) {
 +        for (i = 0; frame->data[i]; i++) {
 +            int offset = (EDGE_WIDTH >> (i ? s->chroma_v_shift : 0)) *
 +                            frame->linesize[i] +
 +                            (EDGE_WIDTH >> (i ? s->chroma_h_shift : 0));
 +            frame->data[i] += offset;
 +        }
 +        frame->width  = s->avctx->width;
 +        frame->height = s->avctx->height;
 +    }
 +
 +    return 0;
 +}
 +
 +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= FF_CEIL_RSHIFT(s->avctx->width,  LOG2_MB_SIZE);
 +    int h= FF_CEIL_RSHIFT(s->avctx->height, LOG2_MB_SIZE);
 +
 +    s->b_width = w;
 +    s->b_height= h;
 +
 +    av_free(s->block);
 +    s->block= av_mallocz_array(w * h,  sizeof(BlockNode) << (s->block_max_depth*2));
 +    if (!s->block)
 +        return AVERROR(ENOMEM);
 +
 +    return 0;
 +}
 +
 +static av_cold 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];
 +    av_assert2(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, ptrdiff_t 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 ?  (2*s->mv_scale)>>s->chroma_h_shift : 2*s->mv_scale;
 +        int mx= block->mx*scale;
 +        int my= block->my*scale;
 +        const int dx= mx&15;
 +        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 >= FFMAX(w - b_w - (HTAPS_MAX-2), 0)
 +           || (unsigned)sy >= FFMAX(h - b_h - (HTAPS_MAX-2), 0)){
 +            s->vdsp.emulated_edge_mc(tmp + MB_SIZE, src,
 +                                     stride, stride,
 +                                     b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1,
 +                                     sx, sy, w, h);
 +            src= tmp + MB_SIZE;
 +        }
 +
 +        av_assert2(s->chroma_h_shift == s->chroma_v_shift); // only one mv_scale
 +
 +        av_assert2((tab_index>=0 && tab_index<4) || b_w==32);
 +        if(    (dx&3) || (dy&3)
 +            || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h)
 +            || (b_w&(b_w-1))
 +            || b_w == 1
 +            || b_h == 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->h264qpel.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + y*stride, src + 3 + (y+3)*stride,stride);
 +                s->h264qpel.put_h264_qpel_pixels_tab[0][dy+(dx>>2)](dst + 16 + y*stride, src + 19 + (y+3)*stride,stride);
 +            }
 +        }else if(b_w==b_h)
 +            s->h264qpel.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst,src + 3 + 3*stride,stride);
 +        else if(b_w==2*b_h){
 +            s->h264qpel.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst    ,src + 3       + 3*stride,stride);
 +            s->h264qpel.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride);
 +        }else{
 +            av_assert2(2*b_w==b_h);
 +            s->h264qpel.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst           ,src + 3 + 3*stride           ,stride);
 +            s->h264qpel.put_h264_qpel_pixels_tab[tab_index  ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride);
 +        }
 +    }
 +}
 +
 +#define mca(dx,dy,b_w)\
 +static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, ptrdiff_t stride, int h){\
 +    av_assert2(h==b_w);\
 +    mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, stride, b_w, b_w, dx, dy);\
 +}
 +
 +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;
 +
 +    s->avctx= avctx;
 +    s->max_ref_frames=1; //just make sure it's not an invalid value in case of no initial keyframe
 +
++    ff_me_cmp_init(&s->mecc, avctx);
 +    ff_hpeldsp_init(&s->hdsp, avctx->flags);
 +    ff_videodsp_init(&s->vdsp, 8);
 +    ff_dwt_init(&s->dwt);
 +    ff_h264qpel_init(&s->h264qpel, 8);
 +
 +#define mcf(dx,dy)\
 +    s->qdsp.put_qpel_pixels_tab       [0][dy+dx/4]=\
 +    s->qdsp.put_no_rnd_qpel_pixels_tab[0][dy+dx/4]=\
 +        s->h264qpel.put_h264_qpel_pixels_tab[0][dy+dx/4];\
 +    s->qdsp.put_qpel_pixels_tab       [1][dy+dx/4]=\
 +    s->qdsp.put_no_rnd_qpel_pixels_tab[1][dy+dx/4]=\
 +        s->h264qpel.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->hdsp.put_pixels_tab       [0][dy/4+dx/8]=\
 +    s->hdsp.put_no_rnd_pixels_tab[0][dy/4+dx/8]=\
 +        mc_block_hpel ## dx ## dy ## 16;\
 +    s->hdsp.put_pixels_tab       [1][dy/4+dx/8]=\
 +    s->hdsp.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_ARRAY_OR_GOTO(avctx, s->spatial_idwt_buffer, width, height * sizeof(IDWTELEM), fail);
 +    FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->spatial_dwt_buffer,  width, height * sizeof(DWTELEM),  fail); //FIXME this does not belong here
 +    FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->temp_dwt_buffer,     width, sizeof(DWTELEM),  fail);
 +    FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->temp_idwt_buffer,    width, sizeof(IDWTELEM), fail);
 +    FF_ALLOC_ARRAY_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);
 +        s->last_picture[i] = av_frame_alloc();
 +        if (!s->last_picture[i])
 +            goto fail;
 +    }
 +
 +    s->mconly_picture = av_frame_alloc();
 +    s->current_picture = av_frame_alloc();
 +    if (!s->mconly_picture || !s->current_picture)
 +        goto 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;
 +    int ret, emu_buf_size;
 +
 +    if(!s->scratchbuf) {
 +        if ((ret = ff_get_buffer(s->avctx, s->mconly_picture,
 +                                 AV_GET_BUFFER_FLAG_REF)) < 0)
 +            return ret;
 +        FF_ALLOCZ_ARRAY_OR_GOTO(avctx, s->scratchbuf, FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256), 7*MB_SIZE, fail);
 +        emu_buf_size = FFMAX(s->mconly_picture->linesize[0], 2*avctx->width+256) * (2 * MB_SIZE + HTAPS_MAX - 1);
 +        FF_ALLOC_OR_GOTO(avctx, s->emu_edge_buffer, emu_buf_size, fail);
 +    }
 +
 +    if(s->mconly_picture->format != avctx->pix_fmt) {
 +        av_log(avctx, AV_LOG_ERROR, "pixel format changed\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    for(plane_index=0; plane_index < s->nb_planes; 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_array(((b->width+1) * b->height+1), sizeof(x_and_coeff));
 +                if (!b->x_coeff)
 +                    goto fail;
 +            }
 +            w= (w+1)>>1;
 +            h= (h+1)>>1;
 +        }
 +    }
 +
 +    return 0;
 +fail:
 +    return AVERROR(ENOMEM);
 +}
 +
 +#define USE_HALFPEL_PLANE 0
 +
 +static int halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){
 +    int p,x,y;
 +
 +    for(p=0; p < s->nb_planes; p++){
 +        int is_chroma= !!p;
 +        int w= is_chroma ? s->avctx->width >>s->chroma_h_shift : s->avctx->width;
 +        int h= is_chroma ? s->avctx->height>>s->chroma_v_shift : s->avctx->height;
 +        int ls= frame->linesize[p];
 +        uint8_t *src= frame->data[p];
 +
 +        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);
 +        if (!halfpel[1][p] || !halfpel[2][p] || !halfpel[3][p])
 +            return AVERROR(ENOMEM);
 +
 +        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!
 +    }
 +    return 0;
 +}
 +
 +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]){
 +        av_frame_unref(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 i, ret;
 +
 +    ff_snow_release_buffer(s->avctx);
 +
 +    tmp= s->last_picture[s->max_ref_frames-1];
 +    for(i=s->max_ref_frames-1; i>0; i--)
 +        s->last_picture[i] = s->last_picture[i-1];
 +    memmove(s->halfpel_plane+1, s->halfpel_plane, (s->max_ref_frames-1)*sizeof(void*)*4*4);
 +    if(USE_HALFPEL_PLANE && s->current_picture->data[0]) {
 +        if((ret = halfpel_interpol(s, s->halfpel_plane[0], s->current_picture)) < 0)
 +            return ret;
 +    }
 +    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;
 +        }
 +    }
 +    if ((ret = ff_snow_get_buffer(s, s->current_picture)) < 0)
 +        return ret;
 +
 +    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]) {
 +            av_assert0(s->last_picture[i]->data[0] != s->current_picture->data[0]);
 +        }
 +        av_frame_free(&s->last_picture[i]);
 +    }
 +
 +    for(plane_index=0; plane_index < s->nb_planes; 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);
 +            }
 +        }
 +    }
 +    av_frame_free(&s->mconly_picture);
 +    av_frame_free(&s->current_picture);
 +}
index 2cda5b3,0000000..38810c1
mode 100644,000000..100644
--- /dev/null
@@@ -1,710 -1,0 +1,710 @@@
- #include "dsputil.h"
 +/*
 + * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
 + * Copyright (C) 2006 Robert Edele <yartrebo@earthlink.net>
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#ifndef AVCODEC_SNOW_H
 +#define AVCODEC_SNOW_H
 +
-     DSPContext dsp;
 +#include "hpeldsp.h"
++#include "me_cmp.h"
 +#include "qpeldsp.h"
 +#include "snow_dwt.h"
 +
 +#include "rangecoder.h"
 +#include "mathops.h"
 +#include "mpegvideo.h"
 +#include "h264qpel.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;
++    MECmpContext mecc;
 +    HpelDSPContext hdsp;
 +    QpelDSPContext qdsp;
 +    VideoDSPContext vdsp;
 +    H264QpelContext h264qpel;
 +    MpegvideoEncDSPContext mpvencdsp;
 +    SnowDWTContext 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;
 +    int nb_planes;
 +    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;
 +    int no_bitstream;
 +
 +    MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
 +
 +    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, ptrdiff_t stride,
 +                     int sx, int sy, int b_w, int b_h, BlockNode *block,
 +                     int plane_index, int w, int h);
 +int ff_snow_get_buffer(SnowContext *s, AVFrame *frame);
 +/* 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;
 +    }
 +    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;
 +    }
 +    if(src_y + b_h> h){
 +        b_h = h - src_y;
 +    }
 +
 +    if(b_w<=0 || b_h<=0) return;
 +
 +    av_assert2(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>>s->chroma_h_shift : block_size;
 +    int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
 +    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
 +    const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
 +    int ref_stride= s->current_picture->linesize[plane_index];
 +    uint8_t *dst8= s->current_picture->data[plane_index];
 +    int w= p->width;
 +    int h= p->height;
 +    av_assert2(s->chroma_h_shift == s->chroma_v_shift); // obmc params assume squares
 +    if(s->keyframe || (s->avctx->debug&512)){
 +        if(mb_y==mb_h)
 +            return;
 +
 +        if(add){
 +            for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
 +                for(x=0; x<w; x++){
 +                    int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
 +                    v >>= FRAC_BITS;
 +                    if(v&(~255)) v= ~(v>>31);
 +                    dst8[x + y*ref_stride]= v;
 +                }
 +            }
 +        }else{
 +            for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
 +                for(x=0; x<w; x++){
 +                    buf[x + y*w]-= 128<<FRAC_BITS;
 +                }
 +            }
 +        }
 +
 +        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_h*mb_y - block_h/2,
 +                   block_w, block_h,
 +                   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;
 +    const int block_h= 1<<rem_depth; //FIXME "w!=h"
 +    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_h; 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){
 +    SnowContext *s = c->avctx->priv_data;
 +    const int offset[3]= {
 +          y*c->  stride + x,
 +        ((y*c->uvstride + x)>>s->chroma_h_shift),
 +        ((y*c->uvstride + x)>>s->chroma_h_shift),
 +    };
 +    int i;
 +    for(i=0; i<3; i++){
 +        c->src[0][i]= src [i];
 +        c->ref[0][i]= ref [i] + offset[i];
 +    }
 +    av_assert2(!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;
 +
 +    av_assert2(v>=0);
 +    av_assert2(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;
 +
 +    av_assert2(log2>=-4);
 +
 +    while(log2<28 && 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;
 +                    av_assert2(run >= 0);
 +                    if(y) max_run= FFMIN(run, prev_xc->x - x - 2);
 +                    else  max_run= FFMIN(run, w-x-1);
 +                    if(parent_xc)
 +                        max_run= FFMIN(max_run, 2*parent_xc->x - x - 1);
 +                    av_assert2(max_run >= 0 && max_run <= run);
 +
 +                    x+= max_run;
 +                    run-= max_run;
 +                }
 +            }
 +        }
 +        (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 */
index cd94c13,0000000..63ff7a0
mode 100644,000000..100644
--- /dev/null
@@@ -1,865 -1,0 +1,865 @@@
- #include "dsputil.h"
 +/*
 + * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
 + * Copyright (C) 2008 David Conrad
 + *
 + * This file is part of FFmpeg.
 + *
 + * FFmpeg is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU Lesser General Public
 + * License as published by the Free Software Foundation; either
 + * version 2.1 of the License, or (at your option) any later version.
 + *
 + * FFmpeg is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 + * Lesser General Public License for more details.
 + *
 + * You should have received a copy of the GNU Lesser General Public
 + * License along with FFmpeg; if not, write to the Free Software
 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + */
 +
 +#include "libavutil/attributes.h"
 +#include "libavutil/avassert.h"
 +#include "libavutil/common.h"
- void ff_dsputil_init_dwt(DSPContext *c)
++#include "me_cmp.h"
 +#include "snow_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_array(line_count, sizeof(IDWTELEM *));
 +    if (!buf->line)
 +        return AVERROR(ENOMEM);
 +    buf->data_stack  = av_malloc_array(max_allocated_lines, sizeof(IDWTELEM *));
 +    if (!buf->data_stack) {
 +        av_freep(&buf->line);
 +        return AVERROR(ENOMEM);
 +    }
 +
 +    for (i = 0; i < max_allocated_lines; i++) {
 +        buf->data_stack[i] = av_malloc_array(line_width, sizeof(IDWTELEM));
 +        if (!buf->data_stack[i]) {
 +            for (i--; i >=0; i--)
 +                av_freep(&buf->data_stack[i]);
 +            av_freep(&buf->data_stack);
 +            av_freep(&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;
 +
 +    av_assert0(buf->data_stack_top >= 0);
 +//  av_assert1(!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;
 +
 +    av_assert1(line >= 0 && line < buf->line_count);
 +    av_assert1(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;
 +
 +    av_assert1(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,
 +                       &