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 26prototype_loopfilter(vp8_mbloop_filter_vertical_edge_mmx); 27prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_mmx); 28prototype_loopfilter(vp8_loop_filter_vertical_edge_mmx); 29prototype_loopfilter(vp8_loop_filter_horizontal_edge_mmx); 30prototype_simple_loopfilter(vp8_loop_filter_simple_horizontal_edge_mmx); 31prototype_simple_loopfilter(vp8_loop_filter_simple_vertical_edge_mmx); 32 33#if HAVE_SSE2 && ARCH_X86_64 34prototype_loopfilter(vp8_loop_filter_bv_y_sse2); 35prototype_loopfilter(vp8_loop_filter_bh_y_sse2); 36#else 37prototype_loopfilter_nc(vp8_loop_filter_vertical_edge_sse2); 38prototype_loopfilter_nc(vp8_loop_filter_horizontal_edge_sse2); 39#endif 40prototype_loopfilter_nc(vp8_mbloop_filter_vertical_edge_sse2); 41prototype_loopfilter_nc(vp8_mbloop_filter_horizontal_edge_sse2); 42 43extern loop_filter_uvfunction vp8_loop_filter_horizontal_edge_uv_sse2; 44extern loop_filter_uvfunction vp8_loop_filter_vertical_edge_uv_sse2; 45extern loop_filter_uvfunction vp8_mbloop_filter_horizontal_edge_uv_sse2; 46extern loop_filter_uvfunction vp8_mbloop_filter_vertical_edge_uv_sse2; 47 48#if HAVE_MMX 49/* Horizontal MB filtering */ 50void 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 */ 64void 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 */ 78void 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 93void 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 */ 102void 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 117void 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 128void 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 */ 139void 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 */ 150void 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 166void 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 */ 175void 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 191void 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