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_rtcd.h"
14#include "vp8/common/loopfilter.h"
15#include "vp8/common/onyxc_int.h"
16
17#define prototype_loopfilter(sym) \
18    void sym(unsigned char *src, int pitch, const unsigned char *blimit,\
19             const unsigned char *limit, const unsigned char *thresh, int count)
20
21#if HAVE_MEDIA
22extern prototype_loopfilter(vp8_loop_filter_horizontal_edge_armv6);
23extern prototype_loopfilter(vp8_loop_filter_vertical_edge_armv6);
24extern prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_armv6);
25extern prototype_loopfilter(vp8_mbloop_filter_vertical_edge_armv6);
26#endif
27
28#if HAVE_NEON
29typedef void loopfilter_y_neon(unsigned char *src, int pitch,
30        unsigned char blimit, unsigned char limit, unsigned char thresh);
31typedef void loopfilter_uv_neon(unsigned char *u, int pitch,
32        unsigned char blimit, unsigned char limit, unsigned char thresh,
33        unsigned char *v);
34
35extern loopfilter_y_neon vp8_loop_filter_horizontal_edge_y_neon;
36extern loopfilter_y_neon vp8_loop_filter_vertical_edge_y_neon;
37extern loopfilter_y_neon vp8_mbloop_filter_horizontal_edge_y_neon;
38extern loopfilter_y_neon vp8_mbloop_filter_vertical_edge_y_neon;
39
40extern loopfilter_uv_neon vp8_loop_filter_horizontal_edge_uv_neon;
41extern loopfilter_uv_neon vp8_loop_filter_vertical_edge_uv_neon;
42extern loopfilter_uv_neon vp8_mbloop_filter_horizontal_edge_uv_neon;
43extern loopfilter_uv_neon vp8_mbloop_filter_vertical_edge_uv_neon;
44#endif
45
46#if HAVE_MEDIA
47/* ARMV6/MEDIA loopfilter functions*/
48/* Horizontal MB filtering */
49void vp8_loop_filter_mbh_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
50                               int y_stride, int uv_stride, loop_filter_info *lfi)
51{
52    vp8_mbloop_filter_horizontal_edge_armv6(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 2);
53
54    if (u_ptr)
55        vp8_mbloop_filter_horizontal_edge_armv6(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
56
57    if (v_ptr)
58        vp8_mbloop_filter_horizontal_edge_armv6(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
59}
60
61/* Vertical MB Filtering */
62void vp8_loop_filter_mbv_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
63                               int y_stride, int uv_stride, loop_filter_info *lfi)
64{
65    vp8_mbloop_filter_vertical_edge_armv6(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 2);
66
67    if (u_ptr)
68        vp8_mbloop_filter_vertical_edge_armv6(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
69
70    if (v_ptr)
71        vp8_mbloop_filter_vertical_edge_armv6(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1);
72}
73
74/* Horizontal B Filtering */
75void vp8_loop_filter_bh_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
76                              int y_stride, int uv_stride, loop_filter_info *lfi)
77{
78    vp8_loop_filter_horizontal_edge_armv6(y_ptr + 4 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
79    vp8_loop_filter_horizontal_edge_armv6(y_ptr + 8 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
80    vp8_loop_filter_horizontal_edge_armv6(y_ptr + 12 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
81
82    if (u_ptr)
83        vp8_loop_filter_horizontal_edge_armv6(u_ptr + 4 * uv_stride, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
84
85    if (v_ptr)
86        vp8_loop_filter_horizontal_edge_armv6(v_ptr + 4 * uv_stride, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
87}
88
89void vp8_loop_filter_bhs_armv6(unsigned char *y_ptr, int y_stride,
90                               const unsigned char *blimit)
91{
92    vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr + 4 * y_stride, y_stride, blimit);
93    vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr + 8 * y_stride, y_stride, blimit);
94    vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr + 12 * y_stride, y_stride, blimit);
95}
96
97/* Vertical B Filtering */
98void vp8_loop_filter_bv_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
99                              int y_stride, int uv_stride, loop_filter_info *lfi)
100{
101    vp8_loop_filter_vertical_edge_armv6(y_ptr + 4, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
102    vp8_loop_filter_vertical_edge_armv6(y_ptr + 8, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
103    vp8_loop_filter_vertical_edge_armv6(y_ptr + 12, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2);
104
105    if (u_ptr)
106        vp8_loop_filter_vertical_edge_armv6(u_ptr + 4, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
107
108    if (v_ptr)
109        vp8_loop_filter_vertical_edge_armv6(v_ptr + 4, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1);
110}
111
112void vp8_loop_filter_bvs_armv6(unsigned char *y_ptr, int y_stride,
113                               const unsigned char *blimit)
114{
115    vp8_loop_filter_simple_vertical_edge_armv6(y_ptr + 4, y_stride, blimit);
116    vp8_loop_filter_simple_vertical_edge_armv6(y_ptr + 8, y_stride, blimit);
117    vp8_loop_filter_simple_vertical_edge_armv6(y_ptr + 12, y_stride, blimit);
118}
119#endif
120
121#if HAVE_NEON
122/* NEON loopfilter functions */
123/* Horizontal MB filtering */
124void vp8_loop_filter_mbh_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
125                              int y_stride, int uv_stride, loop_filter_info *lfi)
126{
127    unsigned char mblim = *lfi->mblim;
128    unsigned char lim = *lfi->lim;
129    unsigned char hev_thr = *lfi->hev_thr;
130    vp8_mbloop_filter_horizontal_edge_y_neon(y_ptr, y_stride, mblim, lim, hev_thr);
131
132    if (u_ptr)
133        vp8_mbloop_filter_horizontal_edge_uv_neon(u_ptr, uv_stride, mblim, lim, hev_thr, v_ptr);
134}
135
136/* Vertical MB Filtering */
137void vp8_loop_filter_mbv_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
138                              int y_stride, int uv_stride, loop_filter_info *lfi)
139{
140    unsigned char mblim = *lfi->mblim;
141    unsigned char lim = *lfi->lim;
142    unsigned char hev_thr = *lfi->hev_thr;
143
144    vp8_mbloop_filter_vertical_edge_y_neon(y_ptr, y_stride, mblim, lim, hev_thr);
145
146    if (u_ptr)
147        vp8_mbloop_filter_vertical_edge_uv_neon(u_ptr, uv_stride, mblim, lim, hev_thr, v_ptr);
148}
149
150/* Horizontal B Filtering */
151void vp8_loop_filter_bh_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
152                             int y_stride, int uv_stride, loop_filter_info *lfi)
153{
154    unsigned char blim = *lfi->blim;
155    unsigned char lim = *lfi->lim;
156    unsigned char hev_thr = *lfi->hev_thr;
157
158    vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 4 * y_stride, y_stride, blim, lim, hev_thr);
159    vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 8 * y_stride, y_stride, blim, lim, hev_thr);
160    vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 12 * y_stride, y_stride, blim, lim, hev_thr);
161
162    if (u_ptr)
163        vp8_loop_filter_horizontal_edge_uv_neon(u_ptr + 4 * uv_stride, uv_stride, blim, lim, hev_thr, v_ptr + 4 * uv_stride);
164}
165
166/* Vertical B Filtering */
167void vp8_loop_filter_bv_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr,
168                             int y_stride, int uv_stride, loop_filter_info *lfi)
169{
170    unsigned char blim = *lfi->blim;
171    unsigned char lim = *lfi->lim;
172    unsigned char hev_thr = *lfi->hev_thr;
173
174    vp8_loop_filter_vertical_edge_y_neon(y_ptr + 4, y_stride, blim, lim, hev_thr);
175    vp8_loop_filter_vertical_edge_y_neon(y_ptr + 8, y_stride, blim, lim, hev_thr);
176    vp8_loop_filter_vertical_edge_y_neon(y_ptr + 12, y_stride, blim, lim, hev_thr);
177
178    if (u_ptr)
179        vp8_loop_filter_vertical_edge_uv_neon(u_ptr + 4, uv_stride, blim, lim, hev_thr, v_ptr + 4);
180}
181#endif
182