summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohann <johannkoenig@google.com>2016-06-10 15:49:44 -0700
committerJohann Koenig <johannkoenig@google.com>2016-06-14 19:23:38 +0000
commitc516dd67bc50eecd13dc7fc95b75251cf67c8750 (patch)
tree7754a4d3f34f2467ab6a1715567fc9a2ddede7e4
parent63eb2ee0569e5480b39860eb898e16ab45b43e9c (diff)
downloadlibvpx-c516dd67bc50eecd13dc7fc95b75251cf67c8750.tar
libvpx-c516dd67bc50eecd13dc7fc95b75251cf67c8750.tar.gz
libvpx-c516dd67bc50eecd13dc7fc95b75251cf67c8750.tar.bz2
libvpx-c516dd67bc50eecd13dc7fc95b75251cf67c8750.zip
neon hadamard 16x16
Runs about twice as fast as C BUG=webm:1027 Change-Id: I6760d99f4e22259439ca35d746194b12a81bfa71
-rw-r--r--test/hadamard_test.cc5
-rw-r--r--vpx_dsp/arm/hadamard_neon.c39
-rw-r--r--vpx_dsp/vpx_dsp_rtcd_defs.pl2
3 files changed, 45 insertions, 1 deletions
diff --git a/test/hadamard_test.cc b/test/hadamard_test.cc
index d21c28af0..7a5bd5b4c 100644
--- a/test/hadamard_test.cc
+++ b/test/hadamard_test.cc
@@ -212,4 +212,9 @@ INSTANTIATE_TEST_CASE_P(C, Hadamard16x16Test,
INSTANTIATE_TEST_CASE_P(SSE2, Hadamard16x16Test,
::testing::Values(&vpx_hadamard_16x16_sse2));
#endif // HAVE_SSE2
+
+#if HAVE_NEON
+INSTANTIATE_TEST_CASE_P(NEON, Hadamard16x16Test,
+ ::testing::Values(&vpx_hadamard_16x16_neon));
+#endif // HAVE_NEON
} // namespace
diff --git a/vpx_dsp/arm/hadamard_neon.c b/vpx_dsp/arm/hadamard_neon.c
index cc9e80416..21e3e3dba 100644
--- a/vpx_dsp/arm/hadamard_neon.c
+++ b/vpx_dsp/arm/hadamard_neon.c
@@ -160,3 +160,42 @@ void vpx_hadamard_8x8_neon(const int16_t *src_diff, int src_stride,
vst1q_s16(coeff + 48, a6);
vst1q_s16(coeff + 56, a7);
}
+
+void vpx_hadamard_16x16_neon(const int16_t *src_diff, int src_stride,
+ int16_t *coeff) {
+ int i;
+
+ /* Rearrange 16x16 to 8x32 and remove stride.
+ * Top left first. */
+ vpx_hadamard_8x8_neon(src_diff + 0 + 0 * src_stride, src_stride, coeff + 0);
+ /* Top right. */
+ vpx_hadamard_8x8_neon(src_diff + 8 + 0 * src_stride, src_stride, coeff + 64);
+ /* Bottom left. */
+ vpx_hadamard_8x8_neon(src_diff + 0 + 8 * src_stride, src_stride, coeff + 128);
+ /* Bottom right. */
+ vpx_hadamard_8x8_neon(src_diff + 8 + 8 * src_stride, src_stride, coeff + 192);
+
+ for (i = 0; i < 64; i += 8) {
+ const int16x8_t a0 = vld1q_s16(coeff + 0);
+ const int16x8_t a1 = vld1q_s16(coeff + 64);
+ const int16x8_t a2 = vld1q_s16(coeff + 128);
+ const int16x8_t a3 = vld1q_s16(coeff + 192);
+
+ const int16x8_t b0 = vhaddq_s16(a0, a1);
+ const int16x8_t b1 = vhsubq_s16(a0, a1);
+ const int16x8_t b2 = vhaddq_s16(a2, a3);
+ const int16x8_t b3 = vhsubq_s16(a2, a3);
+
+ const int16x8_t c0 = vaddq_s16(b0, b2);
+ const int16x8_t c1 = vaddq_s16(b1, b3);
+ const int16x8_t c2 = vsubq_s16(b0, b2);
+ const int16x8_t c3 = vsubq_s16(b1, b3);
+
+ vst1q_s16(coeff + 0, c0);
+ vst1q_s16(coeff + 64, c1);
+ vst1q_s16(coeff + 128, c2);
+ vst1q_s16(coeff + 192, c3);
+
+ coeff += 8;
+ }
+}
diff --git a/vpx_dsp/vpx_dsp_rtcd_defs.pl b/vpx_dsp/vpx_dsp_rtcd_defs.pl
index 414428127..a62acb717 100644
--- a/vpx_dsp/vpx_dsp_rtcd_defs.pl
+++ b/vpx_dsp/vpx_dsp_rtcd_defs.pl
@@ -1020,7 +1020,7 @@ if ((vpx_config("CONFIG_VP9_ENCODER") eq "yes") || (vpx_config("CONFIG_VP10_ENCO
specialize qw/vpx_hadamard_8x8 sse2 neon/, "$ssse3_x86_64_x86inc";
add_proto qw/void vpx_hadamard_16x16/, "const int16_t *src_diff, int src_stride, int16_t *coeff";
- specialize qw/vpx_hadamard_16x16 sse2/;
+ specialize qw/vpx_hadamard_16x16 sse2 neon/;
add_proto qw/int vpx_satd/, "const int16_t *coeff, int length";
specialize qw/vpx_satd sse2 neon/;