]> granicus.if.org Git - libvpx/commitdiff
neon hadamard 16x16
authorJohann <johannkoenig@google.com>
Fri, 10 Jun 2016 22:49:44 +0000 (15:49 -0700)
committerJohann Koenig <johannkoenig@google.com>
Tue, 14 Jun 2016 19:23:38 +0000 (19:23 +0000)
Runs about twice as fast as C

BUG=webm:1027

Change-Id: I6760d99f4e22259439ca35d746194b12a81bfa71

test/hadamard_test.cc
vpx_dsp/arm/hadamard_neon.c
vpx_dsp/vpx_dsp_rtcd_defs.pl

index d21c28af02f1444098234ee7b760f84278fe2392..7a5bd5b4cf087c1c06b73fbed387edc1a86e0115 100644 (file)
@@ -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
index cc9e8041601ba5e45f5d26bdb7a3615a89f7a0b5..21e3e3dbacfb79ae044954081a4f3138d5514b98 100644 (file)
@@ -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;
+  }
+}
index 4144281278aeb71b18250f55d953f363aa10879d..a62acb717d4768cb5043eb2f0ed12143673a72c3 100644 (file)
@@ -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/;