PR #23815 opened by Ramiro Polla (ramiro)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23815
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23815.patch


>From e8065d70ba7e3bd0cfc9af1a6d63e5f6a16d87be Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Thu, 25 Jun 2026 23:30:35 +0200
Subject: [PATCH 1/2] swscale/jit: move jit-related code to its own file

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <[email protected]>
---
 libswscale/Makefile |   1 +
 libswscale/jit.c    | 101 ++++++++++++++++++++++++++++++++++++++++++++
 libswscale/jit.h    |  35 +++++++++++++++
 libswscale/utils.c  |  73 ++++----------------------------
 4 files changed, 145 insertions(+), 65 deletions(-)
 create mode 100644 libswscale/jit.c
 create mode 100644 libswscale/jit.h

diff --git a/libswscale/Makefile b/libswscale/Makefile
index 9c3aae2304..b53b815309 100644
--- a/libswscale/Makefile
+++ b/libswscale/Makefile
@@ -16,6 +16,7 @@ OBJS = alphablend.o                                     \
        gamma.o                                          \
        graph.o                                          \
        input.o                                          \
+       jit.o                                            \
        lut3d.o                                          \
        options.o                                        \
        output.o                                         \
diff --git a/libswscale/jit.c b/libswscale/jit.c
new file mode 100644
index 0000000000..a98cb5ac2f
--- /dev/null
+++ b/libswscale/jit.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2005 Aurelien Jacobs <[email protected]>
+ * Copyright (C) 2009, 2026 Ramiro Polla <[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 "config.h"
+
+#include "libavutil/error.h"
+
+#include "jit.h"
+
+#if HAVE_MMAP && HAVE_MPROTECT
+#   define _DEFAULT_SOURCE
+#   define _SVID_SOURCE // needed for MAP_ANONYMOUS
+#   define _DARWIN_C_SOURCE // needed for MAP_ANON
+#   include <sys/mman.h>
+#   if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
+#       define MAP_ANONYMOUS MAP_ANON
+#   endif
+#endif
+
+#if HAVE_MMAP && HAVE_MPROTECT && defined(MAP_ANONYMOUS)
+
+void *ff_sws_jit_alloc(size_t size)
+{
+    void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
+                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    if (ptr == MAP_FAILED)
+        return NULL;
+    return ptr;
+}
+
+int ff_sws_jit_protect(void *ptr, size_t size)
+{
+    if (mprotect(ptr, size, PROT_READ | PROT_EXEC) == -1)
+        return AVERROR(errno);
+    return 0;
+}
+
+void ff_sws_jit_free(void *ptr, size_t size)
+{
+    if (ptr)
+        munmap(ptr, size);
+}
+
+#elif HAVE_VIRTUALALLOC
+
+#include <windows.h>
+
+void *ff_sws_jit_alloc(size_t size)
+{
+    return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+}
+
+int ff_sws_jit_protect(void *ptr, size_t size)
+{
+    return 0;
+}
+
+void ff_sws_jit_free(void *ptr, size_t size)
+{
+    if (ptr)
+        VirtualFree(ptr, 0, MEM_RELEASE);
+}
+
+#else
+
+#include "libavutil/mem.h"
+
+void *ff_sws_jit_alloc(size_t size)
+{
+    return av_malloc(size);
+}
+
+int ff_sws_jit_protect(void *ptr, size_t size)
+{
+    return 0;
+}
+
+void ff_sws_jit_free(void *ptr, size_t size)
+{
+    av_free(ptr);
+}
+
+#endif
diff --git a/libswscale/jit.h b/libswscale/jit.h
new file mode 100644
index 0000000000..a8778f41b5
--- /dev/null
+++ b/libswscale/jit.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2026 Ramiro Polla <[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
+ */
+
+#ifndef SWSCALE_JIT_H
+#define SWSCALE_JIT_H
+
+#include <stddef.h>
+
+/* Allocate size bytes of writable memory for JIT code generation. */
+void *ff_sws_jit_alloc(size_t size);
+
+/* Protect JIT memory from further writes. */
+int ff_sws_jit_protect(void *ptr, size_t size);
+
+/* Free memory allocated by ff_sws_jit_alloc(). */
+void ff_sws_jit_free(void *ptr, size_t size);
+
+#endif /* SWSCALE_JIT_H */
diff --git a/libswscale/utils.c b/libswscale/utils.c
index fa070c270a..31d2e6e111 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -22,21 +22,10 @@
 #include "config.h"
 
 #define _DEFAULT_SOURCE
-#define _SVID_SOURCE // needed for MAP_ANONYMOUS
-#define _DARWIN_C_SOURCE // needed for MAP_ANON
 #include <inttypes.h>
 #include <math.h>
 #include <stdio.h>
 #include <string.h>
-#if HAVE_MMAP
-#include <sys/mman.h>
-#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-#endif
-#if HAVE_VIRTUALALLOC
-#include <windows.h>
-#endif
 
 #include "libavutil/attributes.h"
 #include "libavutil/avassert.h"
@@ -63,6 +52,7 @@
 #include "swscale.h"
 #include "swscale_internal.h"
 #include "graph.h"
+#include "jit.h"
 
 #if CONFIG_VULKAN
 #include "vulkan/ops.h"
@@ -1647,12 +1637,6 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, 
SwsFilter *srcFilter,
         }
     }
 
