ffmpeg ci

Signed-off-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
crueter 2025-09-20 19:09:21 -04:00
parent 49ddf95c70
commit 51a33940a9
Signed by: crueter
GPG key ID: 425ACD2D4830EBC6
9 changed files with 117 additions and 122 deletions

View file

@ -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_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
option(ENABLE_WIFI_SCAN "Enable WiFi scanning" OFF) 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) 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? # TODO(crueter): CI this?
option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" ON) 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 # 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) CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "ENABLE_SDL2" OFF)
@ -579,6 +578,10 @@ if(ENABLE_CUBEB)
) )
endif() endif()
endif() endif()
if (NOT TARGET cubeb::cubeb)
add_library(cubeb::cubeb ALIAS cubeb)
endif()
endif() endif()
# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package # 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) find_package(cpp-jwt)
endif() endif()
if (ENABLE_SDL2)
find_package(SDL2)
endif()
if (ENABLE_QT) if (ENABLE_QT)
if (YUZU_USE_BUNDLED_QT) if (YUZU_USE_BUNDLED_QT)
download_qt(6.8.3) download_qt(6.8.3)
@ -738,9 +737,8 @@ if (UNIX AND NOT APPLE AND NOT ANDROID)
pkg_check_modules(LIBVA libva) pkg_check_modules(LIBVA libva)
endif() endif()
if (NOT YUZU_USE_BUNDLED_FFMPEG) if (NOT (YUZU_USE_BUNDLED_FFMPEG OR YUZU_USE_EXTERNAL_FFMPEG))
# Use system installed FFmpeg # Use system installed FFmpeg
#find_package(FFmpeg 4.3 REQUIRED QUIET COMPONENTS ${FFmpeg_COMPONENTS})
find_package(FFmpeg REQUIRED QUIET COMPONENTS ${FFmpeg_COMPONENTS}) find_package(FFmpeg REQUIRED QUIET COMPONENTS ${FFmpeg_COMPONENTS})
# TODO(crueter): Version # TODO(crueter): Version

View file

@ -126,6 +126,15 @@ function(AddJsonPackage)
DISABLED_PLATFORMS ${disabled_platforms} DISABLED_PLATFORMS ${disabled_platforms}
CMAKE_FILENAME ${cmake_filename} 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() return()
endif() endif()
@ -598,7 +607,9 @@ function(AddCIPackage)
if (DEFINED ARTIFACT_DIR) if (DEFINED ARTIFACT_DIR)
include(${ARTIFACT_DIR}/${ARTIFACT_CMAKE}.cmake) include(${ARTIFACT_DIR}/${ARTIFACT_CMAKE}.cmake)
set(${ARTIFACT_PACKAGE}_ADDED TRUE PARENT_SCOPE) set(${ARTIFACT_PACKAGE}_ADDED TRUE PARENT_SCOPE)
set(${ARTIFACT_PACKAGE}_SOURCE_DIR "${ARTIFACT_DIR}" PARENT_SCOPE)
else() else()
find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED) find_package(${ARTIFACT_PACKAGE} ${ARTIFACT_MIN_VERSION} REQUIRED)
endif() endif()

View file

@ -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}") message(STATUS "Using bundled binaries at ${${cpm_key}_SOURCE_DIR}")
endfunction() 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) function(download_moltenvk_external platform version)
set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK") set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK")
set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar") set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar")

View file

@ -25,10 +25,6 @@ set(BUILD_SHARED_LIBS OFF)
# Skip install rules for all externals # Skip install rules for all externals
set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL ON) 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) # Xbyak (also used by Dynarmic, so needs to be added first)
if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64) if (ARCHITECTURE_x86 OR ARCHITECTURE_x86_64)
if (PLATFORM_SUN OR PLATFORM_OPENBSD) if (PLATFORM_SUN OR PLATFORM_OPENBSD)
@ -97,11 +93,13 @@ endif()
AddJsonPackage(unordered-dense) AddJsonPackage(unordered-dense)
# FFMpeg # FFMpeg
if (YUZU_USE_BUNDLED_FFMPEG) if (YUZU_USE_EXTERNAL_FFMPEG OR YUZU_USE_BUNDLED_FFMPEG)
add_subdirectory(ffmpeg) add_subdirectory(ffmpeg)
set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE) set(FFmpeg_PATH "${FFmpeg_PATH}" PARENT_SCOPE)
set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE) set(FFmpeg_LDFLAGS "${FFmpeg_LDFLAGS}" PARENT_SCOPE)
set(FFmpeg_LIBRARIES "${FFmpeg_LIBRARIES}" 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) set(FFmpeg_INCLUDE_DIR "${FFmpeg_INCLUDE_DIR}" PARENT_SCOPE)
endif() endif()

