From 32f7665673f49f0a45c7bd11ddca2a52e41e5bfa Mon Sep 17 00:00:00 2001 From: Anthony Roberts Date: Tue, 27 May 2025 10:20:48 +0200 Subject: [PATCH] Deps: Add support for ARM64 assembly in x264 and update FFmpeg version It appears that previously, assembly was straight up disabled for all ARM64 platforms in x264 - this re-enables it. This also updates the version of FFmpeg to 7.1.1. I updated the patch files so that they would cleanly apply to 7.1.1. For Windows ARM64, it also switches both of these libraries to use the copy of LLVM we build as part of the deps, instead of MSVC - this gives a small performance increase. To do this for x264, I added a small patch taken from VCPKG - this should be harmless to other platforms. With all these changes, I was able to get a ~20-30% perf improvement in video transcoding in the sequence editor. Pull Request: https://projects.blender.org/blender/blender/pulls/137670 --- .../build_environment/cmake/ffmpeg.cmake | 24 ++++++++++++------- .../build_environment/cmake/options.cmake | 13 ++++++++++ .../build_environment/cmake/setup_msys2.cmake | 4 ++-- .../build_environment/cmake/versions.cmake | 4 ++-- .../build_environment/cmake/x264.cmake | 22 +++++++++++++---- .../build_environment/patches/ffmpeg.diff | 16 +++++++------ .../patches/ffmpeg_windows.diff | 21 +++++++++------- .../patches/x264_enable_clang-cl.diff | 15 ++++++++++++ source/creator/CMakeLists.txt | 13 +++++++++- 9 files changed, 97 insertions(+), 35 deletions(-) create mode 100644 build_files/build_environment/patches/x264_enable_clang-cl.diff diff --git a/build_files/build_environment/cmake/ffmpeg.cmake b/build_files/build_environment/cmake/ffmpeg.cmake index 00cc4ff242f..6c5141e6c05 100644 --- a/build_files/build_environment/cmake/ffmpeg.cmake +++ b/build_files/build_environment/cmake/ffmpeg.cmake @@ -101,25 +101,25 @@ if(WIN32) --disable-mediafoundation --toolchain=msvc --target-os=win32 - --disable-inline-asm ) if(BLENDER_PLATFORM_ARM) set(FFMPEG_EXTRA_FLAGS ${FFMPEG_EXTRA_FLAGS} --arch=aarch64 - --enable-cross-compile - --as=armasm64 + "--as=${DOWNLOAD_DIR}/msys2/msys64/usr/bin/gas-preprocessor.pl -arch aarch64 -as-type armasm -- armasm64 -nologo" + --cc=${LIBDIR}/llvm/bin/clang-cl.exe + --cxx=${LIBDIR}/llvm/bin/clang-cl.exe + --windres=${LIBDIR}/llvm/bin/llvm-rc.exe + --nm=${LIBDIR}/llvm/bin/llvm-nm.exe + --ar='${LIBDIR}/llvm/bin/llvm-ar.exe' + --ranlib=${LIBDIR}/llvm/bin/llvm-ranlib.exe ) - - set(GAS_PATH ${BUILD_DIR}/x264/src/external_x264/tools/) - string(REPLACE "/" "\\" GAS_PATH ${GAS_PATH}) - set(ENV{PATH} "$ENV{PATH};${GAS_PATH}") else() set(FFMPEG_EXTRA_FLAGS ${FFMPEG_EXTRA_FLAGS} + --disable-inline-asm --arch=x86_64 - --target-os=win32 ) endif() @@ -207,7 +207,6 @@ ExternalProject_Add(external_ffmpeg --disable-indev=jack --disable-indev=alsa --disable-outdev=alsa - --disable-crystalhd --disable-sndio --disable-doc @@ -251,6 +250,13 @@ if(WIN32) external_zlib external_openjpeg_msvc ) + + if(BLENDER_PLATFORM_ARM) + add_dependencies( + external_ffmpeg + ll + ) + endif() endif() if(UNIX) add_dependencies( diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake index 1924aa0e853..1db7ced4f37 100644 --- a/build_files/build_environment/cmake/options.cmake +++ b/build_files/build_environment/cmake/options.cmake @@ -189,6 +189,19 @@ if(WIN32) set LDFLAGS=${MINGW_LDFLAGS} ) + set(CONFIGURE_ENV_CLANG_CL_NO_PERL + cd ${MINGW_PATH} && + call ${MINGW_SHELL} && + set path && + set CC=${LIBDIR}/llvm/bin/clang-cl.exe && + set CXX=${LIBDIR}/llvm/bin/clang-cl.exe && + set RANLIB=${LIBDIR}/llvm/bin/llvm-ranlib.exe && + set RC=${LIBDIR}/llvm/bin/llvm-rc.exe && + set AR=${LIBDIR}/llvm/bin/llvm-ar.exe && + set CFLAGS=${MINGW_CFLAGS} && + set LDFLAGS=${MINGW_LDFLAGS} + ) + set(CONFIGURE_COMMAND sh ./configure) set(CONFIGURE_COMMAND_NO_TARGET ${CONFIGURE_COMMAND}) else() diff --git a/build_files/build_environment/cmake/setup_msys2.cmake b/build_files/build_environment/cmake/setup_msys2.cmake index ed5ac017463..cf3c4068f88 100644 --- a/build_files/build_environment/cmake/setup_msys2.cmake +++ b/build_files/build_environment/cmake/setup_msys2.cmake @@ -65,8 +65,8 @@ set(MSYS2_NASM_HASH 6ae5eaffde68aa7450fadd7f45ba5c6df3dce558) set(MSYS2_PERL_URL https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_5380_5361/strawberry-perl-5.38.0.1-64bit-portable.zip) set(MSYS2_PERL_HASH 987c870cc2401e481e3ddbdd1462d2a52da34187) -set(MSYS2_GAS_URL https://raw.githubusercontent.com/FFmpeg/gas-preprocessor/9309c67acb535ca6248f092e96131d8eb07eefc1/gas-preprocessor.pl) -set(MSYS2_GAS_HASH d86e756793eb37a269f06e20538d2bb3141ec24a) +set(MSYS2_GAS_URL https://raw.githubusercontent.com/FFmpeg/gas-preprocessor/7380ac24e1cd23a5e6d76c6af083d8fc5ab9e943/gas-preprocessor.pl) +set(MSYS2_GAS_HASH 313c45e9ae7e4b6c13475e65ee4063593dac2cbe) set(MSYS2_AR_URL https://raw.githubusercontent.com/gcc-mirror/gcc/releases/gcc-12.2.0/ar-lib) set(MSYS2_AR_HASH 77194f45708a80f502102fa881a8a5cb048b03af) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 0986215f381..e275529c8c4 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -581,9 +581,9 @@ Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France. Copyright (c) 2012, CS Systemes d'Information, France. ]=]) -set(FFMPEG_VERSION 6.1.1) +set(FFMPEG_VERSION 7.1.1) set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2) -set(FFMPEG_HASH 5e3133939a61ef64ac9b47ffd29a5ea6e337a4023ef0ad972094b4da844e3a20) +set(FFMPEG_HASH 0c8da2f11579a01e014fc007cbacf5bb4da1d06afd0b43c7f8097ec7c0f143ba) set(FFMPEG_HASH_TYPE SHA256) set(FFMPEG_FILE ffmpeg-${FFMPEG_VERSION}.tar.bz2) set(FFMPEG_CPE "cpe:2.3:a:ffmpeg:ffmpeg:${FFMPEG_VERSION}:*:*:*:*:*:*:*") diff --git a/build_files/build_environment/cmake/x264.cmake b/build_files/build_environment/cmake/x264.cmake index 718ef187950..9d771e4dcc6 100644 --- a/build_files/build_environment/cmake/x264.cmake +++ b/build_files/build_environment/cmake/x264.cmake @@ -6,16 +6,19 @@ if(WIN32) set(X264_EXTRA_ARGS --enable-win32thread) endif() -if(BLENDER_PLATFORM_ARM) - set(X264_EXTRA_ARGS ${X264_EXTRA_ARGS} "--disable-asm") -endif() - if((APPLE AND NOT BLENDER_PLATFORM_ARM) OR (UNIX AND NOT APPLE)) set(X264_CONFIGURE_ENV ${CONFIGURE_ENV} && export AS=${LIBDIR}/nasm/bin/nasm ) elseif(WIN32) - set(X264_CONFIGURE_ENV ${CONFIGURE_ENV_NO_PERL}) + if(BLENDER_PLATFORM_ARM) + set(X264_CONFIGURE_ENV + ${CONFIGURE_ENV_CLANG_CL_NO_PERL} && + set "AS=${DOWNLOAD_DIR}/msys2/msys64/usr/bin/gas-preprocessor.pl -arch aarch64 -as-type armasm -- armasm64 -nologo" + ) + else() + set(X264_CONFIGURE_ENV ${CONFIGURE_ENV_NO_PERL}) + endif() else() set(X264_CONFIGURE_ENV ${CONFIGURE_ENV}) endif() @@ -24,6 +27,9 @@ ExternalProject_Add(external_x264 URL file://${PACKAGE_DIR}/${X264_FILE} DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH ${X264_HASH_TYPE}=${X264_HASH} + PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d + ${BUILD_DIR}/x264/src/external_x264 < + ${PATCH_DIR}/x264_enable_clang-cl.diff PREFIX ${BUILD_DIR}/x264 CONFIGURE_COMMAND ${X264_CONFIGURE_ENV} && @@ -47,6 +53,12 @@ ExternalProject_Add(external_x264 if(WIN32) set_target_properties(external_x264 PROPERTIES FOLDER Mingw) + if(BLENDER_PLATFORM_ARM) + add_dependencies( + external_x264 + ll + ) + endif() else() add_dependencies( external_x264 diff --git a/build_files/build_environment/patches/ffmpeg.diff b/build_files/build_environment/patches/ffmpeg.diff index 49cb76fc279..9cd05b53020 100644 --- a/build_files/build_environment/patches/ffmpeg.diff +++ b/build_files/build_environment/patches/ffmpeg.diff @@ -1,15 +1,17 @@ ---- a/configure 2018-08-27 13:46:41.071106150 +0200 -+++ b/configure 2018-08-27 13:46:28.162765762 +0200 -@@ -6768,7 +6768,7 @@ +diff --git a/configure b/configure +index ffa407d53d..d291f87187 100755 +--- a/configure ++++ b/configure +@@ -6964,7 +6964,7 @@ enabled libopencv && { check_headers opencv2/core/core_c.h && require_pkg_config libopencv opencv opencv/cxcore.h cvCreateImageHeader; } - enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_api.h WelsGetCodecVersion + enabled libopenh264 && require_pkg_config libopenh264 "openh264 >= 1.3.0" wels/codec_api.h WelsGetCodecVersion enabled libopenjpeg && { check_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version || - { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } } + { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version "-DOPJ_STATIC $pthreads_extralibs $libm_extralibs" && add_cppflags "-DOPJ_STATIC $pthreads_extralibs $libm_extralibs"; } } enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++" enabled libopenvino && { { check_pkg_config libopenvino openvino openvino/c/openvino.h ov_core_create && enable openvino2; } || { check_pkg_config libopenvino openvino c_api/ie_c_api.h ie_c_api_version || -@@ -6812,8 +6812,8 @@ +@@ -7011,8 +7011,8 @@ enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 2.0.0" libvmaf.h vmaf_init enabled libvmaf && check_pkg_config libvmaf_cuda "libvmaf >= 2.0.0" libvmaf_cuda.h vmaf_cuda_state_init enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc @@ -20,9 +22,9 @@ enabled libvpx && { enabled libvpx_vp8_decoder && { -@@ -6845,7 +6845,7 @@ - [ "$toolchain" != "msvc" ] || +@@ -7046,7 +7046,7 @@ enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } && + check_cpp_condition libx264_hdr10 x264.h "X264_BUILD >= 163" && check_cpp_condition libx262 x264.h "X264_MPEG2" -enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get && +enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get "$pthreads_extralibs" && diff --git a/build_files/build_environment/patches/ffmpeg_windows.diff b/build_files/build_environment/patches/ffmpeg_windows.diff index adb992235c9..3c2786c3af0 100644 --- a/build_files/build_environment/patches/ffmpeg_windows.diff +++ b/build_files/build_environment/patches/ffmpeg_windows.diff @@ -1,18 +1,20 @@ ---- ffmpeg-6.1.1\configure 2023-12-30 16:07:26 -0700 -+++ external_ffmpeg\configure 2024-03-18 13:17:59 -0600 -@@ -6675,7 +6675,7 @@ +diff --git a/configure b/configure +index ffa407d53d..8a7cb7065c 100755 +--- a/configure ++++ b/configure +@@ -6865,7 +6865,7 @@ enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gn enabled jni && { [ $target_os = "android" ] && check_headers jni.h && enabled pthreads || die "ERROR: jni not found"; } enabled ladspa && require_headers "ladspa.h dlfcn.h" enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext --enabled libaom && require_pkg_config libaom "aom >= 1.0.0" aom/aom_codec.h aom_codec_version +-enabled libaom && require_pkg_config libaom "aom >= 2.0.0" aom/aom_codec.h aom_codec_version +enabled libaom && { require libaom aom/aom_codec.h aom_codec_version -laom; } enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new || { enabled gpl && require_pkg_config libaribb24 aribb24 "aribb24/aribb24.h" arib_instance_new; } || die "ERROR: libaribb24 requires version higher than 1.0.3 or --enable-gpl."; } -@@ -6767,18 +6767,17 @@ +@@ -6963,18 +6963,17 @@ enabled libopencv && { check_headers opencv2/core/core_c.h && require libopencv opencv2/core/core_c.h cvCreateImageHeader -lopencv_core -lopencv_imgproc; } || require_pkg_config libopencv opencv opencv/cxcore.h cvCreateImageHeader; } - enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_api.h WelsGetCodecVersion + enabled libopenh264 && require_pkg_config libopenh264 "openh264 >= 1.3.0" wels/codec_api.h WelsGetCodecVersion -enabled libopenjpeg && { check_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version || - { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } } +enabled libopenjpeg && require libopenjpeg openjpeg.h opj_version "-DOPJ_STATIC" -lopenjp2 @@ -31,7 +33,7 @@ } } enabled libplacebo && require_pkg_config libplacebo "libplacebo >= 4.192.0" libplacebo/vulkan.h pl_vulkan_create -@@ -6812,8 +6811,8 @@ +@@ -7011,8 +7010,8 @@ enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 2.0.0" libvmaf.h vmaf_init enabled libvmaf && check_pkg_config libvmaf_cuda "libvmaf >= 2.0.0" libvmaf_cuda.h vmaf_cuda_state_init enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc @@ -42,15 +44,16 @@ enabled libvpx && { enabled libvpx_vp8_decoder && { -@@ -6840,12 +6839,12 @@ +@@ -7040,13 +7039,13 @@ enabled libvvenc && require_pkg_config libvvenc "libvvenc >= 1.6.1" "vv enabled libwebp && { enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; } -enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode && +enabled libx264 && require libx264 "stdint.h x264.h" x264_encoder_encode -lx264 && - require_cpp_condition libx264 x264.h "X264_BUILD >= 122" && { + require_cpp_condition libx264 x264.h "X264_BUILD >= 155" && { [ "$toolchain" != "msvc" ] || require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } && + check_cpp_condition libx264_hdr10 x264.h "X264_BUILD >= 163" && check_cpp_condition libx262 x264.h "X264_MPEG2" -enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get && +enabled libx265 && require libx265 "x265.h" x265_api_get -lx265 && diff --git a/build_files/build_environment/patches/x264_enable_clang-cl.diff b/build_files/build_environment/patches/x264_enable_clang-cl.diff new file mode 100644 index 00000000000..c4fe44ddb01 --- /dev/null +++ b/build_files/build_environment/patches/x264_enable_clang-cl.diff @@ -0,0 +1,15 @@ +diff --git a/configure b/configure +index 6f95e2314..e677e36f4 100644 +--- a/configure ++++ b/configure +@@ -606,9 +606,9 @@ if [[ $host_os = mingw* || $host_os = msys* || $host_os = cygwin* ]]; then + if cc_check '' -Qdiag-error:10006,10157 ; then + CHECK_CFLAGS="$CHECK_CFLAGS -Qdiag-error:10006,10157" + fi +- elif [[ "$cc_base" = cl || "$cc_base" = cl[\ .]* ]]; then ++ elif [[ "$cc_base" = cl || "$cc_base" = cl[\ .]* || "$cc_base" = clang-cl || "$cc_base" = clang-cl[\ .]* ]]; then + # Standard Microsoft Visual Studio + compiler=CL + compiler_style=MS + CFLAGS="$CFLAGS -nologo -GS- -DHAVE_STRING_H -I\$(SRCPATH)/extras" + cpp_check '' '' '_MSC_VER > 1800 || (_MSC_VER == 1800 && _MSC_FULL_VER >= 180030324)' || die "Microsoft Visual Studio support requires Visual Studio 2013 Update 2 or newer" diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 296fb6b779e..30094afd520 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -1422,7 +1422,18 @@ elseif(WIN32) # Filenames change slightly between FFMPEG versions check both 6.0 and fallback to 5.0 # to ease the transition between versions. - if(EXISTS "${LIBDIR}/ffmpeg/lib/avcodec-60.dll") + if(EXISTS "${LIBDIR}/ffmpeg/lib/avcodec-61.dll") + windows_install_shared_manifest( + FILES + ${LIBDIR}/ffmpeg/lib/avcodec-61.dll + ${LIBDIR}/ffmpeg/lib/avformat-61.dll + ${LIBDIR}/ffmpeg/lib/avdevice-61.dll + ${LIBDIR}/ffmpeg/lib/avutil-59.dll + ${LIBDIR}/ffmpeg/lib/swscale-8.dll + ${LIBDIR}/ffmpeg/lib/swresample-5.dll + ALL + ) + elseif(EXISTS "${LIBDIR}/ffmpeg/lib/avcodec-60.dll") windows_install_shared_manifest( FILES ${LIBDIR}/ffmpeg/lib/avcodec-60.dll