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]

Reply via email to