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]