View file

@ -6,51 +6,9 @@
include(CPMUtil) include(CPMUtil)
if (NOT WIN32 AND NOT ANDROID) # TODO(crueter, MaranBr): Externals FFmpeg 8.0
# 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()
if (UNIX)
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
if (NOT ANDROID) if (NOT ANDROID)
pkg_check_modules(LIBVA libva) pkg_check_modules(LIBVA libva)
@ -145,6 +103,83 @@ if (NOT WIN32 AND NOT ANDROID)
list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau) list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau)
message(WARNING "ffmpeg: libvdpau-dev not found, disabling Video Decode and Presentation API for Unix (VDPAU)...") message(WARNING "ffmpeg: libvdpau-dev not found, disabling Video Decode and Presentation API for Unix (VDPAU)...")
endif() 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) find_program(BASH_PROGRAM bash REQUIRED)
@ -245,57 +280,6 @@ if (NOT WIN32 AND NOT ANDROID)
else() else()
message(FATAL_ERROR "FFmpeg not found") message(FATAL_ERROR "FFmpeg not found")
endif() 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() endif()
unset(FFmpeg_COMPONENTS) unset(FFmpeg_COMPONENTS)

View file

@ -4,5 +4,17 @@
"sha": "c2184b65d2", "sha": "c2184b65d2",
"hash": "2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97", "hash": "2a89d664119debbb3c006ab1c48d5d7f26e889f4a65ad2e25c8b0503308295123d5a9c5c78bf683aef5ff09acef8c3fc2837f22d3e8c611528b933bf03bcdd97",
"bundled": true "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"
]
} }
} }

View file

@ -243,7 +243,7 @@ if (ENABLE_CUBEB)
sink/cubeb_sink.h 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) target_compile_definitions(audio_core PRIVATE HAVE_CUBEB=1)
endif() endif()

View file

@ -321,11 +321,12 @@ add_library(video_core STATIC
target_link_libraries(video_core PUBLIC common core) target_link_libraries(video_core PUBLIC common core)
target_link_libraries(video_core PUBLIC glad shader_recompiler stb bc_decoder) 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) add_dependencies(video_core ffmpeg-build)
endif() endif()
target_include_directories(video_core PRIVATE ${FFmpeg_INCLUDE_DIR}) target_include_directories(video_core PRIVATE ${FFmpeg_INCLUDE_DIR})
target_link_libraries(video_core PRIVATE ${FFmpeg_LIBRARIES}) target_link_libraries(video_core PRIVATE ${FFmpeg_LIBRARIES})
target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS}) target_link_options(video_core PRIVATE ${FFmpeg_LDFLAGS})

View file

@ -28,7 +28,7 @@ constexpr AVPixelFormat PreferredCpuFormat = AV_PIX_FMT_YUV420P;
constexpr std::array PreferredGpuDecoders = { constexpr std::array PreferredGpuDecoders = {
#if defined (_WIN32) #if defined (_WIN32)
AV_HWDEVICE_TYPE_CUDA, AV_HWDEVICE_TYPE_CUDA,
AV_HWDEVICE_TYPE_D3D11VA, AV_HWDEVICE_TYPE_D3D11VA,
AV_HWDEVICE_TYPE_DXVA2, AV_HWDEVICE_TYPE_DXVA2,
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
AV_HWDEVICE_TYPE_VDPAU, AV_HWDEVICE_TYPE_VDPAU,
@ -37,7 +37,7 @@ constexpr std::array PreferredGpuDecoders = {
AV_HWDEVICE_TYPE_VAAPI, AV_HWDEVICE_TYPE_VAAPI,
AV_HWDEVICE_TYPE_VDPAU, AV_HWDEVICE_TYPE_VDPAU,
#endif #endif
AV_HWDEVICE_TYPE_VULKAN, AV_HWDEVICE_TYPE_VULKAN,
}; };
AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* pix_fmts) { AVPixelFormat GetGpuFormat(AVCodecContext* codec_context, const AVPixelFormat* pix_fmts) {