From 47401016bfbcd904edd22a4a1bf772e893ad36f6 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Fri, 5 Feb 2021 13:45:10 -0500 Subject: [PATCH] CMake: Implement YUZU_USE_BUNDLED_FFMPEG For Linux, instructs CMake to use the FFmpeg submodule in externals. This is HEAVILY based on our usage of the late Unicorn. Minimal change to MSVC as it uses the yuzu-emu/ext-windows-bin. MinGW now targets the same ext-windows-bin libraries as MSVC for FFmpeg. Adds FFMPEG_LIBRARIES to WIN32 and simplifies video_core/CMakeLists.txt a bit. --- CMakeLists.txt | 112 ++++++++++++++++-- src/video_core/CMakeLists.txt | 11 +- .../command_classes/codecs/codec.cpp | 2 +- 3 files changed, 108 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27aa56780..aafe73c44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,8 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "EN option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) +option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled yuzu" ON) + option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) option(YUZU_ENABLE_BOXCAT "Enable the Boxcat service, a yuzu high-level implementation of BCAT" ON) @@ -384,17 +386,107 @@ if (NOT LIBUSB_FOUND) set(LIBUSB_LIBRARIES usb) endif() -# Use system installed ffmpeg. -if (NOT MSVC) - find_package(FFmpeg REQUIRED) +if (YUZU_USE_BUNDLED_FFMPEG) + if (NOT WIN32) + # Build FFmpeg from externals + message(STATUS "Using FFmpeg from externals") + + 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() + + set(FFMPEG_COMPONENTS + avcodec + avutil + swscale) + + 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() + + set(FFMPEG_INCLUDE_DIR + ${FFMPEG_PREFIX} + CACHE PATH "Path to FFmpeg headers" FORCE) + + # `configure` parameters builds only exactly what yuzu needs from FFmpeg + # `--disable-{vaapi,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 + --disable-vaapi + --disable-vdpau + --enable-decoder=h264 + --enable-decoder=vp9 + WORKING_DIRECTORY + ${FFMPEG_BUILD_DIR} + ) + + add_custom_command( + OUTPUT + ${FFMPEG_LIBRARIES} + COMMAND + make + WORKING_DIRECTORY + ${FFMPEG_BUILD_DIR} + ) + + # 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-build ALL DEPENDS ${FFMPEG_LIBRARIES}) + add_custom_target(ffmpeg-configure ALL DEPENDS ${FFMPEG_MAKEFILE}) + + if (FFMPEG_FOUND) + message(STATUS "Found FFmpeg version ${FFMPEG_VERSION}") + + add_dependencies(ffmpeg-build ffmpeg-configure) + else() + message(FATAL_ERROR "FFmpeg not found") + endif() + else() # WIN32 + # Use yuzu FFmpeg binaries + set(FFMPEG_EXT_NAME "ffmpeg-4.2.1") + 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_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() else() - set(FFMPEG_EXT_NAME "ffmpeg-4.2.1") - 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" FORCE) - set(FFMPEG_DLL_DIR "${FFMPEG_PATH}/bin" CACHE PATH "Path to FFmpeg dll's" FORCE) + # Use system installed FFmpeg + find_package(FFmpeg REQUIRED VERSION 4.0) endif() # Prefer the -pthread flag on Linux. diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index bb1f8491f..01e284d8c 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -273,14 +273,13 @@ create_target_directory_groups(video_core) target_link_libraries(video_core PUBLIC common core) target_link_libraries(video_core PRIVATE glad xbyak) -if (MSVC) - target_include_directories(video_core PRIVATE ${FFMPEG_INCLUDE_DIR}) - target_link_libraries(video_core PUBLIC ${FFMPEG_LIBRARY_DIR}/swscale.lib ${FFMPEG_LIBRARY_DIR}/avcodec.lib ${FFMPEG_LIBRARY_DIR}/avutil.lib) -else() - target_include_directories(video_core PRIVATE ${FFMPEG_INCLUDE_DIR}) - target_link_libraries(video_core PRIVATE ${FFMPEG_LIBRARIES}) +if (YUZU_USE_BUNDLED_FFMPEG AND NOT WIN32) + add_dependencies(video_core ffmpeg-build) endif() +target_include_directories(video_core PRIVATE ${FFMPEG_INCLUDE_DIR}) +target_link_libraries(video_core PRIVATE ${FFMPEG_LIBRARIES}) + add_dependencies(video_core host_shaders) target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE}) target_include_directories(video_core PRIVATE sirit ../../externals/Vulkan-Headers/include) diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/command_classes/codecs/codec.cpp index 39bc923a5..c25d2ad2c 100644 --- a/src/video_core/command_classes/codecs/codec.cpp +++ b/src/video_core/command_classes/codecs/codec.cpp @@ -13,7 +13,7 @@ #include "video_core/memory_manager.h" extern "C" { -#include +#include "libavutil/opt.h" } namespace Tegra {