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