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

Windows CE

开发平台:

C/C++

  1. /*
  2.  * Alpha optimized DSP utils
  3.  * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #include "asm.h"
  20. #include "../dsputil.h"
  21. void get_pixels_mvi(DCTELEM *restrict block,
  22.                     const uint8_t *restrict pixels, int line_size)
  23. {
  24.     int h = 8;
  25.     do {
  26.         uint64_t p;
  27.         p = ldq(pixels);
  28.         stq(unpkbw(p),       block);
  29.         stq(unpkbw(p >> 32), block + 4); 
  30.         pixels += line_size;
  31.         block += 8;
  32.     } while (--h);
  33. }
  34. void diff_pixels_mvi(DCTELEM *block, const uint8_t *s1, const uint8_t *s2,
  35.                      int stride) {
  36.     int h = 8;
  37.     uint64_t mask = 0x4040;
  38.     mask |= mask << 16;
  39.     mask |= mask << 32;
  40.     do {
  41.         uint64_t x, y, c, d, a;
  42.         uint64_t signs;
  43.         x = ldq(s1);
  44.         y = ldq(s2);
  45.         c = cmpbge(x, y);
  46.         d = x - y;
  47.         a = zap(mask, c);       /* We use 0x4040404040404040 here...  */
  48.         d += 4 * a;             /* ...so we can use s4addq here.      */
  49.         signs = zap(-1, c);
  50.         stq(unpkbw(d)       | (unpkbw(signs)       << 8), block);
  51.         stq(unpkbw(d >> 32) | (unpkbw(signs >> 32) << 8), block + 4);
  52.         s1 += stride;
  53.         s2 += stride;
  54.         block += 8;
  55.     } while (--h);
  56. }
  57. static inline uint64_t avg2(uint64_t a, uint64_t b)
  58. {
  59.     return (a | b) - (((a ^ b) & BYTE_VEC(0xfe)) >> 1);
  60. }
  61. static inline uint64_t avg4(uint64_t l1, uint64_t l2, uint64_t l3, uint64_t l4)
  62. {
  63.     uint64_t r1 = ((l1 & ~BYTE_VEC(0x03)) >> 2)
  64.                 + ((l2 & ~BYTE_VEC(0x03)) >> 2)
  65.                 + ((l3 & ~BYTE_VEC(0x03)) >> 2)
  66.                 + ((l4 & ~BYTE_VEC(0x03)) >> 2);
  67.     uint64_t r2 = ((  (l1 & BYTE_VEC(0x03))
  68.                     + (l2 & BYTE_VEC(0x03))
  69.                     + (l3 & BYTE_VEC(0x03))
  70.                     + (l4 & BYTE_VEC(0x03))
  71.                     + BYTE_VEC(0x02)) >> 2) & BYTE_VEC(0x03);
  72.     return r1 + r2;
  73. }
  74. int pix_abs8x8_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
  75. {
  76.     int result = 0;
  77.     if ((size_t) pix2 & 0x7) {
  78.         /* works only when pix2 is actually unaligned */
  79.         do {                    /* do 8 pixel a time */
  80.             uint64_t p1, p2;
  81.             p1  = ldq(pix1);
  82.             p2  = uldq(pix2);
  83.             result += perr(p1, p2);
  84.             pix1 += line_size;
  85.             pix2 += line_size;
  86.         } while (--h);
  87.     } else {
  88.         do {
  89.             uint64_t p1, p2;
  90.             p1 = ldq(pix1);
  91.             p2 = ldq(pix2);
  92.             result += perr(p1, p2);
  93.             pix1 += line_size;
  94.             pix2 += line_size;
  95.         } while (--h);
  96.     }
  97.     return result;
  98. }
  99. #if 0 /* now done in assembly */
  100. int pix_abs16x16_mvi(uint8_t *pix1, uint8_t *pix2, int line_size)
  101. {
  102.     int result = 0;
  103.     int h = 16;
  104.     if ((size_t) pix2 & 0x7) {
  105.         /* works only when pix2 is actually unaligned */
  106.         do {                    /* do 16 pixel a time */
  107.             uint64_t p1_l, p1_r, p2_l, p2_r;
  108.             uint64_t t;
  109.             p1_l  = ldq(pix1);
  110.             p1_r  = ldq(pix1 + 8);
  111.             t     = ldq_u(pix2 + 8);
  112.             p2_l  = extql(ldq_u(pix2), pix2) | extqh(t, pix2);
  113.             p2_r  = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2);
  114.             pix1 += line_size;
  115.             pix2 += line_size;
  116.             result += perr(p1_l, p2_l)
  117.                     + perr(p1_r, p2_r);
  118.         } while (--h);
  119.     } else {
  120.         do {
  121.             uint64_t p1_l, p1_r, p2_l, p2_r;
  122.             p1_l = ldq(pix1);
  123.             p1_r = ldq(pix1 + 8);
  124.             p2_l = ldq(pix2);
  125.             p2_r = ldq(pix2 + 8);
  126.             pix1 += line_size;
  127.             pix2 += line_size;
  128.             result += perr(p1_l, p2_l)
  129.                     + perr(p1_r, p2_r);
  130.         } while (--h);
  131.     }
  132.     return result;
  133. }
  134. #endif
  135. int pix_abs16x16_x2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
  136. {
  137.     int result = 0;
  138.     uint64_t disalign = (size_t) pix2 & 0x7;
  139.     switch (disalign) {
  140.     case 0:
  141.         do {
  142.             uint64_t p1_l, p1_r, p2_l, p2_r;
  143.             uint64_t l, r;
  144.             p1_l = ldq(pix1);
  145.             p1_r = ldq(pix1 + 8);
  146.             l    = ldq(pix2);
  147.             r    = ldq(pix2 + 8);
  148.             p2_l = avg2(l, (l >> 8) | ((uint64_t) r << 56));
  149.             p2_r = avg2(r, (r >> 8) | ((uint64_t) pix2[16] << 56));
  150.             pix1 += line_size;
  151.             pix2 += line_size;
  152.             result += perr(p1_l, p2_l)
  153.                     + perr(p1_r, p2_r);
  154.         } while (--h);
  155.         break;
  156.     case 7:
  157.         /* |.......l|lllllllr|rrrrrrr*|
  158.            This case is special because disalign1 would be 8, which
  159.            gets treated as 0 by extqh.  At least it is a bit faster
  160.            that way :)  */   
  161.         do {
  162.             uint64_t p1_l, p1_r, p2_l, p2_r;
  163.             uint64_t l, m, r;
  164.             p1_l = ldq(pix1);
  165.             p1_r = ldq(pix1 + 8);
  166.             l     = ldq_u(pix2);
  167.             m     = ldq_u(pix2 + 8);
  168.             r     = ldq_u(pix2 + 16);
  169.             p2_l  = avg2(extql(l, disalign) | extqh(m, disalign), m);
  170.             p2_r  = avg2(extql(m, disalign) | extqh(r, disalign), r);
  171.             pix1 += line_size;
  172.             pix2 += line_size;
  173.             
  174.             result += perr(p1_l, p2_l)
  175.                     + perr(p1_r, p2_r);
  176.         } while (--h);
  177.         break;
  178.     default:
  179.         do {
  180.             uint64_t disalign1 = disalign + 1;
  181.             uint64_t p1_l, p1_r, p2_l, p2_r;
  182.             uint64_t l, m, r;
  183.             p1_l  = ldq(pix1);
  184.             p1_r  = ldq(pix1 + 8);
  185.             l     = ldq_u(pix2);
  186.             m     = ldq_u(pix2 + 8);
  187.             r     = ldq_u(pix2 + 16);
  188.             p2_l  = avg2(extql(l, disalign) | extqh(m, disalign),
  189.                          extql(l, disalign1) | extqh(m, disalign1));
  190.             p2_r  = avg2(extql(m, disalign) | extqh(r, disalign),
  191.                          extql(m, disalign1) | extqh(r, disalign1));
  192.             pix1 += line_size;
  193.             pix2 += line_size;
  194.             result += perr(p1_l, p2_l)
  195.                     + perr(p1_r, p2_r);
  196.         } while (--h);
  197.         break;
  198.     }
  199.     return result;
  200. }
  201. int pix_abs16x16_y2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
  202. {
  203.     int result = 0;
  204.     if ((size_t) pix2 & 0x7) {
  205.         uint64_t t, p2_l, p2_r;
  206.         t     = ldq_u(pix2 + 8);
  207.         p2_l  = extql(ldq_u(pix2), pix2) | extqh(t, pix2);
  208.         p2_r  = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2);
  209.         do {
  210.             uint64_t p1_l, p1_r, np2_l, np2_r;
  211.             uint64_t t;
  212.             p1_l  = ldq(pix1);
  213.             p1_r  = ldq(pix1 + 8);
  214.             pix2 += line_size;
  215.             t     = ldq_u(pix2 + 8);
  216.             np2_l = extql(ldq_u(pix2), pix2) | extqh(t, pix2);
  217.             np2_r = extql(t, pix2) | extqh(ldq_u(pix2 + 16), pix2);
  218.             result += perr(p1_l, avg2(p2_l, np2_l))
  219.                     + perr(p1_r, avg2(p2_r, np2_r));
  220.             pix1 += line_size;
  221.             p2_l  = np2_l;
  222.             p2_r  = np2_r;
  223.         } while (--h);
  224.     } else {
  225.         uint64_t p2_l, p2_r;
  226.         p2_l = ldq(pix2);
  227.         p2_r = ldq(pix2 + 8);
  228.         do {
  229.             uint64_t p1_l, p1_r, np2_l, np2_r;
  230.             p1_l = ldq(pix1);
  231.             p1_r = ldq(pix1 + 8);
  232.             pix2 += line_size;
  233.             np2_l = ldq(pix2);
  234.             np2_r = ldq(pix2 + 8);
  235.             result += perr(p1_l, avg2(p2_l, np2_l))
  236.                     + perr(p1_r, avg2(p2_r, np2_r));
  237.             pix1 += line_size;
  238.             p2_l  = np2_l;
  239.             p2_r  = np2_r;
  240.         } while (--h);
  241.     }
  242.     return result;
  243. }
  244. int pix_abs16x16_xy2_mvi(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h)
  245. {
  246.     int result = 0;
  247.     
  248.     uint64_t p1_l, p1_r;
  249.     uint64_t p2_l, p2_r, p2_x;
  250.     p1_l = ldq(pix1);
  251.     p1_r = ldq(pix1 + 8);
  252.     if ((size_t) pix2 & 0x7) { /* could be optimized a lot */
  253.         p2_l = uldq(pix2);
  254.         p2_r = uldq(pix2 + 8);
  255.         p2_x = (uint64_t) pix2[16] << 56;
  256.     } else {
  257.         p2_l = ldq(pix2);
  258.         p2_r = ldq(pix2 + 8);
  259.         p2_x = ldq(pix2 + 16) << 56;
  260.     }
  261.     do {
  262.         uint64_t np1_l, np1_r;
  263.         uint64_t np2_l, np2_r, np2_x;
  264.         pix1 += line_size;
  265.         pix2 += line_size;
  266.         np1_l = ldq(pix1);
  267.         np1_r = ldq(pix1 + 8);
  268.         if ((size_t) pix2 & 0x7) { /* could be optimized a lot */
  269.             np2_l = uldq(pix2);
  270.             np2_r = uldq(pix2 + 8);
  271.             np2_x = (uint64_t) pix2[16] << 56;
  272.         } else {
  273.             np2_l = ldq(pix2);
  274.             np2_r = ldq(pix2 + 8);
  275.             np2_x = ldq(pix2 + 16) << 56;
  276.         }
  277.         result += perr(p1_l,
  278.                        avg4( p2_l, ( p2_l >> 8) | ((uint64_t)  p2_r << 56),
  279.                             np2_l, (np2_l >> 8) | ((uint64_t) np2_r << 56)))
  280.                 + perr(p1_r,
  281.                        avg4( p2_r, ( p2_r >> 8) | ((uint64_t)  p2_x),
  282.                             np2_r, (np2_r >> 8) | ((uint64_t) np2_x)));
  283.         p1_l = np1_l;
  284.         p1_r = np1_r;
  285.         p2_l = np2_l;
  286.         p2_r = np2_r;
  287.         p2_x = np2_x;
  288.     } while (--h);
  289.     return result;
  290. }