Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2000, 2001 Fabrice Bellard
  3.  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  7.  * FFmpeg is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * FFmpeg is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with FFmpeg; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20.  */
  21.  
  22. #include "config.h"
  23. #include "libavutil/attributes.h"
  24. #include "libavutil/cpu.h"
  25. #include "libavutil/x86/asm.h"
  26. #include "libavutil/x86/cpu.h"
  27. #include "libavcodec/dsputil.h"
  28. #include "libavcodec/simple_idct.h"
  29. #include "dsputil_x86.h"
  30. #include "idct_xvid.h"
  31.  
  32. void ff_put_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
  33.                               int dstStride, int src1Stride, int h);
  34. void ff_put_no_rnd_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1,
  35.                                      uint8_t *src2, int dstStride,
  36.                                      int src1Stride, int h);
  37. void ff_avg_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
  38.                               int dstStride, int src1Stride, int h);
  39. void ff_put_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
  40.                                int dstStride, int src1Stride, int h);
  41. void ff_avg_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
  42.                                int dstStride, int src1Stride, int h);
  43. void ff_put_no_rnd_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
  44.                                       int dstStride, int src1Stride, int h);
  45. void ff_put_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  46.                                          int dstStride, int srcStride, int h);
  47. void ff_avg_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  48.                                          int dstStride, int srcStride, int h);
  49. void ff_put_no_rnd_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  50.                                                  int dstStride, int srcStride,
  51.                                                  int h);
  52. void ff_put_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  53.                                         int dstStride, int srcStride, int h);
  54. void ff_avg_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  55.                                         int dstStride, int srcStride, int h);
  56. void ff_put_no_rnd_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  57.                                                 int dstStride, int srcStride,
  58.                                                 int h);
  59. void ff_put_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  60.                                          int dstStride, int srcStride);
  61. void ff_avg_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  62.                                          int dstStride, int srcStride);
  63. void ff_put_no_rnd_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  64.                                                  int dstStride, int srcStride);
  65. void ff_put_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  66.                                         int dstStride, int srcStride);
  67. void ff_avg_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  68.                                         int dstStride, int srcStride);
  69. void ff_put_no_rnd_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
  70.                                                 int dstStride, int srcStride);
  71. #define ff_put_no_rnd_pixels16_mmxext ff_put_pixels16_mmxext
  72. #define ff_put_no_rnd_pixels8_mmxext ff_put_pixels8_mmxext
  73.  
  74. void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale);
  75. void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale);
  76.  
  77. int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2,
  78.                                       int order);
  79. int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2,
  80.                                     int order);
  81. int32_t ff_scalarproduct_and_madd_int16_mmxext(int16_t *v1, const int16_t *v2,
  82.                                                const int16_t *v3,
  83.                                                int order, int mul);
  84. int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2,
  85.                                              const int16_t *v3,
  86.                                              int order, int mul);
  87. int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2,
  88.                                               const int16_t *v3,
  89.                                               int order, int mul);
  90.  
  91. void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input,
  92.                                         const int16_t *window, unsigned int len);
  93. void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input,
  94.                                       const int16_t *window, unsigned int len);
  95. void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input,
  96.                                   const int16_t *window, unsigned int len);
  97. void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input,
  98.                                 const int16_t *window, unsigned int len);
  99. void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input,
  100.                                  const int16_t *window, unsigned int len);
  101. void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input,
  102.                                       const int16_t *window, unsigned int len);
  103.  
  104. void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w);
  105. void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w);
  106.  
  107. void ff_add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top,
  108.                                           const uint8_t *diff, int w,
  109.                                           int *left, int *left_top);
  110. int  ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src,
  111.                                        int w, int left);
  112. int  ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src,
  113.                                       int w, int left);
  114.  
  115. void ff_vector_clip_int32_mmx     (int32_t *dst, const int32_t *src,
  116.                                    int32_t min, int32_t max, unsigned int len);
  117. void ff_vector_clip_int32_sse2    (int32_t *dst, const int32_t *src,
  118.                                    int32_t min, int32_t max, unsigned int len);
  119. void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src,
  120.                                    int32_t min, int32_t max, unsigned int len);
  121. void ff_vector_clip_int32_sse4    (int32_t *dst, const int32_t *src,
  122.                                    int32_t min, int32_t max, unsigned int len);
  123.  
  124. #if HAVE_YASM
  125.  
  126. PIXELS16(static, ff_avg, , , _mmxext)
  127. PIXELS16(static, ff_put, , , _mmxext)
  128.  
  129. #define QPEL_OP(OPNAME, RND, MMX)                                       \
  130. static void OPNAME ## qpel8_mc00_ ## MMX (uint8_t *dst, uint8_t *src,   \
  131.                                           ptrdiff_t stride)             \
  132. {                                                                       \
  133.     ff_ ## OPNAME ## pixels8_ ## MMX(dst, src, stride, 8);              \
  134. }                                                                       \
  135.                                                                         \
  136. static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, uint8_t *src,    \
  137.                                          ptrdiff_t stride)              \
  138. {                                                                       \
  139.     uint64_t temp[8];                                                   \
  140.     uint8_t * const half = (uint8_t*)temp;                              \
  141.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,        \
  142.                                                    stride, 8);          \
  143.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half,                 \
  144.                                         stride, stride, 8);             \
  145. }                                                                       \
  146.                                                                         \
  147. static void OPNAME ## qpel8_mc20_ ## MMX(uint8_t *dst, uint8_t *src,    \
  148.                                          ptrdiff_t stride)              \
  149. {                                                                       \
  150.     ff_ ## OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride,    \
  151.                                                    stride, 8);          \
  152. }                                                                       \
  153.                                                                         \
  154. static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, uint8_t *src,    \
  155.                                          ptrdiff_t stride)              \
  156. {                                                                       \
  157.     uint64_t temp[8];                                                   \
  158.     uint8_t * const half = (uint8_t*)temp;                              \
  159.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8,        \
  160.                                                    stride, 8);          \
  161.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride,     \
  162.                                         stride, 8);                     \
  163. }                                                                       \
  164.                                                                         \
  165. static void OPNAME ## qpel8_mc01_ ## MMX(uint8_t *dst, uint8_t *src,    \
  166.                                          ptrdiff_t stride)              \
  167. {                                                                       \
  168.     uint64_t temp[8];                                                   \
  169.     uint8_t * const half = (uint8_t*)temp;                              \
  170.     ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src,           \
  171.                                                    8, stride);          \
  172.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half,                 \
  173.                                         stride, stride, 8);             \
  174. }                                                                       \
  175.                                                                         \
  176. static void OPNAME ## qpel8_mc02_ ## MMX(uint8_t *dst, uint8_t *src,    \
  177.                                          ptrdiff_t stride)              \
  178. {                                                                       \
  179.     ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src,            \
  180.                                                    stride, stride);     \
  181. }                                                                       \
  182.                                                                         \
  183. static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, uint8_t *src,    \
  184.                                          ptrdiff_t stride)              \
  185. {                                                                       \
  186.     uint64_t temp[8];                                                   \
  187.     uint8_t * const half = (uint8_t*)temp;                              \
  188.     ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src,           \
  189.                                                    8, stride);          \
  190.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,\
  191.                                         stride, 8);                     \
  192. }                                                                       \
  193.                                                                         \
  194. static void OPNAME ## qpel8_mc11_ ## MMX(uint8_t *dst, uint8_t *src,    \
  195.                                          ptrdiff_t stride)              \
  196. {                                                                       \
  197.     uint64_t half[8 + 9];                                               \
  198.     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
  199.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  200.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
  201.                                                    stride, 9);          \
  202.     ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8,           \
  203.                                         stride, 9);                     \
  204.     ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
  205.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
  206.                                         stride, 8, 8);                  \
  207. }                                                                       \
  208.                                                                         \
  209. static void OPNAME ## qpel8_mc31_ ## MMX(uint8_t *dst, uint8_t *src,    \
  210.                                          ptrdiff_t stride)              \
  211. {                                                                       \
  212.     uint64_t half[8 + 9];                                               \
  213.     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
  214.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  215.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
  216.                                                    stride, 9);          \
  217.     ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
  218.                                         stride, 9);                     \
  219.     ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
  220.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
  221.                                         stride, 8, 8);                  \
  222. }                                                                       \
  223.                                                                         \
  224. static void OPNAME ## qpel8_mc13_ ## MMX(uint8_t *dst, uint8_t *src,    \
  225.                                          ptrdiff_t stride)              \
  226. {                                                                       \
  227.     uint64_t half[8 + 9];                                               \
  228.     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
  229.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  230.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
  231.                                                    stride, 9);          \
  232.     ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8,           \
  233.                                         stride, 9);                     \
  234.     ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
  235.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
  236.                                         stride, 8, 8);                  \
  237. }                                                                       \
  238.                                                                         \
  239. static void OPNAME ## qpel8_mc33_ ## MMX(uint8_t *dst, uint8_t *src,    \
  240.                                          ptrdiff_t stride)              \
  241. {                                                                       \
  242.     uint64_t half[8 + 9];                                               \
  243.     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
  244.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  245.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
  246.                                                    stride, 9);          \
  247.     ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
  248.                                         stride, 9);                     \
  249.     ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
  250.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
  251.                                         stride, 8, 8);                  \
  252. }                                                                       \
  253.                                                                         \
  254. static void OPNAME ## qpel8_mc21_ ## MMX(uint8_t *dst, uint8_t *src,    \
  255.                                          ptrdiff_t stride)              \
  256. {                                                                       \
  257.     uint64_t half[8 + 9];                                               \
  258.     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
  259.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  260.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
  261.                                                    stride, 9);          \
  262.     ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
  263.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV,             \
  264.                                         stride, 8, 8);                  \
  265. }                                                                       \
  266.                                                                         \
  267. static void OPNAME ## qpel8_mc23_ ## MMX(uint8_t *dst, uint8_t *src,    \
  268.                                          ptrdiff_t stride)              \
  269. {                                                                       \
  270.     uint64_t half[8 + 9];                                               \
  271.     uint8_t * const halfH  = ((uint8_t*)half) + 64;                     \
  272.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  273.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
  274.                                                    stride, 9);          \
  275.     ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
  276.     ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV,         \
  277.                                         stride, 8, 8);                  \
  278. }                                                                       \
  279.                                                                         \
  280. static void OPNAME ## qpel8_mc12_ ## MMX(uint8_t *dst, uint8_t *src,    \
  281.                                          ptrdiff_t stride)              \
  282. {                                                                       \
  283.     uint64_t half[8 + 9];                                               \
  284.     uint8_t * const halfH = ((uint8_t*)half);                           \
  285.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
  286.                                                    stride, 9);          \
  287.     ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH,              \
  288.                                         8, stride, 9);                  \
  289.     ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
  290.                                                    stride, 8);          \
  291. }                                                                       \
  292.                                                                         \
  293. static void OPNAME ## qpel8_mc32_ ## MMX(uint8_t *dst, uint8_t *src,    \
  294.                                          ptrdiff_t stride)              \
  295. {                                                                       \
  296.     uint64_t half[8 + 9];                                               \
  297.     uint8_t * const halfH = ((uint8_t*)half);                           \
  298.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
  299.                                                    stride, 9);          \
  300.     ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8,       \
  301.                                         stride, 9);                     \
  302.     ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
  303.                                                    stride, 8);          \
  304. }                                                                       \
  305.                                                                         \
  306. static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, uint8_t *src,    \
  307.                                          ptrdiff_t stride)              \
  308. {                                                                       \
  309.     uint64_t half[9];                                                   \
  310.     uint8_t * const halfH = ((uint8_t*)half);                           \
  311.     ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8,       \
  312.                                                    stride, 9);          \
  313.     ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH,          \
  314.                                                    stride, 8);          \
  315. }                                                                       \
  316.                                                                         \
  317. static void OPNAME ## qpel16_mc00_ ## MMX (uint8_t *dst, uint8_t *src,  \
  318.                                            ptrdiff_t stride)            \
  319. {                                                                       \
  320.     ff_ ## OPNAME ## pixels16_ ## MMX(dst, src, stride, 16);            \
  321. }                                                                       \
  322.                                                                         \
  323. static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, uint8_t *src,   \
  324.                                           ptrdiff_t stride)             \
  325. {                                                                       \
  326.     uint64_t temp[32];                                                  \
  327.     uint8_t * const half = (uint8_t*)temp;                              \
  328.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,      \
  329.                                                     stride, 16);        \
  330.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride,        \
  331.                                          stride, 16);                   \
  332. }                                                                       \
  333.                                                                         \
  334. static void OPNAME ## qpel16_mc20_ ## MMX(uint8_t *dst, uint8_t *src,   \
  335.                                           ptrdiff_t stride)             \
  336. {                                                                       \
  337.     ff_ ## OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src,           \
  338.                                                     stride, stride, 16);\
  339. }                                                                       \
  340.                                                                         \
  341. static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, uint8_t *src,   \
  342.                                           ptrdiff_t stride)             \
  343. {                                                                       \
  344.     uint64_t temp[32];                                                  \
  345.     uint8_t * const half = (uint8_t*)temp;                              \
  346.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16,      \
  347.                                                     stride, 16);        \
  348.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half,            \
  349.                                          stride, stride, 16);           \
  350. }                                                                       \
  351.                                                                         \
  352. static void OPNAME ## qpel16_mc01_ ## MMX(uint8_t *dst, uint8_t *src,   \
  353.                                           ptrdiff_t stride)             \
  354. {                                                                       \
  355.     uint64_t temp[32];                                                  \
  356.     uint8_t * const half = (uint8_t*)temp;                              \
  357.     ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,      \
  358.                                                     stride);            \
  359.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride,        \
  360.                                          stride, 16);                   \
  361. }                                                                       \
  362.                                                                         \
  363. static void OPNAME ## qpel16_mc02_ ## MMX(uint8_t *dst, uint8_t *src,   \
  364.                                           ptrdiff_t stride)             \
  365. {                                                                       \
  366.     ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src,           \
  367.                                                     stride, stride);    \
  368. }                                                                       \
  369.                                                                         \
  370. static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, uint8_t *src,   \
  371.                                           ptrdiff_t stride)             \
  372. {                                                                       \
  373.     uint64_t temp[32];                                                  \
  374.     uint8_t * const half = (uint8_t*)temp;                              \
  375.     ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16,      \
  376.                                                     stride);            \
  377.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half,         \
  378.                                          stride, stride, 16);           \
  379. }                                                                       \
  380.                                                                         \
  381. static void OPNAME ## qpel16_mc11_ ## MMX(uint8_t *dst, uint8_t *src,   \
  382.                                           ptrdiff_t stride)             \
  383. {                                                                       \
  384.     uint64_t half[16 * 2 + 17 * 2];                                     \
  385.     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
  386.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  387.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
  388.                                                     stride, 17);        \
  389.     ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
  390.                                          stride, 17);                   \
  391.     ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
  392.                                                     16, 16);            \
  393.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
  394.                                          stride, 16, 16);               \
  395. }                                                                       \
  396.                                                                         \
  397. static void OPNAME ## qpel16_mc31_ ## MMX(uint8_t *dst, uint8_t *src,   \
  398.                                           ptrdiff_t stride)             \
  399. {                                                                       \
  400.     uint64_t half[16 * 2 + 17 * 2];                                     \
  401.     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
  402.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  403.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
  404.                                                     stride, 17);        \
  405.     ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
  406.                                          stride, 17);                   \
  407.     ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
  408.                                                     16, 16);            \
  409.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
  410.                                          stride, 16, 16);               \
  411. }                                                                       \
  412.                                                                         \
  413. static void OPNAME ## qpel16_mc13_ ## MMX(uint8_t *dst, uint8_t *src,   \
  414.                                           ptrdiff_t stride)             \
  415. {                                                                       \
  416.     uint64_t half[16 * 2 + 17 * 2];                                     \
  417.     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
  418.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  419.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
  420.                                                     stride, 17);        \
  421.     ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
  422.                                          stride, 17);                   \
  423.     ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
  424.                                                     16, 16);            \
  425.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
  426.                                          stride, 16, 16);               \
  427. }                                                                       \
  428.                                                                         \
  429. static void OPNAME ## qpel16_mc33_ ## MMX(uint8_t *dst, uint8_t *src,   \
  430.                                           ptrdiff_t stride)             \
  431. {                                                                       \
  432.     uint64_t half[16 * 2 + 17 * 2];                                     \
  433.     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
  434.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  435.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
  436.                                                     stride, 17);        \
  437.     ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
  438.                                          stride, 17);                   \
  439.     ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
  440.                                                     16, 16);            \
  441.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
  442.                                          stride, 16, 16);               \
  443. }                                                                       \
  444.                                                                         \
  445. static void OPNAME ## qpel16_mc21_ ## MMX(uint8_t *dst, uint8_t *src,   \
  446.                                           ptrdiff_t stride)             \
  447. {                                                                       \
  448.     uint64_t half[16 * 2 + 17 * 2];                                     \
  449.     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
  450.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  451.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
  452.                                                     stride, 17);        \
  453.     ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
  454.                                                     16, 16);            \
  455.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV,            \
  456.                                          stride, 16, 16);               \
  457. }                                                                       \
  458.                                                                         \
  459. static void OPNAME ## qpel16_mc23_ ## MMX(uint8_t *dst, uint8_t *src,   \
  460.                                           ptrdiff_t stride)             \
  461. {                                                                       \
  462.     uint64_t half[16 * 2 + 17 * 2];                                     \
  463.     uint8_t * const halfH  = ((uint8_t*)half) + 256;                    \
  464.     uint8_t * const halfHV = ((uint8_t*)half);                          \
  465.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
  466.                                                     stride, 17);        \
  467.     ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH,      \
  468.                                                     16, 16);            \
  469.     ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV,       \
  470.                                          stride, 16, 16);               \
  471. }                                                                       \
  472.                                                                         \
  473. static void OPNAME ## qpel16_mc12_ ## MMX(uint8_t *dst, uint8_t *src,   \
  474.                                           ptrdiff_t stride)             \
  475. {                                                                       \
  476.     uint64_t half[17 * 2];                                              \
  477.     uint8_t * const halfH = ((uint8_t*)half);                           \
  478.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
  479.                                                     stride, 17);        \
  480.     ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16,         \
  481.                                          stride, 17);                   \
  482.     ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
  483.                                                     stride, 16);        \
  484. }                                                                       \
  485.                                                                         \
  486. static void OPNAME ## qpel16_mc32_ ## MMX(uint8_t *dst, uint8_t *src,   \
  487.                                           ptrdiff_t stride)             \
  488. {                                                                       \
  489.     uint64_t half[17 * 2];                                              \
  490.     uint8_t * const halfH = ((uint8_t*)half);                           \
  491.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
  492.                                                     stride, 17);        \
  493.     ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16,     \
  494.                                          stride, 17);                   \
  495.     ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
  496.                                                     stride, 16);        \
  497. }                                                                       \
  498.                                                                         \
  499. static void OPNAME ## qpel16_mc22_ ## MMX(uint8_t *dst, uint8_t *src,   \
  500.                                           ptrdiff_t stride)             \
  501. {                                                                       \
  502.     uint64_t half[17 * 2];                                              \
  503.     uint8_t * const halfH = ((uint8_t*)half);                           \
  504.     ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16,     \
  505.                                                     stride, 17);        \
  506.     ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH,         \
  507.                                                     stride, 16);        \
  508. }
  509.  
  510. QPEL_OP(put_,        _,        mmxext)
  511. QPEL_OP(avg_,        _,        mmxext)
  512. QPEL_OP(put_no_rnd_, _no_rnd_, mmxext)
  513. #endif /* HAVE_YASM */
  514.  
  515. #define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX)                          \
  516.     do {                                                                     \
  517.     c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \
  518.     c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \
  519.     c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \
  520.     c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \
  521.     c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \
  522.     c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \
  523.     c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \
  524.     c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \
  525.     c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \
  526.     c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \
  527.     c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \
  528.     c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \
  529.     c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \
  530.     c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \
  531.     c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \
  532.     c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \
  533.     } while (0)
  534.  
  535. static av_cold void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx,
  536.                                      int cpu_flags)
  537. {
  538. #if HAVE_MMX_INLINE
  539.     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
  540.  
  541.     c->put_pixels_clamped        = ff_put_pixels_clamped_mmx;
  542.     c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx;
  543.     c->add_pixels_clamped        = ff_add_pixels_clamped_mmx;
  544.  
  545.     if (!high_bit_depth) {
  546.         c->clear_block  = ff_clear_block_mmx;
  547.         c->clear_blocks = ff_clear_blocks_mmx;
  548.         c->draw_edges   = ff_draw_edges_mmx;
  549.     }
  550.  
  551. #if CONFIG_VIDEODSP && (ARCH_X86_32 || !HAVE_YASM)
  552.     c->gmc = ff_gmc_mmx;
  553. #endif
  554.  
  555.     c->add_bytes = ff_add_bytes_mmx;
  556. #endif /* HAVE_MMX_INLINE */
  557.  
  558. #if HAVE_MMX_EXTERNAL
  559.     if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
  560.         c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx;
  561.         c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx;
  562.     }
  563.  
  564.     c->vector_clip_int32 = ff_vector_clip_int32_mmx;
  565. #endif /* HAVE_MMX_EXTERNAL */
  566. }
  567.  
  568. static av_cold void dsputil_init_mmxext(DSPContext *c, AVCodecContext *avctx,
  569.                                         int cpu_flags)
  570. {
  571. #if HAVE_MMXEXT_INLINE
  572.     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
  573.  
  574.     if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX && avctx->lowres == 0) {
  575.         c->idct_put = ff_idct_xvid_mmxext_put;
  576.         c->idct_add = ff_idct_xvid_mmxext_add;
  577.         c->idct     = ff_idct_xvid_mmxext;
  578.     }
  579. #endif /* HAVE_MMXEXT_INLINE */
  580.  
  581. #if HAVE_MMXEXT_EXTERNAL
  582.     SET_QPEL_FUNCS(avg_qpel,        0, 16, mmxext, );
  583.     SET_QPEL_FUNCS(avg_qpel,        1,  8, mmxext, );
  584.  
  585.     SET_QPEL_FUNCS(put_qpel,        0, 16, mmxext, );
  586.     SET_QPEL_FUNCS(put_qpel,        1,  8, mmxext, );
  587.     SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, );
  588.     SET_QPEL_FUNCS(put_no_rnd_qpel, 1,  8, mmxext, );
  589.  
  590.     /* slower than cmov version on AMD */
  591.     if (!(cpu_flags & AV_CPU_FLAG_3DNOW))
  592.         c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmxext;
  593.  
  594.     c->scalarproduct_int16          = ff_scalarproduct_int16_mmxext;
  595.     c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext;
  596.  
  597.     if (avctx->flags & CODEC_FLAG_BITEXACT) {
  598.         c->apply_window_int16 = ff_apply_window_int16_mmxext;
  599.     } else {
  600.         c->apply_window_int16 = ff_apply_window_int16_round_mmxext;
  601.     }
  602. #endif /* HAVE_MMXEXT_EXTERNAL */
  603. }
  604.  
  605. static av_cold void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx,
  606.                                      int cpu_flags)
  607. {
  608. #if HAVE_SSE_INLINE
  609.     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
  610.  
  611.     if (!high_bit_depth) {
  612.         if (!(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)) {
  613.             /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */
  614.             c->clear_block  = ff_clear_block_sse;
  615.             c->clear_blocks = ff_clear_blocks_sse;
  616.         }
  617.     }
  618.  
  619.     c->vector_clipf = ff_vector_clipf_sse;
  620. #endif /* HAVE_SSE_INLINE */
  621.  
  622. #if HAVE_YASM
  623. #if HAVE_INLINE_ASM && CONFIG_VIDEODSP
  624.     c->gmc = ff_gmc_sse;
  625. #endif
  626. #endif /* HAVE_YASM */
  627. }
  628.  
  629. static av_cold void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx,
  630.                                       int cpu_flags)
  631. {
  632. #if HAVE_SSE2_INLINE
  633.     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
  634.  
  635.     if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX && avctx->lowres == 0) {
  636.         c->idct_put              = ff_idct_xvid_sse2_put;
  637.         c->idct_add              = ff_idct_xvid_sse2_add;
  638.         c->idct                  = ff_idct_xvid_sse2;
  639.         c->idct_permutation_type = FF_SSE2_IDCT_PERM;
  640.     }
  641. #endif /* HAVE_SSE2_INLINE */
  642.  
  643. #if HAVE_SSE2_EXTERNAL
  644.     c->scalarproduct_int16          = ff_scalarproduct_int16_sse2;
  645.     c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2;
  646.     if (cpu_flags & AV_CPU_FLAG_ATOM) {
  647.         c->vector_clip_int32 = ff_vector_clip_int32_int_sse2;
  648.     } else {
  649.         c->vector_clip_int32 = ff_vector_clip_int32_sse2;
  650.     }
  651.     if (avctx->flags & CODEC_FLAG_BITEXACT) {
  652.         c->apply_window_int16 = ff_apply_window_int16_sse2;
  653.     } else if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
  654.         c->apply_window_int16 = ff_apply_window_int16_round_sse2;
  655.     }
  656.     c->bswap_buf = ff_bswap32_buf_sse2;
  657. #endif /* HAVE_SSE2_EXTERNAL */
  658. }
  659.  
  660. static av_cold void dsputil_init_ssse3(DSPContext *c, AVCodecContext *avctx,
  661.                                        int cpu_flags)
  662. {
  663. #if HAVE_SSSE3_EXTERNAL
  664.     c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_ssse3;
  665.     if (cpu_flags & AV_CPU_FLAG_SSE4) // not really SSE4, just slow on Conroe
  666.         c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_sse4;
  667.  
  668.     if (cpu_flags & AV_CPU_FLAG_ATOM)
  669.         c->apply_window_int16 = ff_apply_window_int16_ssse3_atom;
  670.     else
  671.         c->apply_window_int16 = ff_apply_window_int16_ssse3;
  672.     if (!(cpu_flags & (AV_CPU_FLAG_SSE42 | AV_CPU_FLAG_3DNOW))) // cachesplit
  673.         c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3;
  674.     c->bswap_buf = ff_bswap32_buf_ssse3;
  675. #endif /* HAVE_SSSE3_EXTERNAL */
  676. }
  677.  
  678. static av_cold void dsputil_init_sse4(DSPContext *c, AVCodecContext *avctx,
  679.                                       int cpu_flags)
  680. {
  681. #if HAVE_SSE4_EXTERNAL
  682.     c->vector_clip_int32 = ff_vector_clip_int32_sse4;
  683. #endif /* HAVE_SSE4_EXTERNAL */
  684. }
  685.  
  686. av_cold void ff_dsputil_init_x86(DSPContext *c, AVCodecContext *avctx)
  687. {
  688.     int cpu_flags = av_get_cpu_flags();
  689.  
  690. #if HAVE_7REGS && HAVE_INLINE_ASM
  691.     if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_CMOV)
  692.         c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_cmov;
  693. #endif
  694.  
  695.     if (X86_MMX(cpu_flags)) {
  696. #if HAVE_INLINE_ASM
  697.         const int idct_algo = avctx->idct_algo;
  698.  
  699.         if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) {
  700.             if (idct_algo == FF_IDCT_AUTO || idct_algo == FF_IDCT_SIMPLEMMX) {
  701.                 c->idct_put              = ff_simple_idct_put_mmx;
  702.                 c->idct_add              = ff_simple_idct_add_mmx;
  703.                 c->idct                  = ff_simple_idct_mmx;
  704.                 c->idct_permutation_type = FF_SIMPLE_IDCT_PERM;
  705.             } else if (idct_algo == FF_IDCT_XVIDMMX) {
  706.                 c->idct_put              = ff_idct_xvid_mmx_put;
  707.                 c->idct_add              = ff_idct_xvid_mmx_add;
  708.                 c->idct                  = ff_idct_xvid_mmx;
  709.             }
  710.         }
  711. #endif /* HAVE_INLINE_ASM */
  712.  
  713.         dsputil_init_mmx(c, avctx, cpu_flags);
  714.     }
  715.  
  716.     if (X86_MMXEXT(cpu_flags))
  717.         dsputil_init_mmxext(c, avctx, cpu_flags);
  718.  
  719.     if (X86_SSE(cpu_flags))
  720.         dsputil_init_sse(c, avctx, cpu_flags);
  721.  
  722.     if (X86_SSE2(cpu_flags))
  723.         dsputil_init_sse2(c, avctx, cpu_flags);
  724.  
  725.     if (EXTERNAL_SSSE3(cpu_flags))
  726.         dsputil_init_ssse3(c, avctx, cpu_flags);
  727.  
  728.     if (EXTERNAL_SSE4(cpu_flags))
  729.         dsputil_init_sse4(c, avctx, cpu_flags);
  730.  
  731.     if (CONFIG_ENCODERS)
  732.         ff_dsputilenc_init_mmx(c, avctx);
  733. }
  734.