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 */ 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 */ 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 */ 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 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 */ 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 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 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 */ 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 */ 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 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 */ 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 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