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 26 prototype_loopfilter(vp8_loop_filter_bv_y_sse2); 27 prototype_loopfilter(vp8_loop_filter_bh_y_sse2); 28 #else 29 prototype_loopfilter_nc(vp8_loop_filter_vertical_edge_sse2); 30 prototype_loopfilter_nc(vp8_loop_filter_horizontal_edge_sse2); 31 #endif 32 prototype_loopfilter_nc(vp8_mbloop_filter_vertical_edge_sse2); 33 prototype_loopfilter_nc(vp8_mbloop_filter_horizontal_edge_sse2); 34 35 extern loop_filter_uvfunction vp8_loop_filter_horizontal_edge_uv_sse2; 36 extern loop_filter_uvfunction vp8_loop_filter_vertical_edge_uv_sse2; 37 extern loop_filter_uvfunction vp8_mbloop_filter_horizontal_edge_uv_sse2; 38 extern loop_filter_uvfunction vp8_mbloop_filter_vertical_edge_uv_sse2; 39 40 /* Horizontal MB filtering */ 41 #if HAVE_SSE2 42 void 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 */ 55 void 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 */ 68 void 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 90 void 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 */ 101 void 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 122 void 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