yadif.h
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:11k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
  3.  *
  4.  * This file is part of MPlayer.
  5.  *
  6.  * MPlayer is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * MPlayer 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
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License along
  17.  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
  18.  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19.  */
  20. /* */
  21. #if defined(CAN_COMPILE_SSE2) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ > 0))
  22. #define HAVE_YADIF_SSE2
  23. #define LOAD4(mem,dst) 
  24.             "movd      "mem", "#dst" nt"
  25.             "punpcklbw %%mm7, "#dst" nt"
  26. #define PABS(tmp,dst) 
  27.             "pxor     "#tmp", "#tmp" nt"
  28.             "psubw    "#dst", "#tmp" nt"
  29.             "pmaxsw   "#tmp", "#dst" nt"
  30. #define CHECK(pj,mj) 
  31.             "movq "#pj"(%[cur],%[mrefs]), %%mm2 nt" /* cur[x-refs-1+j] */
  32.             "movq "#mj"(%[cur],%[prefs]), %%mm3 nt" /* cur[x+refs-1-j] */
  33.             "movq      %%mm2, %%mm4 nt"
  34.             "movq      %%mm2, %%mm5 nt"
  35.             "pxor      %%mm3, %%mm4 nt"
  36.             "pavgb     %%mm3, %%mm5 nt"
  37.             "pand     %[pb1], %%mm4 nt"
  38.             "psubusb   %%mm4, %%mm5 nt"
  39.             "psrlq     $8,    %%mm5 nt"
  40.             "punpcklbw %%mm7, %%mm5 nt" /* (cur[x-refs+j] + cur[x+refs-j])>>1 */
  41.             "movq      %%mm2, %%mm4 nt"
  42.             "psubusb   %%mm3, %%mm2 nt"
  43.             "psubusb   %%mm4, %%mm3 nt"
  44.             "pmaxub    %%mm3, %%mm2 nt"
  45.             "movq      %%mm2, %%mm3 nt"
  46.             "movq      %%mm2, %%mm4 nt" /* ABS(cur[x-refs-1+j] - cur[x+refs-1-j]) */
  47.             "psrlq      $8,   %%mm3 nt" /* ABS(cur[x-refs  +j] - cur[x+refs  -j]) */
  48.             "psrlq     $16,   %%mm4 nt" /* ABS(cur[x-refs+1+j] - cur[x+refs+1-j]) */
  49.             "punpcklbw %%mm7, %%mm2 nt"
  50.             "punpcklbw %%mm7, %%mm3 nt"
  51.             "punpcklbw %%mm7, %%mm4 nt"
  52.             "paddw     %%mm3, %%mm2 nt"
  53.             "paddw     %%mm4, %%mm2 nt" /* score */
  54. #define CHECK1 
  55.             "movq      %%mm0, %%mm3 nt"
  56.             "pcmpgtw   %%mm2, %%mm3 nt" /* if(score < spatial_score) */
  57.             "pminsw    %%mm2, %%mm0 nt" /* spatial_score= score; */
  58.             "movq      %%mm3, %%mm6 nt"
  59.             "pand      %%mm3, %%mm5 nt"
  60.             "pandn     %%mm1, %%mm3 nt"
  61.             "por       %%mm5, %%mm3 nt"
  62.             "movq      %%mm3, %%mm1 nt" /* spatial_pred= (cur[x-refs+j] + cur[x+refs-j])>>1; */
  63. #define CHECK2 /* pretend not to have checked dir=2 if dir=1 was bad.
  64.                   hurts both quality and speed, but matches the C version. */
  65.             "paddw    %[pw1], %%mm6 nt"
  66.             "psllw     $14,   %%mm6 nt"
  67.             "paddsw    %%mm6, %%mm2 nt"
  68.             "movq      %%mm0, %%mm3 nt"
  69.             "pcmpgtw   %%mm2, %%mm3 nt"
  70.             "pminsw    %%mm2, %%mm0 nt"
  71.             "pand      %%mm3, %%mm5 nt"
  72.             "pandn     %%mm1, %%mm3 nt"
  73.             "por       %%mm5, %%mm3 nt"
  74.             "movq      %%mm3, %%mm1 nt"
  75. static void yadif_filter_line_mmx2(struct vf_priv_s *p, uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int refs, int parity){
  76.     static const uint64_t pw_1 = 0x0001000100010001ULL;
  77.     static const uint64_t pb_1 = 0x0101010101010101ULL;
  78.     const int mode = p->mode;
  79.     uint64_t tmp0, tmp1, tmp2, tmp3;
  80.     int x;
  81. #define FILTER
  82.     for(x=0; x<w; x+=4){
  83.         __asm__ volatile(
  84.             "pxor      %%mm7, %%mm7 nt"
  85.             LOAD4("(%[cur],%[mrefs])", %%mm0) /* c = cur[x-refs] */
  86.             LOAD4("(%[cur],%[prefs])", %%mm1) /* e = cur[x+refs] */
  87.             LOAD4("(%["prev2"])", %%mm2) /* prev2[x] */
  88.             LOAD4("(%["next2"])", %%mm3) /* next2[x] */
  89.             "movq      %%mm3, %%mm4 nt"
  90.             "paddw     %%mm2, %%mm3 nt"
  91.             "psraw     $1,    %%mm3 nt" /* d = (prev2[x] + next2[x])>>1 */
  92.             "movq      %%mm0, %[tmp0] nt" /* c */
  93.             "movq      %%mm3, %[tmp1] nt" /* d */
  94.             "movq      %%mm1, %[tmp2] nt" /* e */
  95.             "psubw     %%mm4, %%mm2 nt"
  96.             PABS(      %%mm4, %%mm2) /* temporal_diff0 */
  97.             LOAD4("(%[prev],%[mrefs])", %%mm3) /* prev[x-refs] */
  98.             LOAD4("(%[prev],%[prefs])", %%mm4) /* prev[x+refs] */
  99.             "psubw     %%mm0, %%mm3 nt"
  100.             "psubw     %%mm1, %%mm4 nt"
  101.             PABS(      %%mm5, %%mm3)
  102.             PABS(      %%mm5, %%mm4)
  103.             "paddw     %%mm4, %%mm3 nt" /* temporal_diff1 */
  104.             "psrlw     $1,    %%mm2 nt"
  105.             "psrlw     $1,    %%mm3 nt"
  106.             "pmaxsw    %%mm3, %%mm2 nt"
  107.             LOAD4("(%[next],%[mrefs])", %%mm3) /* next[x-refs] */
  108.             LOAD4("(%[next],%[prefs])", %%mm4) /* next[x+refs] */
  109.             "psubw     %%mm0, %%mm3 nt"
  110.             "psubw     %%mm1, %%mm4 nt"
  111.             PABS(      %%mm5, %%mm3)
  112.             PABS(      %%mm5, %%mm4)
  113.             "paddw     %%mm4, %%mm3 nt" /* temporal_diff2 */
  114.             "psrlw     $1,    %%mm3 nt"
  115.             "pmaxsw    %%mm3, %%mm2 nt"
  116.             "movq      %%mm2, %[tmp3] nt" /* diff */
  117.             "paddw     %%mm0, %%mm1 nt"
  118.             "paddw     %%mm0, %%mm0 nt"
  119.             "psubw     %%mm1, %%mm0 nt"
  120.             "psrlw     $1,    %%mm1 nt" /* spatial_pred */
  121.             PABS(      %%mm2, %%mm0)      /* ABS(c-e) */
  122.             "movq -1(%[cur],%[mrefs]), %%mm2 nt" /* cur[x-refs-1] */
  123.             "movq -1(%[cur],%[prefs]), %%mm3 nt" /* cur[x+refs-1] */
  124.             "movq      %%mm2, %%mm4 nt"
  125.             "psubusb   %%mm3, %%mm2 nt"
  126.             "psubusb   %%mm4, %%mm3 nt"
  127.             "pmaxub    %%mm3, %%mm2 nt"
  128.             "pshufw $9,%%mm2, %%mm3 nt"
  129.             "punpcklbw %%mm7, %%mm2 nt" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */
  130.             "punpcklbw %%mm7, %%mm3 nt" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */
  131.             "paddw     %%mm2, %%mm0 nt"
  132.             "paddw     %%mm3, %%mm0 nt"
  133.             "psubw    %[pw1], %%mm0 nt" /* spatial_score */
  134.             CHECK(-2,0)
  135.             CHECK1
  136.             CHECK(-3,1)
  137.             CHECK2
  138.             CHECK(0,-2)
  139.             CHECK1
  140.             CHECK(1,-3)
  141.             CHECK2
  142.             /* if(p->mode<2) ... */
  143.             "movq    %[tmp3], %%mm6 nt" /* diff */
  144.             "cmp       $2, %[mode] nt"
  145.             "jge       1f nt"
  146.             LOAD4("(%["prev2"],%[mrefs],2)", %%mm2) /* prev2[x-2*refs] */
  147.             LOAD4("(%["next2"],%[mrefs],2)", %%mm4) /* next2[x-2*refs] */
  148.             LOAD4("(%["prev2"],%[prefs],2)", %%mm3) /* prev2[x+2*refs] */
  149.             LOAD4("(%["next2"],%[prefs],2)", %%mm5) /* next2[x+2*refs] */
  150.             "paddw     %%mm4, %%mm2 nt"
  151.             "paddw     %%mm5, %%mm3 nt"
  152.             "psrlw     $1,    %%mm2 nt" /* b */
  153.             "psrlw     $1,    %%mm3 nt" /* f */
  154.             "movq    %[tmp0], %%mm4 nt" /* c */
  155.             "movq    %[tmp1], %%mm5 nt" /* d */
  156.             "movq    %[tmp2], %%mm7 nt" /* e */
  157.             "psubw     %%mm4, %%mm2 nt" /* b-c */
  158.             "psubw     %%mm7, %%mm3 nt" /* f-e */
  159.             "movq      %%mm5, %%mm0 nt"
  160.             "psubw     %%mm4, %%mm5 nt" /* d-c */
  161.             "psubw     %%mm7, %%mm0 nt" /* d-e */
  162.             "movq      %%mm2, %%mm4 nt"
  163.             "pminsw    %%mm3, %%mm2 nt"
  164.             "pmaxsw    %%mm4, %%mm3 nt"
  165.             "pmaxsw    %%mm5, %%mm2 nt"
  166.             "pminsw    %%mm5, %%mm3 nt"
  167.             "pmaxsw    %%mm0, %%mm2 nt" /* max */
  168.             "pminsw    %%mm0, %%mm3 nt" /* min */
  169.             "pxor      %%mm4, %%mm4 nt"
  170.             "pmaxsw    %%mm3, %%mm6 nt"
  171.             "psubw     %%mm2, %%mm4 nt" /* -max */
  172.             "pmaxsw    %%mm4, %%mm6 nt" /* diff= MAX3(diff, min, -max); */
  173.             "1: nt"
  174.             "movq    %[tmp1], %%mm2 nt" /* d */
  175.             "movq      %%mm2, %%mm3 nt"
  176.             "psubw     %%mm6, %%mm2 nt" /* d-diff */
  177.             "paddw     %%mm6, %%mm3 nt" /* d+diff */
  178.             "pmaxsw    %%mm2, %%mm1 nt"
  179.             "pminsw    %%mm3, %%mm1 nt" /* d = clip(spatial_pred, d-diff, d+diff); */
  180.             "packuswb  %%mm1, %%mm1 nt"
  181.             :[tmp0]"=m"(tmp0),
  182.              [tmp1]"=m"(tmp1),
  183.              [tmp2]"=m"(tmp2),
  184.              [tmp3]"=m"(tmp3)
  185.             :[prev] "r"(prev),
  186.              [cur]  "r"(cur),
  187.              [next] "r"(next),
  188.              [prefs]"r"((x86_reg)refs),
  189.              [mrefs]"r"((x86_reg)-refs),
  190.              [pw1]  "m"(pw_1),
  191.              [pb1]  "m"(pb_1),
  192.              [mode] "g"(mode)
  193.         );
  194.         __asm__ volatile("movd %%mm1, %0" :"=m"(*dst));
  195.         dst += 4;
  196.         prev+= 4;
  197.         cur += 4;
  198.         next+= 4;
  199.     }
  200.     if(parity){
  201. #define prev2 "prev"
  202. #define next2 "cur"
  203.         FILTER
  204. #undef prev2
  205. #undef next2
  206.     }else{
  207. #define prev2 "cur"
  208. #define next2 "next"
  209.         FILTER
  210. #undef prev2
  211. #undef next2
  212.     }
  213. }
  214. #undef LOAD4
  215. #undef PABS
  216. #undef CHECK
  217. #undef CHECK1
  218. #undef CHECK2
  219. #undef FILTER
  220. #endif
  221. static void yadif_filter_line_c(struct vf_priv_s *p, uint8_t *dst, uint8_t *prev, uint8_t *cur, uint8_t *next, int w, int refs, int parity){
  222.     int x;
  223.     uint8_t *prev2= parity ? prev : cur ;
  224.     uint8_t *next2= parity ? cur  : next;
  225.     for(x=0; x<w; x++){
  226.         int c= cur[-refs];
  227.         int d= (prev2[0] + next2[0])>>1;
  228.         int e= cur[+refs];
  229.         int temporal_diff0= FFABS(prev2[0] - next2[0]);
  230.         int temporal_diff1=( FFABS(prev[-refs] - c) + FFABS(prev[+refs] - e) )>>1;
  231.         int temporal_diff2=( FFABS(next[-refs] - c) + FFABS(next[+refs] - e) )>>1;
  232.         int diff= FFMAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
  233.         int spatial_pred= (c+e)>>1;
  234.         int spatial_score= FFABS(cur[-refs-1] - cur[+refs-1]) + FFABS(c-e)
  235.                          + FFABS(cur[-refs+1] - cur[+refs+1]) - 1;
  236. #define CHECK(j)
  237.     {   int score= FFABS(cur[-refs-1+j] - cur[+refs-1-j])
  238.                  + FFABS(cur[-refs  +j] - cur[+refs  -j])
  239.                  + FFABS(cur[-refs+1+j] - cur[+refs+1-j]);
  240.         if(score < spatial_score){
  241.             spatial_score= score;
  242.             spatial_pred= (cur[-refs  +j] + cur[+refs  -j])>>1;
  243.         CHECK(-1) CHECK(-2) }} }}
  244.         CHECK( 1) CHECK( 2) }} }}
  245.         if(p->mode<2){
  246.             int b= (prev2[-2*refs] + next2[-2*refs])>>1;
  247.             int f= (prev2[+2*refs] + next2[+2*refs])>>1;
  248. #if 0
  249.             int a= cur[-3*refs];
  250.             int g= cur[+3*refs];
  251.             int max= FFMAX3(d-e, d-c, FFMIN3(FFMAX(b-c,f-e),FFMAX(b-c,b-a),FFMAX(f-g,f-e)) );
  252.             int min= FFMIN3(d-e, d-c, FFMAX3(FFMIN(b-c,f-e),FFMIN(b-c,b-a),FFMIN(f-g,f-e)) );
  253. #else
  254.             int max= FFMAX3(d-e, d-c, FFMIN(b-c, f-e));
  255.             int min= FFMIN3(d-e, d-c, FFMAX(b-c, f-e));
  256. #endif
  257.             diff= FFMAX3(diff, min, -max);
  258.         }
  259.         if(spatial_pred > d + diff)
  260.            spatial_pred = d + diff;
  261.         else if(spatial_pred < d - diff)
  262.            spatial_pred = d - diff;
  263.         dst[0] = spatial_pred;
  264.         dst++;
  265.         cur++;
  266.         prev++;
  267.         next++;
  268.         prev2++;
  269.         next2++;
  270.     }
  271. }