diff options
Diffstat (limited to '')
-rw-r--r-- | CMakeLists.txt | 218 |
1 files changed, 216 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 18d553f4d..a810e11c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -514,7 +514,7 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") endif() if (NOT YUZU_USE_BUNDLED_FFMPEG) # Use system installed FFmpeg - find_package(FFmpeg 4.3 QUIET COMPONENTS ${FFmpeg_COMPONENTS}) + find_package(FFmpeg QUIET COMPONENTS ${FFmpeg_COMPONENTS}) if (FFmpeg_FOUND) # Overwrite aggregate defines from FFmpeg module to avoid over-linking libraries. @@ -527,11 +527,225 @@ if (NOT YUZU_USE_BUNDLED_FFMPEG) set(FFmpeg_INCLUDE_DIR ${FFmpeg_INCLUDE_DIR} ${FFmpeg_INCLUDE_${COMPONENT}} CACHE PATH "Path to FFmpeg headers" FORCE) endforeach() else() - message(WARNING "FFmpeg not found or too old, falling back to externals") + message(WARNING "FFmpeg not found, falling back to externals") set(YUZU_USE_BUNDLED_FFMPEG ON) endif() endif() +if (YUZU_USE_BUNDLED_FFMPEG) + if (NOT WIN32) + # TODO(lat9nq): Move this to externals/ffmpeg/CMakeLists.txt (and move externals/ffmpeg to + # externals/ffmpeg/ffmpeg) + + # Build FFmpeg from externals + message(STATUS "Using FFmpeg from externals") + + # 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() + + find_program(AUTOCONF autoconf) + if ("${AUTOCONF}" STREQUAL "AUTOCONF-NOTFOUND") + message(FATAL_ERROR "Required program `autoconf` not found.") + endif() + + set(FFmpeg_PREFIX ${PROJECT_SOURCE_DIR}/externals/ffmpeg) + set(FFmpeg_BUILD_DIR ${PROJECT_BINARY_DIR}/externals/ffmpeg) + 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() + + Include(FindPkgConfig REQUIRED) + pkg_check_modules(LIBVA libva) + pkg_check_modules(CUDA cuda) + pkg_check_modules(FFNVCODEC ffnvcodec) + pkg_check_modules(VDPAU vdpau) + + set(FFmpeg_HWACCEL_LIBRARIES) + set(FFmpeg_HWACCEL_FLAGS) + set(FFmpeg_HWACCEL_INCLUDE_DIRS) + set(FFmpeg_HWACCEL_LDFLAGS) + + if(LIBVA_FOUND) + pkg_check_modules(LIBDRM libdrm REQUIRED) + find_package(X11 REQUIRED) + pkg_check_modules(LIBVA-DRM libva-drm REQUIRED) + pkg_check_modules(LIBVA-X11 libva-x11 REQUIRED) + list(APPEND FFmpeg_HWACCEL_LIBRARIES + ${LIBDRM_LIBRARIES} + ${X11_LIBRARIES} + ${LIBVA-DRM_LIBRARIES} + ${LIBVA-X11_LIBRARIES} + ${LIBVA_LIBRARIES}) + set(FFmpeg_HWACCEL_FLAGS + --enable-hwaccel=h264_vaapi + --enable-hwaccel=vp8_vaapi + --enable-hwaccel=vp9_vaapi + --enable-libdrm) + list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS + ${LIBDRM_INCLUDE_DIRS} + ${X11_INCLUDE_DIRS} + ${LIBVA-DRM_INCLUDE_DIRS} + ${LIBVA-X11_INCLUDE_DIRS} + ${LIBVA_INCLUDE_DIRS} + ) + message(STATUS "VA-API found") + else() + set(FFmpeg_HWACCEL_FLAGS --disable-vaapi) + endif() + + if (FFNVCODEC_FOUND AND CUDA_FOUND) + list(APPEND FFmpeg_HWACCEL_FLAGS + --enable-cuvid + --enable-ffnvcodec + --enable-nvdec + --enable-hwaccel=h264_nvdec + --enable-hwaccel=vp8_nvdec + --enable-hwaccel=vp9_nvdec + --extra-cflags=-I${CUDA_INCLUDE_DIRS} + ) + list(APPEND FFmpeg_HWACCEL_LIBRARIES + ${FFNVCODEC_LIBRARIES} + ${CUDA_LIBRARIES} + ) + list(APPEND FFmpeg_HWACCEL_INCLUDE_DIRS + ${FFNVCODEC_INCLUDE_DIRS} + ${CUDA_INCLUDE_DIRS} + ) + list(APPEND FFmpeg_HWACCEL_LDFLAGS + ${FFNVCODEC_LDFLAGS} + ${CUDA_LDFLAGS} + ) + message(STATUS "ffnvcodec libraries version ${FFNVCODEC_VERSION} found") + endif() + + if (VDPAU_FOUND) + 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}) + message(STATUS "vdpau libraries version ${VDPAU_VERSION} found") + else() + list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau) + endif() + + # `configure` parameters builds only exactly what yuzu needs from FFmpeg + # `--disable-vdpau` is needed to avoid linking issues + add_custom_command( + OUTPUT + ${FFmpeg_MAKEFILE} + COMMAND + /bin/bash ${FFmpeg_PREFIX}/configure + --disable-avdevice + --disable-avfilter + --disable-avformat + --disable-doc + --disable-everything + --disable-ffmpeg + --disable-ffprobe + --disable-network + --disable-postproc + --disable-swresample + --enable-decoder=h264 + --enable-decoder=vp8 + --enable-decoder=vp9 + --cc="${CMAKE_C_COMPILER}" + --cxx="${CMAKE_CXX_COMPILER}" + ${FFmpeg_HWACCEL_FLAGS} + WORKING_DIRECTORY + ${FFmpeg_BUILD_DIR} + ) + unset(FFmpeg_HWACCEL_FLAGS) + + # 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}) + add_custom_command( + OUTPUT + ${FFmpeg_BUILD_LIBRARIES} + COMMAND + make -j${SYSTEM_THREADS} + 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() + else() # WIN32 + # Use yuzu FFmpeg binaries + set(FFmpeg_EXT_NAME "ffmpeg-4.4") + set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}") + download_bundled_external("ffmpeg/" ${FFmpeg_EXT_NAME} "") + 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_DLL_DIR "${FFmpeg_PATH}/bin" CACHE PATH "Path to FFmpeg dll's" FORCE) + set(FFmpeg_LIBRARIES + ${FFmpeg_LIBRARY_DIR}/swscale.lib + ${FFmpeg_LIBRARY_DIR}/avcodec.lib + ${FFmpeg_LIBRARY_DIR}/avutil.lib + CACHE PATH "Paths to FFmpeg libraries" FORCE) + endif() +endif() + +unset(FFmpeg_COMPONENTS) + # Prefer the -pthread flag on Linux. set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) |