-#if HAVE_MMAP && HAVE_MPROTECT && defined(MAP_ANONYMOUS)
-#define USE_MMAP 1
-#else
-#define USE_MMAP 0
-#endif
-
     /* precalculate horizontal scaler filter coefficients */
     {
 #if HAVE_MMXEXT_INLINE
@@ -1663,35 +1647,9 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, 
SwsFilter *srcFilter,
             c->chrMmxextFilterCodeSize = ff_init_hscaler_mmxext(c->chrDstW, 
c->chrXInc,
                                                              NULL, NULL, NULL, 
4);
 
-#if USE_MMAP
-            c->lumMmxextFilterCode = mmap(NULL, c->lumMmxextFilterCodeSize,
-                                          PROT_READ | PROT_WRITE,
-                                          MAP_PRIVATE | MAP_ANONYMOUS,
-                                          -1, 0);
-            c->chrMmxextFilterCode = mmap(NULL, c->chrMmxextFilterCodeSize,
-                                          PROT_READ | PROT_WRITE,
-                                          MAP_PRIVATE | MAP_ANONYMOUS,
-                                          -1, 0);
-#elif HAVE_VIRTUALALLOC
-            c->lumMmxextFilterCode = VirtualAlloc(NULL,
-                                                  c->lumMmxextFilterCodeSize,
-                                                  MEM_COMMIT,
-                                                  PAGE_EXECUTE_READWRITE);
-            c->chrMmxextFilterCode = VirtualAlloc(NULL,
-                                                  c->chrMmxextFilterCodeSize,
-                                                  MEM_COMMIT,
-                                                  PAGE_EXECUTE_READWRITE);
-#else
-            c->lumMmxextFilterCode = av_malloc(c->lumMmxextFilterCodeSize);
-            c->chrMmxextFilterCode = av_malloc(c->chrMmxextFilterCodeSize);
-#endif
-
-#ifdef MAP_ANONYMOUS
-            if (c->lumMmxextFilterCode == MAP_FAILED || c->chrMmxextFilterCode 
== MAP_FAILED)
-#else
-            if (!c->lumMmxextFilterCode || !c->chrMmxextFilterCode)
-#endif
-            {
+            c->lumMmxextFilterCode = 
ff_sws_jit_alloc(c->lumMmxextFilterCodeSize);
+            c->chrMmxextFilterCode = 
ff_sws_jit_alloc(c->chrMmxextFilterCodeSize);
+            if (!c->lumMmxextFilterCode || !c->chrMmxextFilterCode) {
                 av_log(c, AV_LOG_ERROR, "Failed to allocate MMX2FilterCode\n");
                 return AVERROR(ENOMEM);
             }
@@ -1707,14 +1665,11 @@ av_cold int ff_sws_init_single_context(SwsContext *sws, 
SwsFilter *srcFilter,
             ff_init_hscaler_mmxext(c->chrDstW, c->chrXInc, 
c->chrMmxextFilterCode,
                                 c->hChrFilter, (uint32_t*)c->hChrFilterPos, 4);
 
-#if USE_MMAP
-            if (   mprotect(c->lumMmxextFilterCode, 
c->lumMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1
-                || mprotect(c->chrMmxextFilterCode, 
c->chrMmxextFilterCodeSize, PROT_EXEC | PROT_READ) == -1) {
+            if ((ret = ff_sws_jit_protect(c->lumMmxextFilterCode, 
c->lumMmxextFilterCodeSize)) < 0 ||
+                (ret = ff_sws_jit_protect(c->chrMmxextFilterCode, 
c->chrMmxextFilterCodeSize)) < 0) {
                 av_log(c, AV_LOG_ERROR, "mprotect failed, cannot use fast 
bilinear scaler\n");
-                ret = AVERROR(EINVAL);
                 goto fail;
             }
-#endif
         } else
 #endif /* HAVE_MMXEXT_INLINE */
         {
@@ -2336,20 +2291,8 @@ void sws_freeContext(SwsContext *sws)
     av_freep(&c->hChrFilterPos);
 
 #if HAVE_MMX_INLINE
-#if USE_MMAP
-    if (c->lumMmxextFilterCode)
-        munmap(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize);
-    if (c->chrMmxextFilterCode)
-        munmap(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize);
-#elif HAVE_VIRTUALALLOC
-    if (c->lumMmxextFilterCode)
-        VirtualFree(c->lumMmxextFilterCode, 0, MEM_RELEASE);
-    if (c->chrMmxextFilterCode)
-        VirtualFree(c->chrMmxextFilterCode, 0, MEM_RELEASE);
-#else
-    av_free(c->lumMmxextFilterCode);
-    av_free(c->chrMmxextFilterCode);
-#endif
+    ff_sws_jit_free(c->lumMmxextFilterCode, c->lumMmxextFilterCodeSize);
+    ff_sws_jit_free(c->chrMmxextFilterCode, c->chrMmxextFilterCodeSize);
     c->lumMmxextFilterCode = NULL;
     c->chrMmxextFilterCode = NULL;
 #endif /* HAVE_MMX_INLINE */
-- 
2.52.0


>From 3a464aefc1b6db77499ad04fdd2c541255e214a3 Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Thu, 25 Jun 2026 23:45:53 +0200
Subject: [PATCH 2/2] swscale/jit: implement ff_sws_jit_protect() for win32

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <[email protected]>
---
 libswscale/jit.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libswscale/jit.c b/libswscale/jit.c
index a98cb5ac2f..82e97b3cd5 100644
--- a/libswscale/jit.c
+++ b/libswscale/jit.c
@@ -70,6 +70,9 @@ void *ff_sws_jit_alloc(size_t size)
 
 int ff_sws_jit_protect(void *ptr, size_t size)
 {
+    DWORD old_protect;
+    if (!VirtualProtect(ptr, size, PAGE_EXECUTE_READ, &old_protect))
+        return AVERROR(EINVAL);
     return 0;
 }
 
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to