This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit bdc6a848f0b9bd2286ce5805efcf73e59d60caee Author: Shreesh Adiga <[email protected]> AuthorDate: Fri Jul 10 20:17:12 2026 +0530 Commit: Martin Storsjö <[email protected]> CommitDate: Wed Sep 16 06:29:59 2026 +0000 avutil/aes: add aarch64 NEON implementation Ported the x86 AES-NI implementation to aarch64 NEON using AES extension. Benchmarking on A720 core reports about 50x speedup: checkasm: all 6 tests passed Benchmark results: name nsecs (vs ref) aes_decrypt_128_c: 5671.2 aes_decrypt_128_aes: 92.3 (61.40x) aes_decrypt_192_c: 7031.2 aes_decrypt_192_aes: 112.2 (62.65x) aes_decrypt_256_c: 8107.5 aes_decrypt_256_aes: 131.2 (61.74x) aes_encrypt_128_c: 5838.7 aes_encrypt_128_aes: 101.9 (57.24x) aes_encrypt_192_c: 7058.7 aes_encrypt_192_aes: 120.4 (58.61x) aes_encrypt_256_c: 7952.2 aes_encrypt_256_aes: 136.1 (54.44x) --- libavutil/aarch64/Makefile | 6 +- libavutil/aarch64/aes.S | 127 +++++++++++++++++++++++++++++++++++++++++++ libavutil/aarch64/aes_init.c | 50 +++++++++++++++++ libavutil/aes.c | 2 + libavutil/aes_internal.h | 1 + 5 files changed, 184 insertions(+), 2 deletions(-) diff --git a/libavutil/aarch64/Makefile b/libavutil/aarch64/Makefile index 8a7e7ca057..ba5e0a4a6a 100644 --- a/libavutil/aarch64/Makefile +++ b/libavutil/aarch64/Makefile @@ -1,10 +1,12 @@ -OBJS += aarch64/cpu.o \ +OBJS += aarch64/aes_init.o \ + aarch64/cpu.o \ aarch64/float_dsp_init.o \ aarch64/tx_float_init.o \ ARMV8-OBJS += aarch64/crc.o -NEON-OBJS += aarch64/float_dsp_neon.o \ +NEON-OBJS += aarch64/aes.o \ + aarch64/float_dsp_neon.o \ aarch64/tx_float_neon.o \ NEON-OBJS-$(CONFIG_PIXELUTILS) += aarch64/pixelutils_neon.o diff --git a/libavutil/aarch64/aes.S b/libavutil/aarch64/aes.S new file mode 100644 index 0000000000..24080b0fb6 --- /dev/null +++ b/libavutil/aarch64/aes.S @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2026 Shreesh Adiga <[email protected]> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "asm.S" + +#if HAVE_ARM_AES +ENABLE_ARM_AES + +.macro aesenc x, y + aese \x, \y + aesmc \x, \x +.endm + +.macro aesenclast x, y + aese \x, \y +.endm + +.macro aesdec x, y + aesd \x, \y + aesimc \x, \x +.endm + +.macro aesdeclast x, y + aesd \x, \y +.endm + +.macro AES_CRYPT op, rounds +//----------------------------------------------------------------------------- +// void ff_aes_[enc|dec]rypt_N_neon(AVAES *a, uint8_t *dst, const uint8_t *src, +// int count, uint8_t *iv, int rounds) +//----------------------------------------------------------------------------- +function ff_aes_\op\()rypt_\rounds\()_neon, export=1 + cbz w3, 3f + ubfiz x3, x3, #4, #32 // x3 = w3 << 4 + add x2, x2, x3 + add x1, x1, x3 + neg x3, x3 + movi v1.2d, #0 + .if \rounds == 14 + ldr q31, [x0, #(8*2*\rounds)] + ldp q29, q30, [x0, #0xc0] + ldp q27, q28, [x0, #0xa0] + .elseif \rounds == 12 + ldr q29, [x0, #(8*2*\rounds)] + ldp q27, q28, [x0, #0xa0] + .else + ldr q27, [x0, #(8*2*\rounds)] + .endif + ldp q25, q26, [x0, #0x80] + ldp q23, q24, [x0, #0x60] + ldp q21, q22, [x0, #0x40] + ldp q19, q20, [x0, #0x20] + ldp q17, q18, [x0] + cbz x4, 1f + ldr q1, [x4] +1: + ldr q0, [x2, x3] + .ifc \op, enc + eor v0.16b, v0.16b, v1.16b + .endif + .if \rounds > 10 + .if \rounds > 12 + aes\op v0.16b, v31.16b + aes\op v0.16b, v30.16b + .endif + aes\op v0.16b, v29.16b + aes\op v0.16b, v28.16b + .endif + aes\op v0.16b, v27.16b + aes\op v0.16b, v26.16b + aes\op v0.16b, v25.16b + aes\op v0.16b, v24.16b + aes\op v0.16b, v23.16b + aes\op v0.16b, v22.16b + aes\op v0.16b, v21.16b + aes\op v0.16b, v20.16b + aes\op v0.16b, v19.16b + aes\op\()last v0.16b, v18.16b + eor v0.16b, v0.16b, v17.16b + cbz x4, 2f + .ifc \op, enc + mov v1.16b, v0.16b + .else + eor v0.16b, v0.16b, v1.16b + ldr q1, [x2, x3] + .endif +2: + str q0, [x1, x3] + adds x3, x3, #16 + b.lt 1b + cbz x4, 3f + .ifc \op, dec + str q1, [x4] + .else + str q0, [x4] + .endif +3: + ret +endfunc +.endm + +AES_CRYPT enc, 10 +AES_CRYPT enc, 12 +AES_CRYPT enc, 14 +AES_CRYPT dec, 10 +AES_CRYPT dec, 12 +AES_CRYPT dec, 14 + +DISABLE_ARM_AES +#endif diff --git a/libavutil/aarch64/aes_init.c b/libavutil/aarch64/aes_init.c new file mode 100644 index 0000000000..60bdc0574c --- /dev/null +++ b/libavutil/aarch64/aes_init.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2026 Shreesh Adiga <[email protected]> + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stddef.h> +#include "libavutil/aes_internal.h" +#include "libavutil/aarch64/cpu.h" + +void ff_aes_decrypt_10_neon(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds); +void ff_aes_decrypt_12_neon(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds); +void ff_aes_decrypt_14_neon(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds); +void ff_aes_encrypt_10_neon(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds); +void ff_aes_encrypt_12_neon(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds); +void ff_aes_encrypt_14_neon(AVAES *a, uint8_t *dst, const uint8_t *src, + int count, uint8_t *iv, int rounds); + +void ff_init_aes_aarch64(AVAES *a, int decrypt) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_arm_aes(cpu_flags)) { + if (a->rounds == 10) + a->crypt = decrypt ? ff_aes_decrypt_10_neon : ff_aes_encrypt_10_neon; + else if (a->rounds == 12) + a->crypt = decrypt ? ff_aes_decrypt_12_neon : ff_aes_encrypt_12_neon; + else if (a->rounds == 14) + a->crypt = decrypt ? ff_aes_decrypt_14_neon : ff_aes_encrypt_14_neon; + } +} diff --git a/libavutil/aes.c b/libavutil/aes.c index 13fadb4a47..9ca9268b65 100644 --- a/libavutil/aes.c +++ b/libavutil/aes.c @@ -239,6 +239,8 @@ int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) a->crypt = decrypt ? aes_decrypt : aes_encrypt; #if ARCH_X86 && HAVE_X86ASM && HAVE_AESNI_EXTERNAL ff_init_aes_x86(a, decrypt); +#elif ARCH_AARCH64 && HAVE_ARM_AES + ff_init_aes_aarch64(a, decrypt); #endif ff_thread_once(&aes_static_init, aes_init_static); diff --git a/libavutil/aes_internal.h b/libavutil/aes_internal.h index 17f79d3ce3..92b5a9802a 100644 --- a/libavutil/aes_internal.h +++ b/libavutil/aes_internal.h @@ -41,5 +41,6 @@ typedef struct AVAES { } AVAES; void ff_init_aes_x86(AVAES *a, int decrypt); +void ff_init_aes_aarch64(AVAES *a, int decrypt); #endif /* AVUTIL_AES_INTERNAL_H */ -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
