diff --git a/libavutil/aarch64/pixelutils.h b/libavutil/aarch64/pixelutils.h index e969ee81ed..02d22ab692 100644 --- a/libavutil/aarch64/pixelutils.h +++ b/libavutil/aarch64/pixelutils.h @@ -27,9 +27,11 @@ #include "libavutil/cpu.h" #include "libavutil/pixelutils.h" +int ff_pixelutils_sad8_neon (const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); int ff_pixelutils_sad16_neon(const uint8_t *src1, ptrdiff_t stride1, const uint8_t *src2, ptrdiff_t stride2); -int ff_pixelutils_sad8_neon (const uint8_t *src1, ptrdiff_t stride1, +int ff_pixelutils_sad32_neon(const uint8_t *src1, ptrdiff_t stride1, const uint8_t *src2, ptrdiff_t stride2); static inline av_cold void ff_pixelutils_sad_init_aarch64(av_pixelutils_sad_fn *sad, int aligned) @@ -39,6 +41,7 @@ static inline av_cold void ff_pixelutils_sad_init_aarch64(av_pixelutils_sad_fn * if (have_neon(cpu_flags)) { sad[2] = ff_pixelutils_sad8_neon; sad[3] = ff_pixelutils_sad16_neon; + sad[4] = ff_pixelutils_sad32_neon; } } #endif diff --git a/libavutil/aarch64/pixelutils_neon.S b/libavutil/aarch64/pixelutils_neon.S index 6e5178adb3..4b5c4d5414 100644 --- a/libavutil/aarch64/pixelutils_neon.S +++ b/libavutil/aarch64/pixelutils_neon.S @@ -86,3 +86,50 @@ function ff_pixelutils_sad8_neon, export=1 ret endfunc + +function ff_pixelutils_sad32_neon, export=1 + // x0 uint8_t *pix1 + // x1 ptrdiff_t stride1 + // x2 uint8_t *pix2 + // x3 ptrdiff_t stride2 + movi v16.8h, #0 // clear result accumulator + movi v17.8h, #0 // clear result accumulator + movi v18.8h, #0 // clear result accumulator + movi v19.8h, #0 // clear result accumulator + mov w4, 32 +1: + ld1 {v0.16b, v1.16b}, [x0], x1 // load pix1 + ld1 {v4.16b, v5.16b}, [x2], x3 // load pix2 + ld1 {v2.16b, v3.16b}, [x0], x1 // load pix1 + ld1 {v6.16b, v7.16b}, [x2], x3 // load pix2 + uabal v16.8h, v0.8b, v4.8b // absolute difference accumulate + uabal2 v17.8h, v0.16b, v4.16b + uabal v18.8h, v1.8b, v5.8b + uabal2 v19.8h, v1.16b, v5.16b + ld1 {v0.16b, v1.16b}, [x0], x1 // load pix1 + ld1 {v4.16b, v5.16b}, [x2], x3 // load pix2 + uabal v16.8h, v2.8b, v6.8b // absolute difference accumulate + uabal2 v17.8h, v2.16b, v6.16b + uabal v18.8h, v3.8b, v7.8b + uabal2 v19.8h, v3.16b, v7.16b + ld1 {v2.16b, v3.16b}, [x0], x1 + ld1 {v6.16b, v7.16b}, [x2], x3 + uabal v16.8h, v0.8b, v4.8b + uabal2 v17.8h, v0.16b, v4.16b + uabal v18.8h, v1.8b, v5.8b + uabal2 v19.8h, v1.16b, v5.16b + subs w4, w4, #4 // h -= 4 + uabal v16.8h, v2.8b, v6.8b + uabal2 v17.8h, v2.16b, v6.16b + uabal v18.8h, v3.8b, v7.8b + uabal2 v19.8h, v3.16b, v7.16b + + b.gt 1b // if h > 0, loop + + add v16.8h, v16.8h, v17.8h + add v18.8h, v18.8h, v19.8h + add v16.8h, v16.8h, v18.8h + uaddlv s16, v16.8h // add up everything in v16 accumulator + fmov w0, s16 // copy result to general purpose register + ret +endfunc