diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d8739fb00..6b88ddac67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,7 +165,8 @@ option(YUZU_USE_CPM "Use CPM to fetch system dependencies (fmt, boost, etc) if n option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) option(ENABLE_WIFI_SCAN "Enable WiFi scanning" OFF) -option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" ${EXT_DEFAULT}) +option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT}) +cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from source" OFF "NOT WIN32 AND NOT ANDROID" OFF) option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF) @@ -184,8 +185,6 @@ option(YUZU_USE_PRECOMPILED_HEADERS "Use precompiled headers" ${EXT_DEFAULT}) # TODO(crueter): CI this? option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON) -option(FORCE_DOWNLOAD_WIN_BUNDLES "Forcefully download bundled Windows dependencies (useful for CI)" OFF) - # TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "ENABLE_SDL2" OFF) @@ -579,6 +578,10 @@ if(ENABLE_CUBEB) ) endif() endif() + + if (NOT TARGET cubeb::cubeb) + add_library(cubeb::cubeb ALIAS cubeb) + endif() endif() # find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package @@ -662,10 +665,6 @@ if (ENABLE_WEB_SERVICE OR ENABLE_QT_UPDATE_CHECKER) find_package(cpp-jwt) endif() -if (ENABLE_SDL2) - find_package(SDL2) -endif() - if (ENABLE_QT) if (YUZU_USE_BUNDLED_QT) download_qt(6.8.3) @@ -738,9 +737,8 @@ if (UNIX AND NOT APPLE AND NOT ANDROID) pkg_check_modules(LIBVA libva) endif() -if (NOT YUZU_USE_BUNDLED_FFMPEG) +if (NOT (YUZU_USE_BUNDLED_FFMPEG OR YUZU_USE_EXTERNAL_FFMPEG)) # Use system installed FFmpeg - #find_package(FFmpeg 4.3 REQUIRED QUIET COMPONENTS ${FFmpeg_COMPONENTS}) find_package(FFmpeg REQUIRED QUIET COMPONENTS ${FFmpeg_COMPONENTS}) # TODO(crueter): Version diff --git a/CMakeModules/CPMUtil.cmake b/CMakeModules/CPMUtil.cmake index 6a1384e730..d84c069399 100644 --- a/CMakeModules/CPMUtil.cmake +++ b/CMakeModules/CPMUtil.cmake @@ -126,6 +126,15 @@ function(AddJsonPackage) DISABLED_PLATFORMS ${disabled_platforms} CMAKE_FILENAME ${cmake_filename} ) + + # pass stuff to parent scope + set(${package}_ADDED "${${package}_ADDED}" + PARENT_SCOPE) + set(${package}_SOURCE_DIR "${${package}_SOURCE_DIR}" + PARENT_SCOPE) + set(${package}_BINARY_DIR "${${package}_BINARY_DIR}" + PARENT_SCOPE) + return() endif() @@ -598,7 +607,9 @@ function(AddCIPackage) if (DEFINED ARTIFACT_DIR) include(${ARTIFACT_DIR}/${ARTIFACT_CMAKE}.cmake) + set(${ARTIFACT_PACKAGE}_ADDED TRUE PARENT_SCOPE) + set(${ARTIFACT_PACKAGE}_SOURCE_DIR "${ARTIFACT_DIR}" PARENT_SCOPE) else() find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED) endif() diff --git a/CMakeModules/DownloadExternals.cmake b/CMakeModules/DownloadExternals.cmake index 88fa183061..6c4afc03be 100644 --- a/CMakeModules/DownloadExternals.cmake +++ b/CMakeModules/DownloadExternals.cmake @@ -51,15 +51,6 @@ function(download_bundled_external remote_path lib_name cpm_key prefix_var versi message(STATUS "Using bundled binaries at ${${cpm_key}_SOURCE_DIR}") endfunction() -function(download_win_archives) - set(FORCE_WIN_ARCHIVES ON) - set(FFmpeg_EXT_NAME "ffmpeg-7.1.1") - - download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "ffmpeg-bundled" "" 7.1.1) - - set(FORCE_WIN_ARCHIVES OFF) -endfunction() - function(download_moltenvk_external platform version) set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK") set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar") diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index aba5451b6d..b46e624fb9 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -1,9 +1,6 @@ # SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later -# SPDX-FileCopyrightText: 2025 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - # SPDX-FileCopyrightText: 2016 Citra Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later @@ -28,10 +25,6 @@ set(BUILD_SHARED_LIBS OFF) # Skip install rules for all externals set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL ON) -if (FORCE_DOWNLOAD_WIN_BUNDLES) - download_win_archives() -endif() - # Xbyak (also used by Dynarmic, so needs to be added first) if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) if (PLATFORM_SUN OR PLATFORM_OPENBSD) @@ -100,11 +93,13 @@ endif() AddJsonPackage(unordered-dense) # FFMpeg -if (YUZU_USE_BUNDLED_FFMPEG) +if (YUZU_USE_EXTERNAL_FFMPEG OR YUZU_USE_BUNDLED_FFMPEG) add_subdirectory(ffmpeg) + set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE) set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE) set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE) + set(FFmpeg_LIBRARY_DIR "${FFmpeg_LIBRARY_DIR}" PARENT_SCOPE) set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE) endif() diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt index 8908aa234f..1b21dd711d 100644 --- a/externals/ffmpeg/CMakeLists.txt +++ b/externals/ffmpeg/CMakeLists.txt @@ -1,53 +1,14 @@ +# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + # SPDX-FileCopyrightText: 2021 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later include(CPMUtil) -if (NOT WIN32 AND NOT ANDROID) - # Build FFmpeg from externals - message(STATUS "Using FFmpeg from externals") - - if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|amd64)") - # FFmpeg has source that requires one of nasm or yasm to assemble it. - # REQUIRED throws an error if not found here during configuration rather than during compilation. - find_program(ASSEMBLER NAMES nasm yasm) - if ("${ASSEMBLER}" STREQUAL "ASSEMBLER-NOTFOUND") - message(FATAL_ERROR "One of either `nasm` or `yasm` not found but is required.") - endif() - endif() - - find_program(AUTOCONF autoconf) - if ("${AUTOCONF}" STREQUAL "AUTOCONF-NOTFOUND") - message(FATAL_ERROR "Required program `autoconf` not found.") - endif() - - AddJsonPackage(ffmpeg) - - set(FFmpeg_PREFIX ${ffmpeg_SOURCE_DIR}) - set(FFmpeg_BUILD_DIR ${ffmpeg_BINARY_DIR}) - set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile) - make_directory(${FFmpeg_BUILD_DIR}) - - # Read version string from external - file(READ ${FFmpeg_PREFIX}/RELEASE FFmpeg_VERSION) - set(FFmpeg_FOUND NO) - if (NOT FFmpeg_VERSION STREQUAL "") - set(FFmpeg_FOUND YES) - endif() - - unset(FFmpeg_LIBRARIES CACHE) - - foreach(COMPONENT ${FFmpeg_COMPONENTS}) - set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}") - set(FFmpeg_${COMPONENT}_LIB_NAME "lib${COMPONENT}.a") - set(FFmpeg_${COMPONENT}_LIBRARY "${FFmpeg_${COMPONENT}_PREFIX}/${FFmpeg_${COMPONENT}_LIB_NAME}") - - set(FFmpeg_LIBRARIES - ${FFmpeg_LIBRARIES} - ${FFmpeg_${COMPONENT}_LIBRARY} - CACHE PATH "Paths to FFmpeg libraries" FORCE) - endforeach() +# TODO(crueter, MaranBr): Externals FFmpeg 8.0 +if (UNIX) find_package(PkgConfig REQUIRED) if (NOT ANDROID) pkg_check_modules(LIBVA libva) @@ -142,6 +103,83 @@ if (NOT WIN32 AND NOT ANDROID) list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau) message(WARNING "ffmpeg: libvdpau-dev not found, disabling Video Decode and Presentation API for Unix (VDPAU)...") endif() +endif() + +if (YUZU_USE_BUNDLED_FFMPEG) + # MSVC conflicts with ksuser otherwise + # TODO(crueter) fix + set(BUILD_SHARED_LIBS ${MSVC}) + AddJsonPackage(ffmpeg-ci) + + set(FFmpeg_INCLUDE_DIR + "${FFmpeg_SOURCE_DIR}/include;${FFmpeg_HWACCEL_INCLUDE_DIRS}" + PARENT_SCOPE + ) + + set(FFmpeg_PATH + "${FFmpeg_SOURCE_DIR}" + PARENT_SCOPE + ) + + set(FFmpeg_LIBRARY_DIR + "${FFmpeg_SOURCE_DIR}/bin" + PARENT_SCOPE + ) + + set(FFmpeg_LIBRARIES + cubeb::cubeb + ksuser + FFmpeg::swscale + FFmpeg::avutil + FFmpeg::avcodec + FFmpeg::avfilter + ${FFMPEG_HWACCEL_LIBRARIES} + PARENT_SCOPE + ) +else() + # Build FFmpeg from externals + message(STATUS "Using FFmpeg from externals") + + if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64|amd64)") + # FFmpeg has source that requires one of nasm or yasm to assemble it. + # REQUIRED throws an error if not found here during configuration rather than during compilation. + find_program(ASSEMBLER NAMES nasm yasm) + if ("${ASSEMBLER}" STREQUAL "ASSEMBLER-NOTFOUND") + message(FATAL_ERROR "One of either `nasm` or `yasm` not found but is required.") + endif() + endif() + + find_program(AUTOCONF autoconf) + if ("${AUTOCONF}" STREQUAL "AUTOCONF-NOTFOUND") + message(FATAL_ERROR "Required program `autoconf` not found.") + endif() + + AddJsonPackage(ffmpeg) + + set(FFmpeg_PREFIX ${ffmpeg_SOURCE_DIR}) + set(FFmpeg_BUILD_DIR ${ffmpeg_BINARY_DIR}) + set(FFmpeg_MAKEFILE ${FFmpeg_BUILD_DIR}/Makefile) + make_directory(${FFmpeg_BUILD_DIR}) + + # Read version string from external + file(READ ${FFmpeg_PREFIX}/RELEASE FFmpeg_VERSION) + set(FFmpeg_FOUND NO) + if (NOT FFmpeg_VERSION STREQUAL "") + set(FFmpeg_FOUND YES) + endif() + + unset(FFmpeg_LIBRARIES CACHE) + + foreach(COMPONENT ${FFmpeg_COMPONENTS}) + set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}") + set(FFmpeg_${COMPONENT}_LIB_NAME "lib${COMPONENT}.a") + set(FFmpeg_${COMPONENT}_LIBRARY "${FFmpeg_${COMPONENT}_PREFIX}/${FFmpeg_${COMPONENT}_LIB_NAME}") + + set(FFmpeg_LIBRARIES + ${FFmpeg_LIBRARIES} + ${FFmpeg_${COMPONENT}_LIBRARY} + CACHE PATH "Paths to FFmpeg libraries" FORCE) + endforeach() find_program(BASH_PROGRAM bash REQUIRED) @@ -242,57 +280,6 @@ if (NOT WIN32 AND NOT ANDROID) else() message(FATAL_ERROR "FFmpeg not found") endif() -elseif(ANDROID) - # Use yuzu FFmpeg binaries - if (ARCHITECTURE_arm64) - set(FFmpeg_EXT_NAME "ffmpeg-android-7.1.1-aarch64") - elseif (ARCHITECTURE_x86_64) - set(FFmpeg_EXT_NAME "ffmpeg-android-v5.1.LTS-x86_64") - else() - message(FATAL_ERROR "Unsupported architecture for Android FFmpeg") - endif() - - download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "ffmpeg-bundled" FFmpeg_PATH 7.1.1) - set(FFmpeg_FOUND YES) - set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE) - set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/lib" CACHE PATH "Path to FFmpeg library directory" FORCE) - set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE) - set(FFmpeg_LIBRARIES - ${FFmpeg_LIBRARY_DIR}/libavcodec.so - ${FFmpeg_LIBRARY_DIR}/libavdevice.so - ${FFmpeg_LIBRARY_DIR}/libavfilter.so - ${FFmpeg_LIBRARY_DIR}/libavformat.so - ${FFmpeg_LIBRARY_DIR}/libavutil.so - ${FFmpeg_LIBRARY_DIR}/libswresample.so - ${FFmpeg_LIBRARY_DIR}/libswscale.so - ${FFmpeg_LIBRARY_DIR}/libvpx.a - ${FFmpeg_LIBRARY_DIR}/libx264.a - CACHE PATH "Paths to FFmpeg libraries" FORCE) - # exported variables - set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE) - set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE) - set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE) - set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE) -elseif(WIN32) - # Use yuzu FFmpeg binaries - set(FFmpeg_EXT_NAME "ffmpeg-7.1.1") - - download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "ffmpeg-bundled" FFmpeg_PATH 7.1.1) - set(FFmpeg_FOUND YES) - set(FFmpeg_INCLUDE_DIR "${FFmpeg_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE) - set(FFmpeg_LIBRARY_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg library directory" FORCE) - set(FFmpeg_LDFLAGS "" CACHE STRING "FFmpeg linker flags" FORCE) - set(FFmpeg_LIBRARIES - ${FFmpeg_LIBRARY_DIR}/swscale.lib - ${FFmpeg_LIBRARY_DIR}/avcodec.lib - ${FFmpeg_LIBRARY_DIR}/avfilter.lib - ${FFmpeg_LIBRARY_DIR}/avutil.lib - CACHE PATH "Paths to FFmpeg libraries" FORCE) - # exported variables - set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE) - set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE) - set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" PARENT_SCOPE) - set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE) endif() unset(FFmpeg_COMPONENTS) diff --git a/externals/ffmpeg/cpmfile.json b/externals/ffmpeg/cpmfile.json index dd9179703e..9b9efaadde 100644 --- a/externals/ffmpeg/cpmfile.json +++ b/externals/ffmpeg/cpmfile.json @@ -4,5 +4,17 @@ "sha": "c2184b65d2", "hash": "2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97", "bundled": true + }, + "ffmpeg-ci": { + "ci": true, + "package": "FFmpeg", + "name": "ffmpeg", + "repo": "crueter-ci/FFmpeg", + "version": "8.0", + "min_version": "4.1", + "disabled_platforms": [ + "freebsd", + "solaris" + ] } } diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index 389b1044e9..9e7ba05b39 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -243,7 +243,7 @@ if (ENABLE_CUBEB) sink/cubeb_sink.h ) - target_link_libraries(audio_core PRIVATE cubeb) + target_link_libraries(audio_core PRIVATE cubeb::cubeb) target_compile_definitions(audio_core PRIVATE HAVE_CUBEB=1) endif() diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 3c2473266a..642494016e 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -321,11 +321,12 @@ add_library(video_core STATIC target_link_libraries(video_core PUBLIC common core) target_link_libraries(video_core PUBLIC glad shader_recompiler stb bc_decoder) -if (YUZU_USE_BUNDLED_FFMPEG AND NOT (WIN32 OR ANDROID)) +if (YUZU_USE_EXTERNAL_FFMPEG) add_dependencies(video_core ffmpeg-build) endif() target_include_directories(video_core PRIVATE ${FFmpeg_INCLUDE_DIR}) + target_link_libraries(video_core PRIVATE ${FFmpeg_LIBRARIES}) target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS}) diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp index 6609752bdb..536a01fcc8 100644 --- a/src/video_core/host1x/ffmpeg/ffmpeg.cpp +++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp @@ -28,7 +28,7 @@ constexpr AVPixelFormat PreferredCpuFormat = AV_PIX_FMT_YUV420P; constexpr std::array PreferredGpuDecoders = { #if defined (_WIN32) AV_HWDEVICE_TYPE_CUDA, - AV_HWDEVICE_TYPE_D3D11VA, + AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_DXVA2, #elif defined(__FreeBSD__) AV_HWDEVICE_TYPE_VDPAU, @@ -37,7 +37,7 @@ constexpr std::array PreferredGpuDecoders = { AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_VDPAU, #endif - AV_HWDEVICE_TYPE_VULKAN, + AV_HWDEVICE_TYPE_VULKAN, }; AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* pix_fmts) {