9d0d13e939
BUG=webm:1419 Change-Id: I39c8033734562efc0ac0e28e7f06fa05130f9b96
134 lines
4.8 KiB
C
134 lines
4.8 KiB
C
/*
|
|
* Copyright (c) 2014 The WebM project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include <arm_neon.h>
|
|
|
|
#include "./vpx_config.h"
|
|
#include "./vpx_dsp_rtcd.h"
|
|
|
|
static INLINE void load_u8_8x4(const uint8_t *s, const ptrdiff_t p,
|
|
uint8x8_t *const s0, uint8x8_t *const s1,
|
|
uint8x8_t *const s2, uint8x8_t *const s3) {
|
|
*s0 = vld1_u8(s);
|
|
s += p;
|
|
*s1 = vld1_u8(s);
|
|
s += p;
|
|
*s2 = vld1_u8(s);
|
|
s += p;
|
|
*s3 = vld1_u8(s);
|
|
}
|
|
|
|
static INLINE void load_u8_8x8(const uint8_t *s, const ptrdiff_t p,
|
|
uint8x8_t *const s0, uint8x8_t *const s1,
|
|
uint8x8_t *const s2, uint8x8_t *const s3,
|
|
uint8x8_t *const s4, uint8x8_t *const s5,
|
|
uint8x8_t *const s6, uint8x8_t *const s7) {
|
|
*s0 = vld1_u8(s);
|
|
s += p;
|
|
*s1 = vld1_u8(s);
|
|
s += p;
|
|
*s2 = vld1_u8(s);
|
|
s += p;
|
|
*s3 = vld1_u8(s);
|
|
s += p;
|
|
*s4 = vld1_u8(s);
|
|
s += p;
|
|
*s5 = vld1_u8(s);
|
|
s += p;
|
|
*s6 = vld1_u8(s);
|
|
s += p;
|
|
*s7 = vld1_u8(s);
|
|
}
|
|
|
|
static INLINE void load_u8_16x8(const uint8_t *s, const ptrdiff_t p,
|
|
uint8x16_t *const s0, uint8x16_t *const s1,
|
|
uint8x16_t *const s2, uint8x16_t *const s3,
|
|
uint8x16_t *const s4, uint8x16_t *const s5,
|
|
uint8x16_t *const s6, uint8x16_t *const s7) {
|
|
*s0 = vld1q_u8(s);
|
|
s += p;
|
|
*s1 = vld1q_u8(s);
|
|
s += p;
|
|
*s2 = vld1q_u8(s);
|
|
s += p;
|
|
*s3 = vld1q_u8(s);
|
|
s += p;
|
|
*s4 = vld1q_u8(s);
|
|
s += p;
|
|
*s5 = vld1q_u8(s);
|
|
s += p;
|
|
*s6 = vld1q_u8(s);
|
|
s += p;
|
|
*s7 = vld1q_u8(s);
|
|
}
|
|
|
|
static INLINE int16x4_t convolve8_4(const int16x4_t s0, const int16x4_t s1,
|
|
const int16x4_t s2, const int16x4_t s3,
|
|
const int16x4_t s4, const int16x4_t s5,
|
|
const int16x4_t s6, const int16x4_t s7,
|
|
const int16x8_t filters,
|
|
const int16x4_t filter3,
|
|
const int16x4_t filter4) {
|
|
const int16x4_t filters_lo = vget_low_s16(filters);
|
|
const int16x4_t filters_hi = vget_high_s16(filters);
|
|
int16x4_t sum;
|
|
|
|
sum = vmul_lane_s16(s0, filters_lo, 0);
|
|
sum = vmla_lane_s16(sum, s1, filters_lo, 1);
|
|
sum = vmla_lane_s16(sum, s2, filters_lo, 2);
|
|
sum = vmla_lane_s16(sum, s5, filters_hi, 1);
|
|
sum = vmla_lane_s16(sum, s6, filters_hi, 2);
|
|
sum = vmla_lane_s16(sum, s7, filters_hi, 3);
|
|
sum = vqadd_s16(sum, vmul_s16(s3, filter3));
|
|
sum = vqadd_s16(sum, vmul_s16(s4, filter4));
|
|
return sum;
|
|
}
|
|
|
|
static INLINE uint8x8_t convolve8_8(const int16x8_t s0, const int16x8_t s1,
|
|
const int16x8_t s2, const int16x8_t s3,
|
|
const int16x8_t s4, const int16x8_t s5,
|
|
const int16x8_t s6, const int16x8_t s7,
|
|
const int16x8_t filters,
|
|
const int16x8_t filter3,
|
|
const int16x8_t filter4) {
|
|
const int16x4_t filters_lo = vget_low_s16(filters);
|
|
const int16x4_t filters_hi = vget_high_s16(filters);
|
|
int16x8_t sum;
|
|
|
|
sum = vmulq_lane_s16(s0, filters_lo, 0);
|
|
sum = vmlaq_lane_s16(sum, s1, filters_lo, 1);
|
|
sum = vmlaq_lane_s16(sum, s2, filters_lo, 2);
|
|
sum = vmlaq_lane_s16(sum, s5, filters_hi, 1);
|
|
sum = vmlaq_lane_s16(sum, s6, filters_hi, 2);
|
|
sum = vmlaq_lane_s16(sum, s7, filters_hi, 3);
|
|
sum = vqaddq_s16(sum, vmulq_s16(s3, filter3));
|
|
sum = vqaddq_s16(sum, vmulq_s16(s4, filter4));
|
|
return vqrshrun_n_s16(sum, 7);
|
|
}
|
|
|
|
static INLINE uint8x8_t scale_filter_8(const uint8x8_t *const s,
|
|
const int16x8_t filters) {
|
|
const int16x8_t filter3 = vdupq_lane_s16(vget_low_s16(filters), 3);
|
|
const int16x8_t filter4 = vdupq_lane_s16(vget_high_s16(filters), 0);
|
|
int16x8_t ss[8];
|
|
|
|
ss[0] = vreinterpretq_s16_u16(vmovl_u8(s[0]));
|
|
ss[1] = vreinterpretq_s16_u16(vmovl_u8(s[1]));
|
|
ss[2] = vreinterpretq_s16_u16(vmovl_u8(s[2]));
|
|
ss[3] = vreinterpretq_s16_u16(vmovl_u8(s[3]));
|
|
ss[4] = vreinterpretq_s16_u16(vmovl_u8(s[4]));
|
|
ss[5] = vreinterpretq_s16_u16(vmovl_u8(s[5]));
|
|
ss[6] = vreinterpretq_s16_u16(vmovl_u8(s[6]));
|
|
ss[7] = vreinterpretq_s16_u16(vmovl_u8(s[7]));
|
|
|
|
return convolve8_8(ss[0], ss[1], ss[2], ss[3], ss[4], ss[5], ss[6], ss[7],
|
|
filters, filter3, filter4);
|
|
}
|