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