Merge commit '512f3ffe9b4bb86767c2b1176554407c75fe1a5c'
authorMichael Niedermayer <michaelni@gmx.at>
Tue, 27 May 2014 22:03:59 +0000 (00:03 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 27 May 2014 22:03:59 +0000 (00:03 +0200)
* commit '512f3ffe9b4bb86767c2b1176554407c75fe1a5c':
  dsputil: Split off HuffYUV encoding bits into their own context

Conflicts:
configure
libavcodec/dsputil.c
libavcodec/dsputil.h
libavcodec/huffyuv.h
libavcodec/huffyuvenc.c
libavcodec/pngenc.c
libavcodec/x86/dsputilenc_mmx.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
15 files changed:
1  2 
configure
libavcodec/Makefile
libavcodec/dsputil.c
libavcodec/dsputil.h
libavcodec/huffyuv.h
libavcodec/huffyuvenc.c
libavcodec/huffyuvencdsp.c
libavcodec/huffyuvencdsp.h
libavcodec/pngenc.c
libavcodec/utvideo.h
libavcodec/utvideoenc.c
libavcodec/x86/Makefile
libavcodec/x86/dsputilenc_mmx.c
libavcodec/x86/huffyuvdsp_init.c
libavcodec/x86/huffyuvencdsp_mmx.c

diff --cc configure
+++ b/configure
@@@ -1806,9 -1542,9 +1806,10 @@@ CONFIG_EXTRA=
      hpeldsp
      huffman
      huffyuvdsp
+     huffyuvencdsp
      intrax8
      lgplv3
 +    llviddsp
      lpc
      mpegaudio
      mpegaudiodsp
@@@ -2060,8 -1773,8 +2061,8 @@@ h263p_encoder_select="h263_encoder
  h264_decoder_select="cabac golomb h264chroma h264dsp h264pred h264qpel videodsp"
  h264_decoder_suggest="error_resilience"
  hevc_decoder_select="cabac dsputil golomb videodsp"
 -huffyuv_decoder_select="dsputil huffyuvdsp"
 -huffyuv_encoder_select="dsputil huffman huffyuvencdsp"
 +huffyuv_decoder_select="dsputil huffyuvdsp llviddsp"
- huffyuv_encoder_select="dsputil huffman llviddsp"
++huffyuv_encoder_select="dsputil huffman huffyuvencdsp llviddsp"
  iac_decoder_select="imc_decoder"
  imc_decoder_select="dsputil fft mdct sinewin"
  indeo3_decoder_select="hpeldsp"
@@@ -2111,9 -1824,10 +2112,9 @@@ nellymoser_decoder_select="mdct sinewin
  nellymoser_encoder_select="audio_frame_queue mdct sinewin"
  nuv_decoder_select="dsputil lzo"
  on2avc_decoder_select="mdct"
 -opus_decoder_deps="avresample"
 -png_decoder_deps="zlib"
 -png_encoder_deps="zlib"
 -png_encoder_select="huffyuvencdsp"
 +opus_decoder_deps="swresample"
 +png_decoder_select="zlib"
- png_encoder_select="dsputil zlib"
++png_encoder_select="huffyuvencdsp zlib"
  prores_decoder_select="dsputil"
  prores_encoder_select="dsputil"
  qcelp_decoder_select="lsp"
@@@ -2145,13 -1852,13 +2146,13 @@@ theora_decoder_select="vp3_decoder
  thp_decoder_select="mjpeg_decoder"
  tiff_decoder_suggest="zlib"
  tiff_encoder_suggest="zlib"
 -truehd_decoder_select="mlp_decoder"
 +truehd_decoder_select="mlp_parser"
  truemotion2_decoder_select="dsputil"
  truespeech_decoder_select="dsputil"
 -tscc_decoder_deps="zlib"
 +tscc_decoder_select="zlib"
  twinvq_decoder_select="mdct lsp sinewin"
  utvideo_decoder_select="dsputil"
- utvideo_encoder_select="dsputil huffman"
+ utvideo_encoder_select="dsputil huffman huffyuvencdsp"
  vble_decoder_select="huffyuvdsp"
  vc1_decoder_select="error_resilience h263_decoder h264chroma h264qpel intrax8"
  vc1image_decoder_select="vc1_decoder"
@@@ -55,12 -47,12 +55,13 @@@ OBJS-$(CONFIG_H264QPEL)                
  OBJS-$(CONFIG_HPELDSP)                 += hpeldsp.o
  OBJS-$(CONFIG_HUFFMAN)                 += huffman.o
  OBJS-$(CONFIG_HUFFYUVDSP)              += huffyuvdsp.o
+ OBJS-$(CONFIG_HUFFYUVENCDSP)           += huffyuvencdsp.o
  OBJS-$(CONFIG_INTRAX8)                 += intrax8.o intrax8dsp.o
  OBJS-$(CONFIG_LIBXVID)                 += libxvid_rc.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_MPEGAUDIO)               += mpegaudio.o mpegaudiodata.o   \
                                            mpegaudiodecheader.o
  OBJS-$(CONFIG_MPEGAUDIODSP)            += mpegaudiodsp.o                \
