avcodec/aarch64: add NEON lfe_x96_fixed for DCA DSP

Implement the fixed-point LFE x96 interpolation filter in AArch64
NEON. Four input samples are processed per iteration. The history
sample is kept in a vector lane, and ext constructs the delayed input.

Benchmarks by Martin Storsjö using checkasm:
               a53     a55    a520     a72     a76    a720
              1.86x   1.88x   1.24x   1.99x   1.62x   2.30x

Author's measurement on Neoverse-N1 (Oracle Cloud, clang 14): 1.29x.

Signed-off-by: Jeongkeun Kim <variety0724@gmail.com>
This commit is contained in:
Jeongkeun Kim
2026-08-09 00:18:08 +03:00
committed by Martin Storsjö
parent d920566afe
commit 280fd60916
2 changed files with 41 additions and 0 deletions
+3
View File
@@ -30,6 +30,8 @@ void ff_lfe_fir0_float_neon(float *pcm_samples, const int32_t *lfe_samples,
const float *filter_coeff, ptrdiff_t npcmblocks);
void ff_lfe_fir1_float_neon(float *pcm_samples, const int32_t *lfe_samples,
const float *filter_coeff, ptrdiff_t npcmblocks);
void ff_lfe_x96_fixed_neon(int32_t *dst, const int32_t *src,
int32_t *hist, ptrdiff_t len);
av_cold void ff_dcadsp_init_aarch64(DCADSPContext *s)
{
@@ -38,5 +40,6 @@ av_cold void ff_dcadsp_init_aarch64(DCADSPContext *s)
if (have_neon(cpu_flags)) {
s->lfe_fir_float[0] = ff_lfe_fir0_float_neon;
s->lfe_fir_float[1] = ff_lfe_fir1_float_neon;
s->lfe_x96_fixed = ff_lfe_x96_fixed_neon;
}
}
+38
View File
@@ -111,3 +111,41 @@ function ff_lfe_fir1_float_neon, export=1
b.gt .Louter1
ret
endfunc
function ff_lfe_x96_fixed_neon, export=1
ldr w4, [x2]
dup v2.4s, w4
mov w4, #0x013F
movk w4, #0x0020, lsl #16
dup v3.4s, w4
mov w4, #0xFEC1
movk w4, #0x005F, lsl #16
dup v4.4s, w4
.Lx96d_loop:
ld1 {v0.4s}, [x1], #16
subs x3, x3, #4
ext v1.16b, v2.16b, v0.16b, #12
smull v5.2d, v0.2s, v3.2s
smull2 v6.2d, v0.4s, v3.4s
smlal v5.2d, v1.2s, v4.2s
smlal2 v6.2d, v1.4s, v4.4s
smull v7.2d, v0.2s, v4.2s
smull2 v16.2d, v0.4s, v4.4s
smlal v7.2d, v1.2s, v3.2s
smlal2 v16.2d, v1.4s, v3.4s
mov v2.16b, v0.16b
sqrshrn v17.2s, v5.2d, #23
sqrshrn2 v17.4s, v6.2d, #23
sqrshrn v18.2s, v7.2d, #23
sqrshrn2 v18.4s, v16.2d, #23
sqshl v17.4s, v17.4s, #8
sqshl v18.4s, v18.4s, #8
sshr v17.4s, v17.4s, #8
sshr v18.4s, v18.4s, #8
zip1 v19.4s, v17.4s, v18.4s
zip2 v20.4s, v17.4s, v18.4s
st1 {v19.4s, v20.4s}, [x0], #32
b.gt .Lx96d_loop
st1 {v2.s}[3], [x2]
ret
endfunc