11b362b15af34006e6a11974088a46d42b903418eJohann/* 21b362b15af34006e6a11974088a46d42b903418eJohann * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 31b362b15af34006e6a11974088a46d42b903418eJohann * 41b362b15af34006e6a11974088a46d42b903418eJohann * Use of this source code is governed by a BSD-style license 51b362b15af34006e6a11974088a46d42b903418eJohann * that can be found in the LICENSE file in the root of the source 61b362b15af34006e6a11974088a46d42b903418eJohann * tree. An additional intellectual property rights grant can be found 71b362b15af34006e6a11974088a46d42b903418eJohann * in the file PATENTS. All contributing project authors may 81b362b15af34006e6a11974088a46d42b903418eJohann * be found in the AUTHORS file in the root of the source tree. 91b362b15af34006e6a11974088a46d42b903418eJohann */ 101b362b15af34006e6a11974088a46d42b903418eJohann 111b362b15af34006e6a11974088a46d42b903418eJohann 121b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_config.h" 13ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang#include "vp8_rtcd.h" 141b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/loopfilter.h" 151b362b15af34006e6a11974088a46d42b903418eJohann#include "vp8/common/onyxc_int.h" 161b362b15af34006e6a11974088a46d42b903418eJohann 171b362b15af34006e6a11974088a46d42b903418eJohann#define prototype_loopfilter(sym) \ 181b362b15af34006e6a11974088a46d42b903418eJohann void sym(unsigned char *src, int pitch, const unsigned char *blimit,\ 191b362b15af34006e6a11974088a46d42b903418eJohann const unsigned char *limit, const unsigned char *thresh, int count) 201b362b15af34006e6a11974088a46d42b903418eJohann 211b362b15af34006e6a11974088a46d42b903418eJohann#if HAVE_MEDIA 221b362b15af34006e6a11974088a46d42b903418eJohannextern prototype_loopfilter(vp8_loop_filter_horizontal_edge_armv6); 231b362b15af34006e6a11974088a46d42b903418eJohannextern prototype_loopfilter(vp8_loop_filter_vertical_edge_armv6); 241b362b15af34006e6a11974088a46d42b903418eJohannextern prototype_loopfilter(vp8_mbloop_filter_horizontal_edge_armv6); 251b362b15af34006e6a11974088a46d42b903418eJohannextern prototype_loopfilter(vp8_mbloop_filter_vertical_edge_armv6); 261b362b15af34006e6a11974088a46d42b903418eJohann#endif 271b362b15af34006e6a11974088a46d42b903418eJohann 281b362b15af34006e6a11974088a46d42b903418eJohann#if HAVE_NEON 291b362b15af34006e6a11974088a46d42b903418eJohanntypedef void loopfilter_y_neon(unsigned char *src, int pitch, 301b362b15af34006e6a11974088a46d42b903418eJohann unsigned char blimit, unsigned char limit, unsigned char thresh); 311b362b15af34006e6a11974088a46d42b903418eJohanntypedef void loopfilter_uv_neon(unsigned char *u, int pitch, 321b362b15af34006e6a11974088a46d42b903418eJohann unsigned char blimit, unsigned char limit, unsigned char thresh, 331b362b15af34006e6a11974088a46d42b903418eJohann unsigned char *v); 341b362b15af34006e6a11974088a46d42b903418eJohann 351b362b15af34006e6a11974088a46d42b903418eJohannextern loopfilter_y_neon vp8_loop_filter_horizontal_edge_y_neon; 361b362b15af34006e6a11974088a46d42b903418eJohannextern loopfilter_y_neon vp8_loop_filter_vertical_edge_y_neon; 371b362b15af34006e6a11974088a46d42b903418eJohannextern loopfilter_y_neon vp8_mbloop_filter_horizontal_edge_y_neon; 381b362b15af34006e6a11974088a46d42b903418eJohannextern loopfilter_y_neon vp8_mbloop_filter_vertical_edge_y_neon; 391b362b15af34006e6a11974088a46d42b903418eJohann 401b362b15af34006e6a11974088a46d42b903418eJohannextern loopfilter_uv_neon vp8_loop_filter_horizontal_edge_uv_neon; 411b362b15af34006e6a11974088a46d42b903418eJohannextern loopfilter_uv_neon vp8_loop_filter_vertical_edge_uv_neon; 421b362b15af34006e6a11974088a46d42b903418eJohannextern loopfilter_uv_neon vp8_mbloop_filter_horizontal_edge_uv_neon; 431b362b15af34006e6a11974088a46d42b903418eJohannextern loopfilter_uv_neon vp8_mbloop_filter_vertical_edge_uv_neon; 441b362b15af34006e6a11974088a46d42b903418eJohann#endif 451b362b15af34006e6a11974088a46d42b903418eJohann 461b362b15af34006e6a11974088a46d42b903418eJohann#if HAVE_MEDIA 471b362b15af34006e6a11974088a46d42b903418eJohann/* ARMV6/MEDIA loopfilter functions*/ 481b362b15af34006e6a11974088a46d42b903418eJohann/* Horizontal MB filtering */ 491b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_mbh_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr, 501b362b15af34006e6a11974088a46d42b903418eJohann int y_stride, int uv_stride, loop_filter_info *lfi) 511b362b15af34006e6a11974088a46d42b903418eJohann{ 521b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_horizontal_edge_armv6(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 2); 531b362b15af34006e6a11974088a46d42b903418eJohann 541b362b15af34006e6a11974088a46d42b903418eJohann if (u_ptr) 551b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_horizontal_edge_armv6(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1); 561b362b15af34006e6a11974088a46d42b903418eJohann 571b362b15af34006e6a11974088a46d42b903418eJohann if (v_ptr) 581b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_horizontal_edge_armv6(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1); 591b362b15af34006e6a11974088a46d42b903418eJohann} 601b362b15af34006e6a11974088a46d42b903418eJohann 611b362b15af34006e6a11974088a46d42b903418eJohann/* Vertical MB Filtering */ 621b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_mbv_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr, 631b362b15af34006e6a11974088a46d42b903418eJohann int y_stride, int uv_stride, loop_filter_info *lfi) 641b362b15af34006e6a11974088a46d42b903418eJohann{ 651b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_vertical_edge_armv6(y_ptr, y_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 2); 661b362b15af34006e6a11974088a46d42b903418eJohann 671b362b15af34006e6a11974088a46d42b903418eJohann if (u_ptr) 681b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_vertical_edge_armv6(u_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1); 691b362b15af34006e6a11974088a46d42b903418eJohann 701b362b15af34006e6a11974088a46d42b903418eJohann if (v_ptr) 711b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_vertical_edge_armv6(v_ptr, uv_stride, lfi->mblim, lfi->lim, lfi->hev_thr, 1); 721b362b15af34006e6a11974088a46d42b903418eJohann} 731b362b15af34006e6a11974088a46d42b903418eJohann 741b362b15af34006e6a11974088a46d42b903418eJohann/* Horizontal B Filtering */ 751b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_bh_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr, 761b362b15af34006e6a11974088a46d42b903418eJohann int y_stride, int uv_stride, loop_filter_info *lfi) 771b362b15af34006e6a11974088a46d42b903418eJohann{ 781b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_horizontal_edge_armv6(y_ptr + 4 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2); 791b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_horizontal_edge_armv6(y_ptr + 8 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2); 801b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_horizontal_edge_armv6(y_ptr + 12 * y_stride, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2); 811b362b15af34006e6a11974088a46d42b903418eJohann 821b362b15af34006e6a11974088a46d42b903418eJohann if (u_ptr) 831b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_horizontal_edge_armv6(u_ptr + 4 * uv_stride, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1); 841b362b15af34006e6a11974088a46d42b903418eJohann 851b362b15af34006e6a11974088a46d42b903418eJohann if (v_ptr) 861b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_horizontal_edge_armv6(v_ptr + 4 * uv_stride, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1); 871b362b15af34006e6a11974088a46d42b903418eJohann} 881b362b15af34006e6a11974088a46d42b903418eJohann 891b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_bhs_armv6(unsigned char *y_ptr, int y_stride, 901b362b15af34006e6a11974088a46d42b903418eJohann const unsigned char *blimit) 911b362b15af34006e6a11974088a46d42b903418eJohann{ 921b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr + 4 * y_stride, y_stride, blimit); 931b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr + 8 * y_stride, y_stride, blimit); 941b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_simple_horizontal_edge_armv6(y_ptr + 12 * y_stride, y_stride, blimit); 951b362b15af34006e6a11974088a46d42b903418eJohann} 961b362b15af34006e6a11974088a46d42b903418eJohann 971b362b15af34006e6a11974088a46d42b903418eJohann/* Vertical B Filtering */ 981b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_bv_armv6(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr, 991b362b15af34006e6a11974088a46d42b903418eJohann int y_stride, int uv_stride, loop_filter_info *lfi) 1001b362b15af34006e6a11974088a46d42b903418eJohann{ 1011b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_vertical_edge_armv6(y_ptr + 4, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2); 1021b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_vertical_edge_armv6(y_ptr + 8, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2); 1031b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_vertical_edge_armv6(y_ptr + 12, y_stride, lfi->blim, lfi->lim, lfi->hev_thr, 2); 1041b362b15af34006e6a11974088a46d42b903418eJohann 1051b362b15af34006e6a11974088a46d42b903418eJohann if (u_ptr) 1061b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_vertical_edge_armv6(u_ptr + 4, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1); 1071b362b15af34006e6a11974088a46d42b903418eJohann 1081b362b15af34006e6a11974088a46d42b903418eJohann if (v_ptr) 1091b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_vertical_edge_armv6(v_ptr + 4, uv_stride, lfi->blim, lfi->lim, lfi->hev_thr, 1); 1101b362b15af34006e6a11974088a46d42b903418eJohann} 1111b362b15af34006e6a11974088a46d42b903418eJohann 1121b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_bvs_armv6(unsigned char *y_ptr, int y_stride, 1131b362b15af34006e6a11974088a46d42b903418eJohann const unsigned char *blimit) 1141b362b15af34006e6a11974088a46d42b903418eJohann{ 1151b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_simple_vertical_edge_armv6(y_ptr + 4, y_stride, blimit); 1161b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_simple_vertical_edge_armv6(y_ptr + 8, y_stride, blimit); 1171b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_simple_vertical_edge_armv6(y_ptr + 12, y_stride, blimit); 1181b362b15af34006e6a11974088a46d42b903418eJohann} 1191b362b15af34006e6a11974088a46d42b903418eJohann#endif 1201b362b15af34006e6a11974088a46d42b903418eJohann 1211b362b15af34006e6a11974088a46d42b903418eJohann#if HAVE_NEON 1221b362b15af34006e6a11974088a46d42b903418eJohann/* NEON loopfilter functions */ 1231b362b15af34006e6a11974088a46d42b903418eJohann/* Horizontal MB filtering */ 1241b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_mbh_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr, 1251b362b15af34006e6a11974088a46d42b903418eJohann int y_stride, int uv_stride, loop_filter_info *lfi) 1261b362b15af34006e6a11974088a46d42b903418eJohann{ 1271b362b15af34006e6a11974088a46d42b903418eJohann unsigned char mblim = *lfi->mblim; 1281b362b15af34006e6a11974088a46d42b903418eJohann unsigned char lim = *lfi->lim; 1291b362b15af34006e6a11974088a46d42b903418eJohann unsigned char hev_thr = *lfi->hev_thr; 1301b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_horizontal_edge_y_neon(y_ptr, y_stride, mblim, lim, hev_thr); 1311b362b15af34006e6a11974088a46d42b903418eJohann 1321b362b15af34006e6a11974088a46d42b903418eJohann if (u_ptr) 1331b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_horizontal_edge_uv_neon(u_ptr, uv_stride, mblim, lim, hev_thr, v_ptr); 1341b362b15af34006e6a11974088a46d42b903418eJohann} 1351b362b15af34006e6a11974088a46d42b903418eJohann 1361b362b15af34006e6a11974088a46d42b903418eJohann/* Vertical MB Filtering */ 1371b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_mbv_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr, 1381b362b15af34006e6a11974088a46d42b903418eJohann int y_stride, int uv_stride, loop_filter_info *lfi) 1391b362b15af34006e6a11974088a46d42b903418eJohann{ 1401b362b15af34006e6a11974088a46d42b903418eJohann unsigned char mblim = *lfi->mblim; 1411b362b15af34006e6a11974088a46d42b903418eJohann unsigned char lim = *lfi->lim; 1421b362b15af34006e6a11974088a46d42b903418eJohann unsigned char hev_thr = *lfi->hev_thr; 1431b362b15af34006e6a11974088a46d42b903418eJohann 1441b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_vertical_edge_y_neon(y_ptr, y_stride, mblim, lim, hev_thr); 1451b362b15af34006e6a11974088a46d42b903418eJohann 1461b362b15af34006e6a11974088a46d42b903418eJohann if (u_ptr) 1471b362b15af34006e6a11974088a46d42b903418eJohann vp8_mbloop_filter_vertical_edge_uv_neon(u_ptr, uv_stride, mblim, lim, hev_thr, v_ptr); 1481b362b15af34006e6a11974088a46d42b903418eJohann} 1491b362b15af34006e6a11974088a46d42b903418eJohann 1501b362b15af34006e6a11974088a46d42b903418eJohann/* Horizontal B Filtering */ 1511b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_bh_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr, 1521b362b15af34006e6a11974088a46d42b903418eJohann int y_stride, int uv_stride, loop_filter_info *lfi) 1531b362b15af34006e6a11974088a46d42b903418eJohann{ 1541b362b15af34006e6a11974088a46d42b903418eJohann unsigned char blim = *lfi->blim; 1551b362b15af34006e6a11974088a46d42b903418eJohann unsigned char lim = *lfi->lim; 1561b362b15af34006e6a11974088a46d42b903418eJohann unsigned char hev_thr = *lfi->hev_thr; 1571b362b15af34006e6a11974088a46d42b903418eJohann 1581b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 4 * y_stride, y_stride, blim, lim, hev_thr); 1591b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 8 * y_stride, y_stride, blim, lim, hev_thr); 1601b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_horizontal_edge_y_neon(y_ptr + 12 * y_stride, y_stride, blim, lim, hev_thr); 1611b362b15af34006e6a11974088a46d42b903418eJohann 1621b362b15af34006e6a11974088a46d42b903418eJohann if (u_ptr) 1631b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_horizontal_edge_uv_neon(u_ptr + 4 * uv_stride, uv_stride, blim, lim, hev_thr, v_ptr + 4 * uv_stride); 1641b362b15af34006e6a11974088a46d42b903418eJohann} 1651b362b15af34006e6a11974088a46d42b903418eJohann 1661b362b15af34006e6a11974088a46d42b903418eJohann/* Vertical B Filtering */ 1671b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_loop_filter_bv_neon(unsigned char *y_ptr, unsigned char *u_ptr, unsigned char *v_ptr, 1681b362b15af34006e6a11974088a46d42b903418eJohann int y_stride, int uv_stride, loop_filter_info *lfi) 1691b362b15af34006e6a11974088a46d42b903418eJohann{ 1701b362b15af34006e6a11974088a46d42b903418eJohann unsigned char blim = *lfi->blim; 1711b362b15af34006e6a11974088a46d42b903418eJohann unsigned char lim = *lfi->lim; 1721b362b15af34006e6a11974088a46d42b903418eJohann unsigned char hev_thr = *lfi->hev_thr; 1731b362b15af34006e6a11974088a46d42b903418eJohann 1741b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_vertical_edge_y_neon(y_ptr + 4, y_stride, blim, lim, hev_thr); 1751b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_vertical_edge_y_neon(y_ptr + 8, y_stride, blim, lim, hev_thr); 1761b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_vertical_edge_y_neon(y_ptr + 12, y_stride, blim, lim, hev_thr); 1771b362b15af34006e6a11974088a46d42b903418eJohann 1781b362b15af34006e6a11974088a46d42b903418eJohann if (u_ptr) 1791b362b15af34006e6a11974088a46d42b903418eJohann vp8_loop_filter_vertical_edge_uv_neon(u_ptr + 4, uv_stride, blim, lim, hev_thr, v_ptr + 4); 1801b362b15af34006e6a11974088a46d42b903418eJohann} 1811b362b15af34006e6a11974088a46d42b903418eJohann#endif 182