motion_est_mmx.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:13k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * MMX optimized motion estimation
  3.  * Copyright (c) 2001 Fabrice Bellard.
  4.  * Copyright (c) 2002-2004 Michael Niedermayer
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with this library; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  *
  20.  * mostly by Michael Niedermayer <michaelni@gmx.at>
  21.  */
  22. #include "../dsputil.h"
  23. #include "mmx.h"
  24. static const __attribute__ ((aligned(8))) uint64_t round_tab[3]={
  25. 0x0000000000000000ULL,
  26. 0x0001000100010001ULL,
  27. 0x0002000200020002ULL,
  28. };
  29. static attribute_used __attribute__ ((aligned(8))) uint64_t bone= 0x0101010101010101LL;
  30. static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h)
  31. {
  32.     long len= -(stride*h);
  33.     asm volatile(
  34.         ".balign 16 nt"
  35.         "1: nt"
  36.         "movq (%1, %%"REG_a"), %%mm0 nt"
  37.         "movq (%2, %%"REG_a"), %%mm2 nt"
  38.         "movq (%2, %%"REG_a"), %%mm4 nt"
  39.         "add %3, %%"REG_a" nt"
  40.         "psubusb %%mm0, %%mm2 nt"
  41.         "psubusb %%mm4, %%mm0 nt"
  42.         "movq (%1, %%"REG_a"), %%mm1 nt"
  43.         "movq (%2, %%"REG_a"), %%mm3 nt"
  44.         "movq (%2, %%"REG_a"), %%mm5 nt"
  45.         "psubusb %%mm1, %%mm3 nt"
  46.         "psubusb %%mm5, %%mm1 nt"
  47.         "por %%mm2, %%mm0 nt"
  48.         "por %%mm1, %%mm3 nt"
  49.         "movq %%mm0, %%mm1 nt"
  50.         "movq %%mm3, %%mm2 nt"
  51.         "punpcklbw %%mm7, %%mm0 nt"
  52.         "punpckhbw %%mm7, %%mm1 nt"
  53.         "punpcklbw %%mm7, %%mm3 nt"
  54.         "punpckhbw %%mm7, %%mm2 nt"
  55.         "paddw %%mm1, %%mm0 nt"
  56.         "paddw %%mm3, %%mm2 nt"
  57.         "paddw %%mm2, %%mm0 nt"
  58.         "paddw %%mm0, %%mm6 nt"
  59.         "add %3, %%"REG_a" nt"
  60.         " js 1b nt"
  61.         : "+a" (len)
  62.         : "r" (blk1 - len), "r" (blk2 - len), "r" ((long)stride)
  63.     );
  64. }
  65. static inline void sad8_1_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h)
  66. {
  67.     long len= -(stride*h);
  68.     asm volatile(
  69.         ".balign 16 nt"
  70.         "1: nt"
  71.         "movq (%1, %%"REG_a"), %%mm0 nt"
  72.         "movq (%2, %%"REG_a"), %%mm2 nt"
  73.         "psadbw %%mm2, %%mm0 nt"
  74.         "add %3, %%"REG_a" nt"
  75.         "movq (%1, %%"REG_a"), %%mm1 nt"
  76.         "movq (%2, %%"REG_a"), %%mm3 nt"
  77.         "psadbw %%mm1, %%mm3 nt"
  78.         "paddw %%mm3, %%mm0 nt"
  79.         "paddw %%mm0, %%mm6 nt"
  80.         "add %3, %%"REG_a" nt"
  81.         " js 1b nt"
  82.         : "+a" (len)
  83.         : "r" (blk1 - len), "r" (blk2 - len), "r" ((long)stride)
  84.     );
  85. }
  86. static inline void sad8_2_mmx2(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, int stride, int h)
  87. {
  88.     long len= -(stride*h);
  89.     asm volatile(
  90.         ".balign 16 nt"
  91.         "1: nt"
  92.         "movq (%1, %%"REG_a"), %%mm0 nt"
  93.         "movq (%2, %%"REG_a"), %%mm2 nt"
  94.         "pavgb %%mm2, %%mm0 nt"
  95.         "movq (%3, %%"REG_a"), %%mm2 nt"
  96.         "psadbw %%mm2, %%mm0 nt"
  97.         "add %4, %%"REG_a" nt"
  98.         "movq (%1, %%"REG_a"), %%mm1 nt"
  99.         "movq (%2, %%"REG_a"), %%mm3 nt"
  100.         "pavgb %%mm1, %%mm3 nt"
  101.         "movq (%3, %%"REG_a"), %%mm1 nt"
  102.         "psadbw %%mm1, %%mm3 nt"
  103.         "paddw %%mm3, %%mm0 nt"
  104.         "paddw %%mm0, %%mm6 nt"
  105.         "add %4, %%"REG_a" nt"
  106.         " js 1b nt"
  107.         : "+a" (len)
  108.         : "r" (blk1a - len), "r" (blk1b -len), "r" (blk2 - len), "r" ((long)stride)
  109.     );
  110. }
  111. static inline void sad8_4_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h)
  112. { //FIXME reuse src
  113.     long len= -(stride*h);
  114.     asm volatile(
  115.         ".balign 16 nt"
  116.         "movq "MANGLE(bone)", %%mm5 nt"
  117.         "1: nt"
  118.         "movq (%1, %%"REG_a"), %%mm0 nt"
  119.         "movq (%2, %%"REG_a"), %%mm2 nt"
  120.         "movq 1(%1, %%"REG_a"), %%mm1 nt"
  121.         "movq 1(%2, %%"REG_a"), %%mm3 nt"
  122.         "pavgb %%mm2, %%mm0 nt"
  123.         "pavgb %%mm1, %%mm3 nt"
  124.         "psubusb %%mm5, %%mm3 nt"
  125.         "pavgb %%mm3, %%mm0 nt"
  126.         "movq (%3, %%"REG_a"), %%mm2 nt"
  127.         "psadbw %%mm2, %%mm0 nt"
  128.         "add %4, %%"REG_a" nt"
  129.         "movq (%1, %%"REG_a"), %%mm1 nt"
  130.         "movq (%2, %%"REG_a"), %%mm3 nt"
  131.         "movq 1(%1, %%"REG_a"), %%mm2 nt"
  132.         "movq 1(%2, %%"REG_a"), %%mm4 nt"
  133.         "pavgb %%mm3, %%mm1 nt"
  134.         "pavgb %%mm4, %%mm2 nt"
  135.         "psubusb %%mm5, %%mm2 nt"
  136.         "pavgb %%mm1, %%mm2 nt"
  137.         "movq (%3, %%"REG_a"), %%mm1 nt"
  138.         "psadbw %%mm1, %%mm2 nt"
  139.         "paddw %%mm2, %%mm0 nt"
  140.         "paddw %%mm0, %%mm6 nt"
  141.         "add %4, %%"REG_a" nt"
  142.         " js 1b nt"
  143.         : "+a" (len)
  144.         : "r" (blk1 - len), "r" (blk1 - len + stride), "r" (blk2 - len), "r" ((long)stride)
  145.     );
  146. }
  147. static inline void sad8_2_mmx(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, int stride, int h)
  148. {
  149.     long len= -(stride*h);
  150.     asm volatile(
  151.         ".balign 16 nt"
  152.         "1: nt"
  153.         "movq (%1, %%"REG_a"), %%mm0 nt"
  154.         "movq (%2, %%"REG_a"), %%mm1 nt"
  155.         "movq (%1, %%"REG_a"), %%mm2 nt"
  156.         "movq (%2, %%"REG_a"), %%mm3 nt"
  157.         "punpcklbw %%mm7, %%mm0 nt"
  158.         "punpcklbw %%mm7, %%mm1 nt"
  159.         "punpckhbw %%mm7, %%mm2 nt"
  160.         "punpckhbw %%mm7, %%mm3 nt"
  161.         "paddw %%mm0, %%mm1 nt"
  162.         "paddw %%mm2, %%mm3 nt"
  163.         "movq (%3, %%"REG_a"), %%mm4 nt"
  164.         "movq (%3, %%"REG_a"), %%mm2 nt"
  165.         "paddw %%mm5, %%mm1 nt"
  166.         "paddw %%mm5, %%mm3 nt"
  167.         "psrlw $1, %%mm1 nt"
  168.         "psrlw $1, %%mm3 nt"
  169.         "packuswb %%mm3, %%mm1 nt"
  170.         "psubusb %%mm1, %%mm4 nt"
  171.         "psubusb %%mm2, %%mm1 nt"
  172.         "por %%mm4, %%mm1 nt"
  173.         "movq %%mm1, %%mm0 nt"
  174.         "punpcklbw %%mm7, %%mm0 nt"
  175.         "punpckhbw %%mm7, %%mm1 nt"
  176.         "paddw %%mm1, %%mm0 nt"
  177.         "paddw %%mm0, %%mm6 nt"
  178.         "add %4, %%"REG_a" nt"
  179.         " js 1b nt"
  180.         : "+a" (len)
  181.         : "r" (blk1a - len), "r" (blk1b -len), "r" (blk2 - len), "r" ((long)stride)
  182.     );
  183. }
  184. static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h)
  185. {
  186.     long len= -(stride*h);
  187.     asm volatile(
  188.         ".balign 16 nt"
  189.         "1: nt"
  190.         "movq (%1, %%"REG_a"), %%mm0 nt"
  191.         "movq (%2, %%"REG_a"), %%mm1 nt"
  192.         "movq %%mm0, %%mm4 nt"
  193.         "movq %%mm1, %%mm2 nt"
  194.         "punpcklbw %%mm7, %%mm0 nt"
  195.         "punpcklbw %%mm7, %%mm1 nt"
  196.         "punpckhbw %%mm7, %%mm4 nt"
  197.         "punpckhbw %%mm7, %%mm2 nt"
  198.         "paddw %%mm1, %%mm0 nt"
  199.         "paddw %%mm2, %%mm4 nt"
  200.         "movq 1(%1, %%"REG_a"), %%mm2 nt"
  201.         "movq 1(%2, %%"REG_a"), %%mm3 nt"
  202.         "movq %%mm2, %%mm1 nt"
  203.         "punpcklbw %%mm7, %%mm2 nt"
  204.         "punpckhbw %%mm7, %%mm1 nt"
  205.         "paddw %%mm0, %%mm2 nt"
  206.         "paddw %%mm4, %%mm1 nt"
  207.         "movq %%mm3, %%mm4 nt"
  208.         "punpcklbw %%mm7, %%mm3 nt"
  209.         "punpckhbw %%mm7, %%mm4 nt"
  210.         "paddw %%mm3, %%mm2 nt"
  211.         "paddw %%mm4, %%mm1 nt"
  212.         "movq (%3, %%"REG_a"), %%mm3 nt"
  213.         "movq (%3, %%"REG_a"), %%mm4 nt"
  214.         "paddw %%mm5, %%mm2 nt"
  215.         "paddw %%mm5, %%mm1 nt"
  216.         "psrlw $2, %%mm2 nt"
  217.         "psrlw $2, %%mm1 nt"
  218.         "packuswb %%mm1, %%mm2 nt"
  219.         "psubusb %%mm2, %%mm3 nt"
  220.         "psubusb %%mm4, %%mm2 nt"
  221.         "por %%mm3, %%mm2 nt"
  222.         "movq %%mm2, %%mm0 nt"
  223.         "punpcklbw %%mm7, %%mm0 nt"
  224.         "punpckhbw %%mm7, %%mm2 nt"
  225.         "paddw %%mm2, %%mm0 nt"
  226.         "paddw %%mm0, %%mm6 nt"
  227.         "add %4, %%"REG_a" nt"
  228.         " js 1b nt"
  229.         : "+a" (len)
  230.         : "r" (blk1 - len), "r" (blk1 -len + stride), "r" (blk2 - len), "r" ((long)stride)
  231.     );
  232. }
  233. static inline int sum_mmx(void)
  234. {
  235.     int ret;
  236.     asm volatile(
  237.         "movq %%mm6, %%mm0 nt"
  238.         "psrlq $32, %%mm6 nt"
  239.         "paddw %%mm0, %%mm6 nt"
  240.         "movq %%mm6, %%mm0 nt"
  241.         "psrlq $16, %%mm6 nt"
  242.         "paddw %%mm0, %%mm6 nt"
  243.         "movd %%mm6, %0 nt"
  244.         : "=r" (ret)
  245.     );
  246.     return ret&0xFFFF;
  247. }
  248. static inline int sum_mmx2(void)
  249. {
  250.     int ret;
  251.     asm volatile(
  252.         "movd %%mm6, %0 nt"
  253.         : "=r" (ret)
  254.     );
  255.     return ret;
  256. }
  257. #define PIX_SAD(suf)
  258. static int sad8_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)
  259. {
  260.     assert(h==8);
  261.     asm volatile("pxor %%mm7, %%mm7 nt"
  262.                  "pxor %%mm6, %%mm6 nt":);
  263.     sad8_1_ ## suf(blk1, blk2, stride, 8);
  264.     return sum_ ## suf();
  265. }
  266. static int sad8_x2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)
  267. {
  268.     assert(h==8);
  269.     asm volatile("pxor %%mm7, %%mm7 nt"
  270.                  "pxor %%mm6, %%mm6 nt"
  271.                  "movq %0, %%mm5 nt"
  272.                  :: "m"(round_tab[1]) 
  273.                  );
  274.     sad8_2_ ## suf(blk1, blk1+1, blk2, stride, 8);
  275.     return sum_ ## suf();
  276. }
  277. static int sad8_y2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)
  278. {
  279.     assert(h==8);
  280.     asm volatile("pxor %%mm7, %%mm7 nt"
  281.                  "pxor %%mm6, %%mm6 nt"
  282.                  "movq %0, %%mm5 nt"
  283.                  :: "m"(round_tab[1]) 
  284.                  );
  285.     sad8_2_ ## suf(blk1, blk1+stride, blk2, stride, 8);
  286.     return sum_ ## suf();
  287. }
  288. static int sad8_xy2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)
  289. {
  290.     assert(h==8);
  291.     asm volatile("pxor %%mm7, %%mm7 nt"
  292.                  "pxor %%mm6, %%mm6 nt"
  293.                  "movq %0, %%mm5 nt"
  294.                  :: "m"(round_tab[2]) 
  295.                  );
  296.     sad8_4_ ## suf(blk1, blk2, stride, 8);
  297.     return sum_ ## suf();
  298. }
  299. static int sad16_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)
  300. {
  301.     asm volatile("pxor %%mm7, %%mm7 nt"
  302.                  "pxor %%mm6, %%mm6 nt":);
  303.     sad8_1_ ## suf(blk1  , blk2  , stride, h);
  304.     sad8_1_ ## suf(blk1+8, blk2+8, stride, h);
  305.     return sum_ ## suf();
  306. }
  307. static int sad16_x2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)
  308. {
  309.     asm volatile("pxor %%mm7, %%mm7 nt"
  310.                  "pxor %%mm6, %%mm6 nt"
  311.                  "movq %0, %%mm5 nt"
  312.                  :: "m"(round_tab[1]) 
  313.                  );
  314.     sad8_2_ ## suf(blk1  , blk1+1, blk2  , stride, h);
  315.     sad8_2_ ## suf(blk1+8, blk1+9, blk2+8, stride, h);
  316.     return sum_ ## suf();
  317. }
  318. static int sad16_y2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)
  319. {
  320.     asm volatile("pxor %%mm7, %%mm7 nt"
  321.                  "pxor %%mm6, %%mm6 nt"
  322.                  "movq %0, %%mm5 nt"
  323.                  :: "m"(round_tab[1]) 
  324.                  );
  325.     sad8_2_ ## suf(blk1  , blk1+stride,  blk2  , stride, h);
  326.     sad8_2_ ## suf(blk1+8, blk1+stride+8,blk2+8, stride, h);
  327.     return sum_ ## suf();
  328. }
  329. static int sad16_xy2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)
  330. {
  331.     asm volatile("pxor %%mm7, %%mm7 nt"
  332.                  "pxor %%mm6, %%mm6 nt"
  333.                  "movq %0, %%mm5 nt"
  334.                  :: "m"(round_tab[2]) 
  335.                  );
  336.     sad8_4_ ## suf(blk1  , blk2  , stride, h);
  337.     sad8_4_ ## suf(blk1+8, blk2+8, stride, h);
  338.     return sum_ ## suf();
  339. }
  340. PIX_SAD(mmx)
  341. PIX_SAD(mmx2)
  342. void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx)
  343. {
  344.     if (mm_flags & MM_MMX) {
  345.         c->pix_abs[0][0] = sad16_mmx;
  346.         c->pix_abs[0][1] = sad16_x2_mmx;
  347.         c->pix_abs[0][2] = sad16_y2_mmx;
  348.         c->pix_abs[0][3] = sad16_xy2_mmx;
  349.         c->pix_abs[1][0] = sad8_mmx;
  350.         c->pix_abs[1][1] = sad8_x2_mmx;
  351.         c->pix_abs[1][2] = sad8_y2_mmx;
  352.         c->pix_abs[1][3] = sad8_xy2_mmx;
  353. c->sad[0]= sad16_mmx;
  354.         c->sad[1]= sad8_mmx;
  355.     }
  356.     if (mm_flags & MM_MMXEXT) {
  357. c->pix_abs[0][0] = sad16_mmx2;
  358. c->pix_abs[1][0] = sad8_mmx2;
  359. c->sad[0]= sad16_mmx2;
  360. c->sad[1]= sad8_mmx2;
  361.         
  362.         if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
  363.             c->pix_abs[0][1] = sad16_x2_mmx2;
  364.             c->pix_abs[0][2] = sad16_y2_mmx2;
  365.             c->pix_abs[0][3] = sad16_xy2_mmx2;
  366.             c->pix_abs[1][1] = sad8_x2_mmx2;
  367.             c->pix_abs[1][2] = sad8_y2_mmx2;
  368.             c->pix_abs[1][3] = sad8_xy2_mmx2;
  369.         }
  370.     }
  371. }