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#include "vpx_config.h"
12#include "vp8/common/loopfilter.h"
13
14#define prototype_loopfilter(sym)                                      \
15  void sym(unsigned char *src, int pitch, const unsigned char *blimit, \
16           const unsigned char *limit, const unsigned char *thresh, int count)
17
18#define prototype_loopfilter_nc(sym)                                   \
19  void sym(unsigned char *src, int pitch, const unsigned char *blimit, \
20           const unsigned char *limit, const unsigned char *thresh)
21
22#define prototype_simple_loopfilter(sym) \
23  void sym(unsigned char *y, int ystride, const unsigned char *blimit)
24
25#if HAVE_SSE2 && ARCH_X86_64
26prototype_loopfilter(vp8_loop_filter_bv_y_sse2);
27prototype_loopfilter(vp8_loop_filter_bh_y_sse2);
28#else
29prototype_loopfilter_nc(vp8_loop_filter_vertical_edge_sse2);
30prototype_loopfilter_nc(vp8_loop_filter_horizontal_edge_sse2);
31#endif
32prototype_loopfilter_nc(vp8_mbloop_filter_vertical_edge_sse2);
33prototype_loopfilter_nc(vp8_mbloop_filter_horizontal_edge_sse2);
34
35extern loop_filter_uvfunction vp8_loop_filter_horizontal_edge_uv_sse2;
36extern loop_filter_uvfunction vp8_loop_filter_vertical_edge_uv_sse2;
37extern loop_filter_uvfunction vp8_mbloop_filter_horizontal_edge_uv_sse2;
38extern loop_filter_uvfunction vp8_mbloop_filter_vertical_edge_uv_sse2;
39
40/* Horizontal MB filtering */
41#if HAVE_SSE2
42void vp8_loop_filter_mbh_sse2(unsigned char *y_ptr, unsigned char *u_ptr,
43                              unsigned char *v_ptr, int y_stride, int uv_stride,
44                              loop_filter_info *lfi) {
45  vp8_mbloop_filter_horizontal_edge_sse2(y_ptr, y_stride, lfi->mblim, lfi->lim,
46                                         lfi->hev_thr);
47
48  if (u_ptr) {
49    vp8_mbloop_filter_horizontal_edge_uv_sse2(u_ptr, uv_stride, lfi->mblim,
50                                              lfi->lim, lfi->hev_thr, v_ptr);
51  }
52}
53
54/* Vertical MB Filtering */
55void vp8_loop_filter_mbv_sse2(unsigned char *y_ptr, unsigned char *u_ptr,
56                              unsigned char *v_ptr, int y_stride, int uv_stride,
57                              loop_filter_info *lfi) {
58  vp8_mbloop_filter_vertical_edge_sse2(y_ptr, y_stride, lfi->mblim, lfi->lim,
59                                       lfi->hev_thr);
60
61  if (u_ptr) {
62    vp8_mbloop_filter_vertical_edge_uv_sse2(u_ptr, uv_stride, lfi->mblim,
63                                            lfi->lim, lfi->hev_thr, v_ptr);
64  }
65}
66
67/* Horizontal B Filtering */
68void vp8_loop_filter_bh_sse2(unsigned char *y_ptr, unsigned char *u_ptr,
69                             unsigned char *v_ptr, int y_stride, int uv_stride,
70                             loop_filter_info *lfi) {
71#if ARCH_X86_64
72  vp8_loop_filter_bh_y_sse2(y_ptr, y_stride, lfi->blim, lfi->lim, lfi->hev_thr,
73                            2);
74#else
75  vp8_loop_filter_horizontal_edge_sse2(y_ptr + 4 * y_stride, y_stride,
76                                       lfi->blim, lfi->lim, lfi->hev_thr);
77  vp8_loop_filter_horizontal_edge_sse2(y_ptr + 8 * y_stride, y_stride,
78                                       lfi->blim, lfi->lim, lfi->hev_thr);
79  vp8_loop_filter_horizontal_edge_sse2(y_ptr + 12 * y_stride, y_stride,
80                                       lfi->blim, lfi->lim, lfi->hev_thr);
81#endif
82
83  if (u_ptr) {
84    vp8_loop_filter_horizontal_edge_uv_sse2(u_ptr + 4 * uv_stride, uv_stride,
85                                            lfi->blim, lfi->lim, lfi->hev_thr,
86                                            v_ptr + 4 * uv_stride);
87  }
88}
89
90void vp8_loop_filter_bhs_sse2(unsigned char *y_ptr, int y_stride,
91                              const unsigned char *blimit) {
92  vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 4 * y_stride, y_stride,
93                                              blimit);
94  vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 8 * y_stride, y_stride,
95                                              blimit);
96  vp8_loop_filter_simple_horizontal_edge_sse2(y_ptr + 12 * y_stride, y_stride,
97                                              blimit);
98}
99
100/* Vertical B Filtering */
101void vp8_loop_filter_bv_sse2(unsigned char *y_ptr, unsigned char *u_ptr,
102                             unsigned char *v_ptr, int y_stride, int uv_stride,
103                             loop_filter_info *lfi) {
104#if ARCH_X86_64
105  vp8_loop_filter_bv_y_sse2(y_ptr, y_stride, lfi->blim, lfi->lim, lfi->hev_thr,
106                            2);
107#else
108  vp8_loop_filter_vertical_edge_sse2(y_ptr + 4, y_stride, lfi->blim, lfi->lim,
109                                     lfi->hev_thr);
110  vp8_loop_filter_vertical_edge_sse2(y_ptr + 8, y_stride, lfi->blim, lfi->lim,
111                                     lfi->hev_thr);
112  vp8_loop_filter_vertical_edge_sse2(y_ptr + 12, y_stride, lfi->blim, lfi->lim,
113                                     lfi->hev_thr);
114#endif
115
116  if (u_ptr) {
117    vp8_loop_filter_vertical_edge_uv_sse2(u_ptr + 4, uv_stride, lfi->blim,
118                                          lfi->lim, lfi->hev_thr, v_ptr + 4);
119  }
120}
121
122void vp8_loop_filter_bvs_sse2(unsigned char *y_ptr, int y_stride,
123                              const unsigned char *blimit) {
124  vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 4, y_stride, blimit);
125  vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 8, y_stride, blimit);
126  vp8_loop_filter_simple_vertical_edge_sse2(y_ptr + 12, y_stride, blimit);
127}
128
129#endif
130