1 /*
2 * Copyright (c) 2014 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 <arm_neon.h>
12 #include <assert.h>
13
14 #include "./vp9_rtcd.h"
15 #include "./vpx_config.h"
16 #include "vp9/common/vp9_common.h"
17 #include "vp9/common/arm/neon/vp9_iht_neon.h"
18 #include "vpx_dsp/arm/idct_neon.h"
19 #include "vpx_dsp/arm/mem_neon.h"
20 #include "vpx_dsp/txfm_common.h"
21
vp9_iht4x4_16_add_neon(const tran_low_t * input,uint8_t * dest,int stride,int tx_type)22 void vp9_iht4x4_16_add_neon(const tran_low_t *input, uint8_t *dest, int stride,
23 int tx_type) {
24 int16x8_t a[2];
25 uint8x8_t s[2], d[2];
26 uint16x8_t sum[2];
27
28 assert(!((intptr_t)dest % sizeof(uint32_t)));
29 assert(!(stride % sizeof(uint32_t)));
30
31 a[0] = load_tran_low_to_s16q(input);
32 a[1] = load_tran_low_to_s16q(input + 8);
33 transpose_s16_4x4q(&a[0], &a[1]);
34
35 switch (tx_type) {
36 case DCT_DCT:
37 idct4x4_16_kernel_bd8(a);
38 a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1]));
39 transpose_s16_4x4q(&a[0], &a[1]);
40 idct4x4_16_kernel_bd8(a);
41 a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1]));
42 break;
43
44 case ADST_DCT:
45 idct4x4_16_kernel_bd8(a);
46 a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1]));
47 transpose_s16_4x4q(&a[0], &a[1]);
48 iadst4(a);
49 break;
50
51 case DCT_ADST:
52 iadst4(a);
53 transpose_s16_4x4q(&a[0], &a[1]);
54 idct4x4_16_kernel_bd8(a);
55 a[1] = vcombine_s16(vget_high_s16(a[1]), vget_low_s16(a[1]));
56 break;
57
58 default:
59 assert(tx_type == ADST_ADST);
60 iadst4(a);
61 transpose_s16_4x4q(&a[0], &a[1]);
62 iadst4(a);
63 break;
64 }
65
66 a[0] = vrshrq_n_s16(a[0], 4);
67 a[1] = vrshrq_n_s16(a[1], 4);
68 s[0] = load_u8(dest, stride);
69 s[1] = load_u8(dest + 2 * stride, stride);
70 sum[0] = vaddw_u8(vreinterpretq_u16_s16(a[0]), s[0]);
71 sum[1] = vaddw_u8(vreinterpretq_u16_s16(a[1]), s[1]);
72 d[0] = vqmovun_s16(vreinterpretq_s16_u16(sum[0]));
73 d[1] = vqmovun_s16(vreinterpretq_s16_u16(sum[1]));
74 store_u8(dest, stride, d[0]);
75 store_u8(dest + 2 * stride, stride, d[1]);
76 }
77