Simple merge
Simple merge
@@@ -35,8 -35,8 +35,9 @@@
  #include "dsputil.h"
  #include "get_bits.h"
  #include "huffyuvdsp.h"
+ #include "huffyuvencdsp.h"
  #include "put_bits.h"
 +#include "lossless_videodsp.h"
  
  #define VLC_BITS 11
  
@@@ -97,7 -84,7 +98,8 @@@ typedef struct HYuvContext 
      unsigned int bitstream_buffer_size;
      DSPContext dsp;
      HuffYUVDSPContext hdsp;
+     HuffYUVEncDSPContext hencdsp;
 +    LLVidDSPContext llviddsp;
  } HYuvContext;
  
  void ff_huffyuv_common_init(AVCodecContext *s);
  #include "avcodec.h"
  #include "huffyuv.h"
  #include "huffman.h"
+ #include "huffyuvencdsp.h"
 +#include "internal.h"
  #include "put_bits.h"
-         s->dsp.diff_bytes(dst, src0, src1, w);
 +#include "libavutil/pixdesc.h"
 +
 +static inline void diff_bytes(HYuvContext *s, uint8_t *dst,
 +                              const uint8_t *src0, const uint8_t *src1, int w)
 +{
 +    if (s->bps <= 8) {
++        s->hencdsp.diff_bytes(dst, src0, src1, w);
 +    } else {
 +        s->llviddsp.diff_int16((uint16_t *)dst, (const uint16_t *)src0, (const uint16_t *)src1, s->n - 1, w);
 +    }
 +}
  
  static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst,
 -                                      uint8_t *src, int w, int left)
 +                                      const uint8_t *src, int w, int left)
  {
      int i;
 -    if (w < 32) {
 -        for (i = 0; i < w; i++) {
 -            const int temp = src[i];
 -            dst[i] = temp - left;
 -            left   = temp;
 +    if (s->bps <= 8) {
 +        if (w < 32) {
 +            for (i = 0; i < w; i++) {
 +                const int temp = src[i];
 +                dst[i] = temp - left;
 +                left   = temp;
 +            }
 +            return left;
 +        } else {
 +            for (i = 0; i < 16; i++) {
 +                const int temp = src[i];
 +                dst[i] = temp - left;
 +                left   = temp;
 +            }
-             s->dsp.diff_bytes(dst + 16, src + 16, src + 15, w - 16);
++            s->hencdsp.diff_bytes(dst + 16, src + 16, src + 15, w - 16);
 +            return src[w-1];
          }
 -        return left;
      } else {
 -        for (i = 0; i < 16; i++) {
 -            const int temp = src[i];
 -            dst[i] = temp - left;
 -            left   = temp;
 +        const uint16_t *src16 = (const uint16_t *)src;
 +        uint16_t       *dst16 = (      uint16_t *)dst;
 +        if (w < 32) {
 +            for (i = 0; i < w; i++) {
 +                const int temp = src16[i];
 +                dst16[i] = temp - left;
 +                left   = temp;
 +            }
 +            return left;
 +        } else {
 +            for (i = 0; i < 16; i++) {
 +                const int temp = src16[i];
 +                dst16[i] = temp - left;
 +                left   = temp;
 +            }
 +            s->llviddsp.diff_int16(dst16 + 16, src16 + 16, src16 + 15, s->n - 1, w - 16);
 +            return src16[w-1];
          }
 -        s->hencdsp.diff_bytes(dst + 16, src + 16, src + 15, w - 16);
 -        return src[w-1];
      }
  }
  
@@@ -151,15 -117,6 +152,15 @@@ static inline void sub_left_prediction_
      *blue  = src[(w - 1) * 3 + 2];
  }
  
-         s->dsp.sub_hfyu_median_prediction(dst, src1, src2, w , left, left_top);
 +static void sub_median_prediction(HYuvContext *s, uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w, int *left, int *left_top)
 +{
 +    if (s->bps <= 8) {
++        s->hencdsp.sub_hfyu_median_pred(dst, src1, src2, w , left, left_top);
 +    } else {
 +        s->llviddsp.sub_hfyu_median_prediction_int16((uint16_t *)dst, (const uint16_t *)src1, (const uint16_t *)src2, s->n - 1, w , left, left_top);
 +    }
 +}
 +
  static int store_table(HYuvContext *s, const uint8_t *len, uint8_t *buf)
  {
      int i;
@@@ -211,20 -145,12 +212,21 @@@ static av_cold int encode_init(AVCodecC
  {
      HYuvContext *s = avctx->priv_data;
      int i, j;
 +    int ret;
 +    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
  
      ff_huffyuv_common_init(avctx);
+     ff_huffyuvencdsp_init(&s->hencdsp);
  
 -    avctx->extradata = av_mallocz(1024*30); // 256*3+4 == 772
 -    avctx->stats_out = av_mallocz(1024*30); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132
 +    avctx->extradata = av_mallocz(3*MAX_N + 4);
 +    if (!avctx->extradata)
 +        return AVERROR(ENOMEM);
 +    if (s->flags&CODEC_FLAG_PASS1) {
 +#define STATS_OUT_SIZE 21*MAX_N*3 + 4
 +        avctx->stats_out = av_mallocz(STATS_OUT_SIZE); // 21*256*3(%llu ) + 3(\n) + 1(0) = 16132
 +        if (!avctx->stats_out)
 +            return AVERROR(ENOMEM);
 +    }
      s->version = 2;
  
      avctx->coded_frame = av_frame_alloc();
index 0000000,6c30877..1f9256b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,84 +1,84 @@@
 - * 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
 -static void diff_bytes_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w)
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "config.h"
+ #include "libavutil/attributes.h"
+ #include "huffyuvencdsp.h"
+ #include "mathops.h"
+ // 0x7f7f7f7f or 0x7f7f7f7f7f7f7f7f or whatever, depending on the cpu's native arithmetic size
+ #define pb_7f (~0UL / 255 * 0x7f)
+ #define pb_80 (~0UL / 255 * 0x80)
++static void diff_bytes_c(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w)
+ {
+     long i;
+ #if !HAVE_FAST_UNALIGNED
+     if ((long) src2 & (sizeof(long) - 1)) {
+         for (i = 0; i + 7 < w; i += 8) {
+             dst[i + 0] = src1[i + 0] - src2[i + 0];
+             dst[i + 1] = src1[i + 1] - src2[i + 1];
+             dst[i + 2] = src1[i + 2] - src2[i + 2];
+             dst[i + 3] = src1[i + 3] - src2[i + 3];
+             dst[i + 4] = src1[i + 4] - src2[i + 4];
+             dst[i + 5] = src1[i + 5] - src2[i + 5];
+             dst[i + 6] = src1[i + 6] - src2[i + 6];
+             dst[i + 7] = src1[i + 7] - src2[i + 7];
+         }
+     } else
+ #endif
+     for (i = 0; i <= w - (int) sizeof(long); i += sizeof(long)) {
+         long a = *(long *) (src1 + i);
+         long b = *(long *) (src2 + i);
+         *(long *) (dst + i) = ((a | pb_80) - (b & pb_7f)) ^
+                               ((a ^ b ^ pb_80) & pb_80);
+     }
+     for (; i < w; i++)
+         dst[i + 0] = src1[i + 0] - src2[i + 0];
+ }
+ static void sub_hfyu_median_pred_c(uint8_t *dst, const uint8_t *src1,
+                                    const uint8_t *src2, int w,
+                                    int *left, int *left_top)
+ {
+     int i;
+     uint8_t l, lt;
+     l  = *left;
+     lt = *left_top;
+     for (i = 0; i < w; i++) {
+         const int pred = mid_pred(l, src1[i], (l + src1[i] - lt) & 0xFF);
+         lt     = src1[i];
+         l      = src2[i];
+         dst[i] = l - pred;
+     }
+     *left     = l;
+     *left_top = lt;
+ }
+ av_cold void ff_huffyuvencdsp_init(HuffYUVEncDSPContext *c)
+ {
+     c->diff_bytes           = diff_bytes_c;
+     c->sub_hfyu_median_pred = sub_hfyu_median_pred_c;
+     if (ARCH_X86)
+         ff_huffyuvencdsp_init_x86(c);
+ }
index 0000000,603c36f..3a49b4a
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,41 +1,41 @@@
 - * 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
 -                       uint8_t *src1 /* align 16 */,
 -                       uint8_t *src2 /* align 1 */,
++ * 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_HUFFYUVENCDSP_H
+ #define AVCODEC_HUFFYUVENCDSP_H
+ #include <stdint.h>
+ typedef struct HuffYUVEncDSPContext {
+     void (*diff_bytes)(uint8_t *dst /* align 16 */,
++                       const uint8_t *src1 /* align 16 */,
++                       const uint8_t *src2 /* align 1 */,
+                        int w);
+     /**
+      * Subtract HuffYUV's variant of median prediction.
+      * Note, this might read from src1[-1], src2[-1].
+      */
+     void (*sub_hfyu_median_pred)(uint8_t *dst, const uint8_t *src1,
+                                  const uint8_t *src2, int w,
+                                  int *left, int *left_top);
+ } HuffYUVEncDSPContext;
+ void ff_huffyuvencdsp_init(HuffYUVEncDSPContext *c);
+ void ff_huffyuvencdsp_init_x86(HuffYUVEncDSPContext *c);
+ #endif /* AVCODEC_HUFFYUVENCDSP_H */
   */
  
  #include "avcodec.h"
 +#include "internal.h"
  #include "bytestream.h"
- #include "dsputil.h"
+ #include "huffyuvencdsp.h"
  #include "png.h"
  
 -/* TODO:
 - * - add 2, 4 and 16 bit depth support
 - */
 +#include "libavutil/avassert.h"
 +#include "libavutil/opt.h"
  
  #include <zlib.h>
  
  #define IOBUF_SIZE 4096
  
  typedef struct PNGEncContext {
-     DSPContext dsp;
 +    AVClass *class;
+     HuffYUVEncDSPContext hdsp;
  
      uint8_t *bytestream;
      uint8_t *bytestream_start;
@@@ -115,23 -111,7 +115,23 @@@ static void sub_png_paeth_prediction(ui
      }
  }
  
- static void sub_left_prediction(DSPContext *dsp, uint8_t *dst, const uint8_t *src, int bpp, int size)
++static void sub_left_prediction(PNGEncContext *c, uint8_t *dst, const uint8_t *src, int bpp, int size)
 +{
 +    const uint8_t *src1 = src + bpp;
 +    const uint8_t *src2 = src;
 +    int x, unaligned_w;
 +
 +    memcpy(dst, src, bpp);
 +    dst += bpp;
 +    size -= bpp;
 +    unaligned_w = FFMIN(32 - bpp, size);
 +    for (x = 0; x < unaligned_w; x++)
 +        *dst++ = *src1++ - *src2++;
 +    size -= unaligned_w;
-     dsp->diff_bytes(dst, src1, src2, size);
++    c->hdsp.diff_bytes(dst, src1, src2, size);
 +}
 +
- static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type,
+ static void png_filter_row(PNGEncContext *c, uint8_t *dst, int filter_type,
                             uint8_t *src, uint8_t *top, int size, int bpp)
  {
      int i;
          memcpy(dst, src, size);
          break;
      case PNG_FILTER_VALUE_SUB:
-         sub_left_prediction(dsp, dst, src, bpp, size);
 -        c->hdsp.diff_bytes(dst, src, src - bpp, size);
 -        memcpy(dst, src, bpp);
++        sub_left_prediction(c, dst, src, bpp, size);
          break;
      case PNG_FILTER_VALUE_UP:
-         dsp->diff_bytes(dst, src, top, size);
+         c->hdsp.diff_bytes(dst, src, top, size);
          break;
      case PNG_FILTER_VALUE_AVG:
          for (i = 0; i < bpp; i++)
Simple merge
Simple merge
@@@ -15,10 -13,9 +15,11 @@@ OBJS-$(CONFIG_H264CHROMA)              
  OBJS-$(CONFIG_H264DSP)                 += x86/h264dsp_init.o
  OBJS-$(CONFIG_H264PRED)                += x86/h264_intrapred_init.o
  OBJS-$(CONFIG_H264QPEL)                += x86/h264_qpel.o
 +OBJS-$(CONFIG_HEVC_DECODER)            += x86/hevcdsp_init.o
  OBJS-$(CONFIG_HPELDSP)                 += x86/hpeldsp_init.o
 +OBJS-$(CONFIG_LLVIDDSP)                += x86/lossless_videodsp_init.o
  OBJS-$(CONFIG_HUFFYUVDSP)              += x86/huffyuvdsp_init.o
+ OBJS-$(CONFIG_HUFFYUVENCDSP)           += x86/huffyuvencdsp_mmx.o
  OBJS-$(CONFIG_LPC)                     += x86/lpc.o
  OBJS-$(CONFIG_MPEGAUDIODSP)            += x86/mpegaudiodsp.o
  OBJS-$(CONFIG_MPEGVIDEO)               += x86/mpegvideo.o
@@@ -700,70 -693,117 +699,6 @@@ static int vsad16_mmxext(MpegEncContex
  }
  #undef SUM
  
- static void diff_bytes_mmx(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w)
- {
-     x86_reg i = 0;
 -#define MMABS_MMX(a,z)                          \
 -    "pxor "    #z ", " #z "             \n\t"   \
 -    "pcmpgtw " #a ", " #z "             \n\t"   \
 -    "pxor "    #z ", " #a "             \n\t"   \
 -    "psubw "   #z ", " #a "             \n\t"
--
-     if (w >= 16)
-     __asm__ volatile (
-         "1:                             \n\t"
-         "movq  (%2, %0), %%mm0          \n\t"
-         "movq  (%1, %0), %%mm1          \n\t"
-         "psubb %%mm0, %%mm1             \n\t"
-         "movq %%mm1, (%3, %0)           \n\t"
-         "movq 8(%2, %0), %%mm0          \n\t"
-         "movq 8(%1, %0), %%mm1          \n\t"
-         "psubb %%mm0, %%mm1             \n\t"
-         "movq %%mm1, 8(%3, %0)          \n\t"
-         "add $16, %0                    \n\t"
-         "cmp %4, %0                     \n\t"
-         " jb 1b                         \n\t"
-         : "+r" (i)
-         : "r" (src1), "r" (src2), "r" (dst), "r" ((x86_reg) w - 15));
 -#define MMABS_MMXEXT(a, z)                      \
 -    "pxor "    #z ", " #z "             \n\t"   \
 -    "psubw "   #a ", " #z "             \n\t"   \
 -    "pmaxsw "  #z ", " #a "             \n\t"
--
-     for (; i < w; i++)
-         dst[i + 0] = src1[i + 0] - src2[i + 0];
- }
 -#define MMABS_SSSE3(a,z)                        \
 -    "pabsw "   #a ", " #a "             \n\t"
--
- static void sub_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *src1,
-                                               const uint8_t *src2, int w,
-                                               int *left, int *left_top)
- {
-     x86_reg i = 0;
-     uint8_t l, lt;
 -#define MMABS_SUM(a,z, sum)                     \
 -    MMABS(a,z)                                  \
 -    "paddusw " #a ", " #sum "           \n\t"
--
-     __asm__ volatile (
-         "movq  (%1, %0), %%mm0          \n\t" // LT
-         "psllq $8, %%mm0                \n\t"
-         "1:                             \n\t"
-         "movq  (%1, %0), %%mm1          \n\t" // T
-         "movq  -1(%2, %0), %%mm2        \n\t" // L
-         "movq  (%2, %0), %%mm3          \n\t" // X
-         "movq %%mm2, %%mm4              \n\t" // L
-         "psubb %%mm0, %%mm2             \n\t"
-         "paddb %%mm1, %%mm2             \n\t" // L + T - LT
-         "movq %%mm4, %%mm5              \n\t" // L
-         "pmaxub %%mm1, %%mm4            \n\t" // max(T, L)
-         "pminub %%mm5, %%mm1            \n\t" // min(T, L)
-         "pminub %%mm2, %%mm4            \n\t"
-         "pmaxub %%mm1, %%mm4            \n\t"
-         "psubb %%mm4, %%mm3             \n\t" // dst - pred
-         "movq %%mm3, (%3, %0)           \n\t"
-         "add $8, %0                     \n\t"
-         "movq -1(%1, %0), %%mm0         \n\t" // LT
-         "cmp %4, %0                     \n\t"
-         " jb 1b                         \n\t"
-         : "+r" (i)
-         : "r" (src1), "r" (src2), "r" (dst), "r" ((x86_reg) w));
 -/* FIXME: HSUM_* saturates at 64k, while an 8x8 hadamard or dct block can get
 - * up to about 100k on extreme inputs. But that's very unlikely to occur in
 - * natural video, and it's even more unlikely to not have any alternative
 - * mvs/modes with lower cost. */
 -#define HSUM_MMX(a, t, dst)                     \
 -    "movq    " #a ", " #t "             \n\t"   \
 -    "psrlq      $32, " #a "             \n\t"   \
 -    "paddusw " #t ", " #a "             \n\t"   \
 -    "movq    " #a ", " #t "             \n\t"   \
 -    "psrlq      $16, " #a "             \n\t"   \
 -    "paddusw " #t ", " #a "             \n\t"   \
 -    "movd    " #a ", " #dst "           \n\t"   \
--
-     l  = *left;
-     lt = *left_top;
 -#define HSUM_MMXEXT(a, t, dst)                  \
 -    "pshufw   $0x0E, " #a ", " #t "     \n\t"   \
 -    "paddusw " #t ", " #a "             \n\t"   \
 -    "pshufw   $0x01, " #a ", " #t "     \n\t"   \
 -    "paddusw " #t ", " #a "             \n\t"   \
 -    "movd    " #a ", " #dst "           \n\t"   \
--
-     dst[0] = src2[0] - mid_pred(l, src1[0], (l + src1[0] - lt) & 0xFF);
 -#define HSUM_SSE2(a, t, dst)                    \
 -    "movhlps " #a ", " #t "             \n\t"   \
 -    "paddusw " #t ", " #a "             \n\t"   \
 -    "pshuflw  $0x0E, " #a ", " #t "     \n\t"   \
 -    "paddusw " #t ", " #a "             \n\t"   \
 -    "pshuflw  $0x01, " #a ", " #t "     \n\t"   \
 -    "paddusw " #t ", " #a "             \n\t"   \
 -    "movd    " #a ", " #dst "           \n\t"   \
--
-     *left_top = src1[w - 1];
-     *left     = src2[w - 1];
 -#define DCT_SAD4(m, mm, o)                      \
 -    "mov"#m" "#o" +  0(%1), " #mm "2    \n\t"   \
 -    "mov"#m" "#o" + 16(%1), " #mm "3    \n\t"   \
 -    "mov"#m" "#o" + 32(%1), " #mm "4    \n\t"   \
 -    "mov"#m" "#o" + 48(%1), " #mm "5    \n\t"   \
 -    MMABS_SUM(mm ## 2, mm ## 6, mm ## 0)        \
 -    MMABS_SUM(mm ## 3, mm ## 7, mm ## 1)        \
 -    MMABS_SUM(mm ## 4, mm ## 6, mm ## 0)        \
 -    MMABS_SUM(mm ## 5, mm ## 7, mm ## 1)        \
 -
 -#define DCT_SAD_MMX                             \
 -    "pxor    %%mm0, %%mm0               \n\t"   \
 -    "pxor    %%mm1, %%mm1               \n\t"   \
 -    DCT_SAD4(q, %%mm, 0)                        \
 -    DCT_SAD4(q, %%mm, 8)                        \
 -    DCT_SAD4(q, %%mm, 64)                       \
 -    DCT_SAD4(q, %%mm, 72)                       \
 -    "paddusw %%mm1, %%mm0               \n\t"   \
 -    HSUM(%%mm0, %%mm1, %0)
 -
 -#define DCT_SAD_SSE2                            \
 -    "pxor    %%xmm0, %%xmm0             \n\t"   \
 -    "pxor    %%xmm1, %%xmm1             \n\t"   \
 -    DCT_SAD4(dqa, %%xmm, 0)                     \
 -    DCT_SAD4(dqa, %%xmm, 64)                    \
 -    "paddusw %%xmm1, %%xmm0             \n\t"   \
 -    HSUM(%%xmm0, %%xmm1, %0)
 -
 -#define DCT_SAD_FUNC(cpu)                           \
 -static int sum_abs_dctelem_ ## cpu(int16_t *block)  \
 -{                                                   \
 -    int sum;                                        \
 -    __asm__ volatile (                              \
 -        DCT_SAD                                     \
 -        :"=r"(sum)                                  \
 -        :"r"(block));                               \
 -    return sum & 0xFFFF;                            \
--}
 -
 -#define DCT_SAD         DCT_SAD_MMX
 -#define HSUM(a, t, dst) HSUM_MMX(a, t, dst)
 -#define MMABS(a, z)     MMABS_MMX(a, z)
 -DCT_SAD_FUNC(mmx)
 -#undef MMABS
 -#undef HSUM
 -
 -#define HSUM(a, t, dst) HSUM_MMXEXT(a, t, dst)
 -#define MMABS(a, z)     MMABS_MMXEXT(a, z)
 -DCT_SAD_FUNC(mmxext)
 -#undef HSUM
 -#undef DCT_SAD
 -
 -#define DCT_SAD         DCT_SAD_SSE2
 -#define HSUM(a, t, dst) HSUM_SSE2(a, t, dst)
 -DCT_SAD_FUNC(sse2)
 -#undef MMABS
 -
 -#if HAVE_SSSE3_INLINE
 -#define MMABS(a, z)     MMABS_SSSE3(a, z)
 -DCT_SAD_FUNC(ssse3)
 -#undef MMABS
 -#endif
 -#undef HSUM
 -#undef DCT_SAD
  
  static int ssd_int8_vs_int16_mmx(const int8_t *pix1, const int16_t *pix2,
                                   int size)
@@@ -905,7 -945,8 +840,6 @@@ av_cold void ff_dsputilenc_init_mmx(DSP
              (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX))
              c->fdct = ff_fdct_mmx;
  
-         c->diff_bytes      = diff_bytes_mmx;
 -        c->sum_abs_dctelem = sum_abs_dctelem_mmx;
 -
          c->sse[0]  = sse16_mmx;
          c->sse[1]  = sse8_mmx;
          c->vsad[4] = vsad_intra16_mmx;
@@@ -42,7 -42,7 +42,7 @@@ av_cold void ff_huffyuvdsp_init_x86(Huf
      int cpu_flags = av_get_cpu_flags();
  
  #if HAVE_7REGS && HAVE_INLINE_ASM
--    if (cpu_flags & AV_CPU_FLAG_CMOV)
++    if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_CMOV)
          c->add_hfyu_median_pred = ff_add_hfyu_median_pred_cmov;
  #endif
  
index 0000000,8ffaced..63d8e3c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,113 +1,114 @@@
 - * This file is part of Libav.
+ /*
+  * SIMD-optimized HuffYUV encoding functions
+  * Copyright (c) 2000, 2001 Fabrice Bellard
+  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+  *
+  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
+  *
 - * 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
 -static void diff_bytes_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w)
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "libavutil/attributes.h"
+ #include "libavutil/cpu.h"
+ #include "libavutil/x86/asm.h"
+ #include "libavutil/x86/cpu.h"
+ #include "libavcodec/huffyuvencdsp.h"
+ #include "libavcodec/mathops.h"
+ #if HAVE_INLINE_ASM
++static void diff_bytes_mmx(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w)
+ {
+     x86_reg i = 0;
++    if (w >= 16)
+     __asm__ volatile (
+         "1:                             \n\t"
+         "movq  (%2, %0), %%mm0          \n\t"
+         "movq  (%1, %0), %%mm1          \n\t"
+         "psubb %%mm0, %%mm1             \n\t"
+         "movq %%mm1, (%3, %0)           \n\t"
+         "movq 8(%2, %0), %%mm0          \n\t"
+         "movq 8(%1, %0), %%mm1          \n\t"
+         "psubb %%mm0, %%mm1             \n\t"
+         "movq %%mm1, 8(%3, %0)          \n\t"
+         "add $16, %0                    \n\t"
+         "cmp %4, %0                     \n\t"
+         " jb 1b                         \n\t"
+         : "+r" (i)
+         : "r" (src1), "r" (src2), "r" (dst), "r" ((x86_reg) w - 15));
+     for (; i < w; i++)
+         dst[i + 0] = src1[i + 0] - src2[i + 0];
+ }
+ static void sub_hfyu_median_pred_mmxext(uint8_t *dst, const uint8_t *src1,
+                                         const uint8_t *src2, int w,
+                                         int *left, int *left_top)
+ {
+     x86_reg i = 0;
+     uint8_t l, lt;
+     __asm__ volatile (
+         "movq  (%1, %0), %%mm0          \n\t" // LT
+         "psllq $8, %%mm0                \n\t"
+         "1:                             \n\t"
+         "movq  (%1, %0), %%mm1          \n\t" // T
+         "movq  -1(%2, %0), %%mm2        \n\t" // L
+         "movq  (%2, %0), %%mm3          \n\t" // X
+         "movq %%mm2, %%mm4              \n\t" // L
+         "psubb %%mm0, %%mm2             \n\t"
+         "paddb %%mm1, %%mm2             \n\t" // L + T - LT
+         "movq %%mm4, %%mm5              \n\t" // L
+         "pmaxub %%mm1, %%mm4            \n\t" // max(T, L)
+         "pminub %%mm5, %%mm1            \n\t" // min(T, L)
+         "pminub %%mm2, %%mm4            \n\t"
+         "pmaxub %%mm1, %%mm4            \n\t"
+         "psubb %%mm4, %%mm3             \n\t" // dst - pred
+         "movq %%mm3, (%3, %0)           \n\t"
+         "add $8, %0                     \n\t"
+         "movq -1(%1, %0), %%mm0         \n\t" // LT
+         "cmp %4, %0                     \n\t"
+         " jb 1b                         \n\t"
+         : "+r" (i)
+         : "r" (src1), "r" (src2), "r" (dst), "r" ((x86_reg) w));
+     l  = *left;
+     lt = *left_top;
+     dst[0] = src2[0] - mid_pred(l, src1[0], (l + src1[0] - lt) & 0xFF);
+     *left_top = src1[w - 1];
+     *left     = src2[w - 1];
+ }
+ #endif /* HAVE_INLINE_ASM */
+ av_cold void ff_huffyuvencdsp_init_x86(HuffYUVEncDSPContext *c)
+ {
+ #if HAVE_INLINE_ASM
+     int cpu_flags = av_get_cpu_flags();
+     if (INLINE_MMX(cpu_flags)) {
+         c->diff_bytes = diff_bytes_mmx;
+     }
+     if (INLINE_MMXEXT(cpu_flags)) {
+         c->sub_hfyu_median_pred = sub_hfyu_median_pred_mmxext;
+     }
+ #endif /* HAVE_INLINE_ASM */
+ }