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 */
vp8_loop_filter_mbh_mmx(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi)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 */
vp8_loop_filter_mbv_mmx(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi)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 */
vp8_loop_filter_bh_mmx(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi)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 
vp8_loop_filter_bhs_mmx(unsigned char * y_ptr,int y_stride,const unsigned char * blimit)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 */
vp8_loop_filter_bv_mmx(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi)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 
vp8_loop_filter_bvs_mmx(unsigned char * y_ptr,int y_stride,const unsigned char * blimit)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
vp8_loop_filter_mbh_sse2(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi)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 */
vp8_loop_filter_mbv_sse2(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi)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 */
vp8_loop_filter_bh_sse2(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi)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 
vp8_loop_filter_bhs_sse2(unsigned char * y_ptr,int y_stride,const unsigned char * blimit)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 */
vp8_loop_filter_bv_sse2(unsigned char * y_ptr,unsigned char * u_ptr,unsigned char * v_ptr,int y_stride,int uv_stride,loop_filter_info * lfi)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 
vp8_loop_filter_bvs_sse2(unsigned char * y_ptr,int y_stride,const unsigned char * blimit)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