2026-04-25 21:54:27 +02:00
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
2025-09-21 21:58:59 +02:00
# SPDX-License-Identifier: GPL-3.0-or-later
2022-05-15 02:06:02 +02:00
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
2025-09-23 19:38:11 +02:00
# TODO(crueter, MaranBr): Externals FFmpeg 8.0
2021-12-15 01:10:07 -07:00
2025-09-23 19:38:11 +02:00
set ( FFmpeg_HWACCEL_LIBRARIES )
set ( FFmpeg_HWACCEL_FLAGS )
set ( FFmpeg_HWACCEL_INCLUDE_DIRS )
set ( FFmpeg_HWACCEL_LDFLAGS )
2021-12-15 01:10:07 -07:00
2026-05-07 15:58:17 +02:00
if ( NOT YUZU_USE_BUNDLED_FFMPEG )
set ( FFmpeg_CROSS_COMPILE_FLAGS "" )
if ( ANDROID )
# TODO: Maybe use CMAKE_SYSROOT? and probably provide a toolchain file for android
# I mean isn't that the "proper" way anyways?
string ( TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" FFmpeg_HOST_SYSTEM_NAME )
set ( TOOLCHAIN "${ANDROID_NDK}/toolchains/llvm/prebuilt/${FFmpeg_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}" )
set ( SYSROOT "${TOOLCHAIN}/sysroot" )
set ( FFmpeg_CPU "armv8-a" )
list ( APPEND FFmpeg_CROSS_COMPILE_FLAGS
--enable-cross-compile
--arch=arm64
#--cpu=${FFmpeg_CPU}
--cross-prefix= "${TOOLCHAIN}/bin/aarch64-linux-android-"
--sysroot= "${SYSROOT}"
--target-os=android
--extra-ldflags= "--ld-path=${TOOLCHAIN}/bin/ld.lld"
--extra-ldflags= "-nostdlib"
)
set ( FFmpeg_IS_CROSS_COMPILING TRUE )
# User attempts to do a FFmpeg cross compilation because...
# Here we just quickly test against host/system processors not matching
# TODO: Test for versions not matching as well?
elseif ( NOT ( CMAKE_HOST_SYSTEM_PROCESSOR MATCHES CMAKE_SYSTEM_PROCESSOR
AND CMAKE_HOST_SYSTEM_NAME MATCHES CMAKE_SYSTEM_NAME ) )
string ( TOLOWER "${CMAKE_SYSTEM_NAME}" FFmpeg_SYSTEM_NAME )
if ( FFmpeg_SYSTEM_NAME STREQUAL "openorbis" OR FFmpeg_SYSTEM_NAME STREQUAL "managarm" )
set ( FFmpeg_SYSTEM_NAME "none" )
endif ( )
# TODO: Can we really do better? Auto-detection? Something clever?
list ( APPEND FFmpeg_CROSS_COMPILE_FLAGS
--enable-cross-compile
--arch= "${CMAKE_SYSTEM_PROCESSOR}"
--target-os= "${FFmpeg_SYSTEM_NAME}"
--sysroot= "${CMAKE_SYSROOT}"
)
if ( DEFINED FFmpeg_CROSS_PREFIX )
list ( APPEND FFmpeg_CROSS_COMPILE_FLAGS --cross-prefix= "${FFmpeg_CROSS_PREFIX}" )
else ( )
message ( WARNING "Please set FFmpeg_CROSS_PREFIX to your cross toolchain prefix, for example: \${CMAKE_STAGING_PREFIX}/bin/${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_SYSTEM_NAME}-" )
endif ( )
set ( FFmpeg_IS_CROSS_COMPILING TRUE )
2022-12-30 00:29:53 -08:00
endif ( )
2026-05-07 15:58:17 +02:00
endif ( )
2021-12-15 01:10:07 -07:00
2026-08-10 04:57:38 +02:00
if ( OPENORBIS OR MANAGARM )
2026-05-07 15:58:17 +02:00
# Doesn't support VA-API, don't go thru the embarrassment of trying to enable it
list ( APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi )
2026-07-09 06:55:54 +02:00
elseif ( ANDROID )
list ( APPEND FFmpeg_HWACCEL_FLAGS
--enable-mediacodec
--enable-jni
)
2026-06-09 21:41:50 +02:00
elseif ( UNIX AND NOT DEFINED FFmpeg_IS_CROSS_COMPILING AND NOT ANDROID )
2026-05-07 15:58:17 +02:00
find_package ( PkgConfig REQUIRED )
pkg_check_modules ( LIBVA libva )
pkg_check_modules ( CUDA cuda )
pkg_check_modules ( FFNVCODEC ffnvcodec )
pkg_check_modules ( VDPAU vdpau )
find_package ( X11 )
if ( X11_FOUND )
if ( NOT APPLE )
# In Solaris needs explicit linking for ffmpeg which links to /lib/amd64/libX11.so
2026-08-10 04:57:38 +02:00
if ( SOLARIS )
2025-11-13 13:26:40 +01:00
list ( APPEND FFmpeg_HWACCEL_LIBRARIES
X11
2026-05-07 15:58:17 +02:00
"${CMAKE_SYSROOT}/usr/lib/xorg/amd64/libdrm.so" )
2025-11-13 13:26:40 +01:00
else ( )
2026-05-07 15:58:17 +02:00
pkg_check_modules ( LIBDRM libdrm REQUIRED )
list ( APPEND FFmpeg_HWACCEL_LIBRARIES
${ LIBDRM_LIBRARIES } )
list ( APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${ LIBDRM_INCLUDE_DIRS } )
2025-11-13 13:26:40 +01:00
endif ( )
list ( APPEND FFmpeg_HWACCEL_FLAGS
--enable-libdrm )
2025-08-31 03:10:34 +02:00
endif ( )
2026-05-07 15:58:17 +02:00
if ( LIBVA_FOUND )
pkg_check_modules ( LIBVA-DRM libva-drm REQUIRED )
pkg_check_modules ( LIBVA-X11 libva-x11 REQUIRED )
list ( APPEND FFmpeg_HWACCEL_LIBRARIES
${ X11_LIBRARIES }
${ LIBVA-DRM_LIBRARIES }
${ LIBVA-X11_LIBRARIES }
${ LIBVA_LIBRARIES } )
list ( APPEND FFmpeg_HWACCEL_FLAGS
--enable-hwaccel=h264_vaapi
--enable-hwaccel=vp8_vaapi
--enable-hwaccel=vp9_vaapi )
list ( APPEND FFmpeg_HWACCEL_INCLUDE_DIRS
${ X11_INCLUDE_DIRS }
${ LIBVA-DRM_INCLUDE_DIRS }
${ LIBVA-X11_INCLUDE_DIRS }
${ LIBVA_INCLUDE_DIRS }
)
message ( STATUS "ffmpeg: va-api libraries version ${LIBVA_VERSION} found" )
else ( )
list ( APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi )
message ( WARNING "ffmpeg: libva-dev not found, disabling Video Acceleration API (VA-API)..." )
endif ( )
2021-12-15 01:10:07 -07:00
else ( )
2025-08-29 01:49:20 +02:00
list ( APPEND FFmpeg_HWACCEL_FLAGS --disable-vaapi )
2026-05-07 15:58:17 +02:00
message ( WARNING "ffmpeg: X11 libraries not found, disabling VA-API..." )
2021-12-15 01:10:07 -07:00
endif ( )
if ( FFNVCODEC_FOUND )
list ( APPEND FFmpeg_HWACCEL_FLAGS
--enable-cuvid
--enable-ffnvcodec
--enable-nvdec
--enable-hwaccel=h264_nvdec
--enable-hwaccel=vp8_nvdec
--enable-hwaccel=vp9_nvdec
)
list ( APPEND FFmpeg_HWACCEL_LIBRARIES ${ FFNVCODEC_LIBRARIES } )
list ( APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${ FFNVCODEC_INCLUDE_DIRS } )
list ( APPEND FFmpeg_HWACCEL_LDFLAGS ${ FFNVCODEC_LDFLAGS } )
2025-08-29 01:49:20 +02:00
message ( STATUS "ffmpeg: ffnvcodec libraries version ${FFNVCODEC_VERSION} found" )
2021-12-15 01:10:07 -07:00
# ffnvenc could load CUDA libraries at the runtime using dlopen/dlsym or LoadLibrary/GetProcAddress
2025-09-23 19:38:11 +02:00
# here we handle the hard-linking scenario where CUDA is linked during compilation
2021-12-15 01:10:07 -07:00
if ( CUDA_FOUND )
2022-01-22 12:56:25 +03:00
# This line causes build error if CUDA_INCLUDE_DIRS is anything but a single non-empty value
#list(APPEND FFmpeg_HWACCEL_FLAGS --extra-cflags=-I${CUDA_INCLUDE_DIRS})
2021-12-15 01:10:07 -07:00
list ( APPEND FFmpeg_HWACCEL_LIBRARIES ${ CUDA_LIBRARIES } )
list ( APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${ CUDA_INCLUDE_DIRS } )
list ( APPEND FFmpeg_HWACCEL_LDFLAGS ${ CUDA_LDFLAGS } )
2025-09-23 19:38:11 +02:00
message ( STATUS "ffmpeg: CUDA libraries version ${CUDA_VERSION} found, hard-linking will be performed" )
2021-12-15 01:10:07 -07:00
endif ( CUDA_FOUND )
endif ( )
2025-11-11 06:22:33 +01:00
if ( VDPAU_FOUND AND NOT APPLE )
2021-12-15 01:10:07 -07:00
list ( APPEND FFmpeg_HWACCEL_FLAGS
--enable-vdpau
--enable-hwaccel=h264_vdpau
--enable-hwaccel=vp9_vdpau
)
list ( APPEND FFmpeg_HWACCEL_LIBRARIES ${ VDPAU_LIBRARIES } )
list ( APPEND FFmpeg_HWACCEL_INCLUDE_DIRS ${ VDPAU_INCLUDE_DIRS } )
list ( APPEND FFmpeg_HWACCEL_LDFLAGS ${ VDPAU_LDFLAGS } )
2025-08-29 01:49:20 +02:00
message ( STATUS "ffmpeg: vdpau libraries version ${VDPAU_VERSION} found" )
2021-12-15 01:10:07 -07:00
else ( )
list ( APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau )
2025-08-29 01:49:20 +02:00
message ( WARNING "ffmpeg: libvdpau-dev not found, disabling Video Decode and Presentation API for Unix (VDPAU)..." )
2021-12-15 01:10:07 -07:00
endif ( )
2025-09-23 19:38:11 +02:00
endif ( )
2026-08-10 04:57:38 +02:00
if ( OPENORBIS )
2026-05-07 15:58:17 +02:00
list ( APPEND FFmpeg_CROSS_COMPILE_LIBS
-lkernel
-lSceUserService
-lSceSysmodule
-lSceNet
-lSceLibcInternal
)
list ( APPEND FFmpeg_CROSS_COMPILE_FLAGS
--disable-pthreads
--extra-cflags= ${ CMAKE_SYSROOT } /usr/include
--extra-cxxflags= ${ CMAKE_SYSROOT } /usr/include
--extra-libs= "${FFmpeg_CROSS_COMPILE_LIBS}"
)
2026-08-10 04:57:38 +02:00
elseif ( MANAGARM )
2026-05-07 15:58:17 +02:00
# Required for proper stuff
2026-06-09 21:41:50 +02:00
list ( APPEND FFmpeg_CROSS_COMPILE_FLAGS
2026-05-07 15:58:17 +02:00
--disable-pthreads
--extra-libs= "${FFmpeg_CROSS_COMPILE_LIBS}"
)
endif ( )
2025-09-23 19:38:11 +02:00
if ( YUZU_USE_BUNDLED_FFMPEG )
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
FFmpeg::FFmpeg
${ 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 ( )
2021-12-15 01:10:07 -07:00
2022-12-30 00:29:53 -08:00
find_program ( BASH_PROGRAM bash REQUIRED )
2021-12-15 01:10:07 -07:00
# `configure` parameters builds only exactly what yuzu needs from FFmpeg
# `--disable-vdpau` is needed to avoid linking issues
2022-01-22 12:56:25 +03:00
set ( FFmpeg_CC ${ CMAKE_C_COMPILER_LAUNCHER } ${ CMAKE_C_COMPILER } )
set ( FFmpeg_CXX ${ CMAKE_CXX_COMPILER_LAUNCHER } ${ CMAKE_CXX_COMPILER } )
2021-12-15 01:10:07 -07:00
add_custom_command (
OUTPUT
${ FFmpeg_MAKEFILE }
COMMAND
2022-12-30 00:29:53 -08:00
${ BASH_PROGRAM } ${ FFmpeg_PREFIX } /configure
2021-12-15 01:10:07 -07:00
--disable-avdevice
--disable-avformat
--disable-doc
--disable-everything
--disable-ffmpeg
--disable-ffprobe
--disable-network
--disable-swresample
--enable-decoder=h264
--enable-decoder=vp8
--enable-decoder=vp9
2023-07-18 03:01:49 +04:00
--enable-filter=yadif,scale
2025-08-07 22:05:51 +02:00
--enable-pic
2026-05-07 15:58:17 +02:00
--cc= ${ FFmpeg_CC }
--cxx= ${ FFmpeg_CXX }
--ld= ${ CMAKE_LINKER }
--extra-cflags= ${ CMAKE_C_FLAGS }
--extra-cxxflags= ${ CMAKE_CXX_FLAGS }
--extra-ldflags= ${ CMAKE_C_LINK_FLAGS }
2021-12-15 01:10:07 -07:00
${ FFmpeg_HWACCEL_FLAGS }
2022-12-30 00:29:53 -08:00
${ FFmpeg_CROSS_COMPILE_FLAGS }
2021-12-15 01:10:07 -07:00
WORKING_DIRECTORY
${ FFmpeg_BUILD_DIR }
)
2022-01-22 12:56:25 +03:00
unset ( FFmpeg_CC )
unset ( FFmpeg_CXX )
2021-12-15 01:10:07 -07:00
unset ( FFmpeg_HWACCEL_FLAGS )
2022-12-30 00:29:53 -08:00
unset ( FFmpeg_CROSS_COMPILE_FLAGS )
2021-12-15 01:10:07 -07:00
# Workaround for Ubuntu 18.04's older version of make not being able to call make as a child
# with context of the jobserver. Also helps ninja users.
execute_process (
COMMAND
nproc
OUTPUT_VARIABLE
SYSTEM_THREADS )
set ( FFmpeg_BUILD_LIBRARIES ${ FFmpeg_LIBRARIES } )
2025-11-13 13:26:40 +01:00
# BSD make or Solaris make don't support ffmpeg make-j8
2026-08-10 04:57:38 +02:00
if ( LINUX OR ANDROID OR APPLE OR WIN32 OR FREEBSD )
2025-11-13 13:26:40 +01:00
set ( FFmpeg_MAKE_ARGS -j ${ SYSTEM_THREADS } )
else ( )
set ( FFmpeg_MAKE_ARGS "" )
endif ( )
2021-12-15 01:10:07 -07:00
add_custom_command (
OUTPUT
${ FFmpeg_BUILD_LIBRARIES }
COMMAND
2026-04-25 21:54:27 +02:00
gmake ${ FFmpeg_MAKE_ARGS }
2021-12-15 01:10:07 -07:00
WORKING_DIRECTORY
${ FFmpeg_BUILD_DIR }
)
set ( FFmpeg_INCLUDE_DIR
"${FFmpeg_PREFIX};${FFmpeg_BUILD_DIR};${FFmpeg_HWACCEL_INCLUDE_DIRS}"
CACHE PATH "Path to FFmpeg headers" FORCE )
set ( FFmpeg_LDFLAGS
"${FFmpeg_HWACCEL_LDFLAGS}"
CACHE STRING "FFmpeg linker flags" FORCE )
# ALL makes this custom target build every time
# but it won't actually build if the DEPENDS parameter is up to date
add_custom_target ( ffmpeg-configure ALL DEPENDS ${ FFmpeg_MAKEFILE } )
add_custom_target ( ffmpeg-build ALL DEPENDS ${ FFmpeg_BUILD_LIBRARIES } ffmpeg-configure )
link_libraries ( ${ FFmpeg_LIBVA_LIBRARIES } )
set ( FFmpeg_LIBRARIES ${ FFmpeg_BUILD_LIBRARIES } ${ FFmpeg_HWACCEL_LIBRARIES }
CACHE PATH "Paths to FFmpeg libraries" FORCE )
unset ( FFmpeg_BUILD_LIBRARIES )
unset ( FFmpeg_HWACCEL_FLAGS )
unset ( FFmpeg_HWACCEL_INCLUDE_DIRS )
unset ( FFmpeg_HWACCEL_LDFLAGS )
unset ( FFmpeg_HWACCEL_LIBRARIES )
if ( FFmpeg_FOUND )
message ( STATUS "Found FFmpeg version ${FFmpeg_VERSION}" )
else ( )
message ( FATAL_ERROR "FFmpeg not found" )
endif ( )
2022-02-28 21:08:12 +00:00
endif ( )
2021-12-15 01:10:07 -07:00
unset ( FFmpeg_COMPONENTS )