Home | History | Annotate | Download | only in x86
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 
     12 #include "vpx_config.h"
     13 #include "vp8/common/loopfilter.h"
     14 
     15 #define prototype_loopfilter(sym) \
     16     void sym(unsigned char *src, int pitch, const unsigned char *blimit,\
     17              const unsigned char *limit, const unsigned char *thresh, int count)
     18 
     19 #define prototype_loopfilter_nc(sym) \
     20     void sym(unsigned char *src, int pitch, const unsigned char *blimit,\
     21              const unsigned char *limit, const unsigned char *thresh)
     22 
     23 #define prototype_simple_loopfilter(sym) \
     24     void sym(unsigned char *y, int ystride, const unsigned char *blimit)
     25 
     26 prototype_loopfilter(vp8_mbloop_filter_vertical_edge_mmx);
     27 prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_mmx);
     28 prototype_loopfilter(vp8_loop_filter_vertical_edge_mmx);
     29 prototype_loopfilter(vp8_loop_filter_horizontal_edge_mmx);
     30 prototype_simple_loopfilter(vp8_loop_filter_simple_horizontal_edge_mmx);
     31 prototype_simple_loopfilter(vp8_loop_filter_simple_vertical_edge_mmx);
     32 
     33 #if HAVE_SSE2 && ARCH_X86_64
     34 prototype_loopfilter(vp8_loop_filter_bv_y_sse2);
     35 prototype_loopfilter(vp8_loop_filter_bh_y_sse2);
     36 #else
     37 prototype_loopfilter_nc(vp8_loop_filter_vertical_edge_sse2);
     38 prototype_loopfilter_nc(vp8_loop_filter_horizontal_edge_sse2);
     39 #endif
     40 prototype_loopfilter_nc(vp8_mbloop_filter_vertical_edge_sse2);
     41 prototype_loopfilter_nc(vp8_mbloop_filter_horizontal_edge_sse2);
     42 
     43 extern loop_filter_uvfunction vp8_loop_filter_horizontal_edge_uv_sse2;
     44 extern loop_filter_uvfunction vp8_loop_filter_vertical_edge_uv_sse2;
     45 extern loop_filter_uvfunction vp8_mbloop_filter_horizontal_edge_uv_sse2;
     46 extern loop_filter_uvfunction vp8_mbloop_filter_vertical_edge_uv_sse2;
     47 
     48 #if HAVE_MMX
     49 /* Horizontal MB filtering */
     50 void vp8_loop_filter_mbh_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
     51                              int y_stride, int uv_stride, loop_filter_info *lfi)
     52 {
     53     vp8_mbloop_filter_horizontal_edge_mmx(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 2);
     54 
     55     if (u_ptr)
     56         vp8_mbloop_filter_horizontal_edge_mmx(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
     57 
     58     if (v_ptr)
     59         vp8_mbloop_filter_horizontal_edge_mmx(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
     60 }
     61 
     62 
     63 /* Vertical MB Filtering */
     64 void vp8_loop_filter_mbv_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
     65                              int y_stride, int uv_stride, loop_filter_info *lfi)
     66 {
     67     vp8_mbloop_filter_vertical_edge_mmx(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 2);
     68 
     69     if (u_ptr)
     70         vp8_mbloop_filter_vertical_edge_mmx(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
     71 
     72     if (v_ptr)
     73         vp8_mbloop_filter_vertical_edge_mmx(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
     74 }
     75 
     76 
     77 /* Horizontal B Filtering */
     78 void vp8_loop_filter_bh_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
     79                             int y_stride, int uv_stride, loop_filter_info *lfi)
     80 {
     81     vp8_loop_filter_horizontal_edge_mmx(y_ptr + 4 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
     82     vp8_loop_filter_horizontal_edge_mmx(y_ptr + 8 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
     83     vp8_loop_filter_horizontal_edge_mmx(y_ptr + 12 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
     84 
     85     if (u_ptr)
     86         vp8_loop_filter_horizontal_edge_mmx(u_ptr + 4 * uv_stride, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
     87 
     88     if (v_ptr)
     89         vp8_loop_filter_horizontal_edge_mmx(v_ptr + 4 * uv_stride, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
     90 }
     91 
     92 
     93 void vp8_loop_filter_bhs_mmx(unsigned char *y_ptr, int y_stride, const unsigned char *blimit)
     94 {
     95     vp8_loop_filter_simple_horizontal_edge_mmx(y_ptr + 4 * y_stride, y_stride, blimit);
     96     vp8_loop_filter_simple_horizontal_edge_mmx(y_ptr + 8 * y_stride, y_stride, blimit);
     97     vp8_loop_filter_simple_horizontal_edge_mmx(y_ptr + 12 * y_stride, y_stride, blimit);
     98 }
     99 
    100 
    101 /* Vertical B Filtering */
    102 void vp8_loop_filter_bv_mmx(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
    103                             int y_stride, int uv_stride, loop_filter_info *lfi)
    104 {
    105     vp8_loop_filter_vertical_edge_mmx(y_ptr + 4, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
    106     vp8_loop_filter_vertical_edge_mmx(y_ptr + 8, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
    107     vp8_loop_filter_vertical_edge_mmx(y_ptr + 12, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
    108 
    109     if (u_ptr)
    110         vp8_loop_filter_vertical_edge_mmx(u_ptr + 4, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
    111 
    112     if (v_ptr)
    113         vp8_loop_filter_vertical_edge_mmx(v_ptr + 4, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
    114 }
    115 
    116 
    117 void vp8_loop_filter_bvs_mmx(unsigned char *y_ptr, int y_stride, const unsigned char *blimit)
    118 {
    119     vp8_loop_filter_simple_vertical_edge_mmx(y_ptr + 4, y_stride, blimit);
    120     vp8_loop_filter_simple_vertical_edge_mmx(y_ptr + 8, y_stride, blimit);
    121     vp8_loop_filter_simple_vertical_edge_mmx(y_ptr + 12, y_stride, blimit);
    122 }
    123 #endif
    124 
    125 
    126 /* Horizontal MB filtering */
    127 #if HAVE_SSE2
    128 void vp8_loop_filter_mbh_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
    129                               int y_stride, int uv_stride, loop_filter_info *lfi)
    130 {
    131     vp8_mbloop_filter_horizontal_edge_sse2(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr);
    132 
    133     if (u_ptr)
    134         vp8_mbloop_filter_horizontal_edge_uv_sse2(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, v_ptr);
    135 }
    136 
    137 
    138 /* Vertical MB Filtering */
    139 void vp8_loop_filter_mbv_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
    140                               int y_stride, int uv_stride, loop_filter_info *lfi)
    141 {
    142     vp8_mbloop_filter_vertical_edge_sse2(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr);
    143 
    144     if (u_ptr)
    145         vp8_mbloop_filter_vertical_edge_uv_sse2(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, v_ptr);
    146 }
    147 
    148 
    149 /* Horizontal B Filtering */
    150 void vp8_loop_filter_bh_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
    151                              int y_stride, int uv_stride, loop_filter_info *lfi)
    152 {
    153 #if ARCH_X86_64
    154     vp8_loop_filter_bh_y_sse2(y_ptr, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
    155 #else
    156     vp8_loop_filter_horizontal_edge_sse2(y_ptr + 4 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr);
    157     vp8_loop_filter_horizontal_edge_sse2(y_ptr + 8 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr);
    158     vp8_loop_filter_horizontal_edge_sse2(y_ptr + 12 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr);
    159 #endif
    160 
    161     if (u_ptr)
    162         vp8_loop_filter_horizontal_edge_uv_sse2(u_ptr + 4 * uv_stride, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, v_ptr + 4 * uv_stride);
    163 }
    164 
    165 
    166 void vp8_loop_filter_bhs_sse2(unsigned char *y_ptr, int y_stride, const unsigned char *blimit)
    167 {
    168     vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 4 * y_stride, y_stride, blimit);
    169     vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 8 * y_stride, y_stride, blimit);
    170     vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 12 * y_stride, y_stride, blimit);
    171 }
    172 
    173 
    174 /* Vertical B Filtering */
    175 void vp8_loop_filter_bv_sse2(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
    176                              int y_stride, int uv_stride, loop_filter_info *lfi)
    177 {
    178 #if ARCH_X86_64
    179     vp8_loop_filter_bv_y_sse2(y_ptr, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
    180 #else
    181     vp8_loop_filter_vertical_edge_sse2(y_ptr + 4, y_stride, lfi->blim, lfi->lim, lfi->hev_thr);
    182     vp8_loop_filter_vertical_edge_sse2(y_ptr + 8, y_stride, lfi->blim, lfi->lim, lfi->hev_thr);
    183     vp8_loop_filter_vertical_edge_sse2(y_ptr + 12, y_stride, lfi->blim, lfi->lim, lfi->hev_thr);
    184 #endif
    185 
    186     if (u_ptr)
    187         vp8_loop_filter_vertical_edge_uv_sse2(u_ptr + 4, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, v_ptr + 4);
    188 }
    189 
    190 
    191 void vp8_loop_filter_bvs_sse2(unsigned char *y_ptr, int y_stride, const unsigned char *blimit)
    192 {
    193     vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 4, y_stride, blimit);
    194     vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 8, y_stride, blimit);
    195     vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 12, y_stride, blimit);
    196 }
    197 
    198 #endif
    199