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.
This commit is contained in:
lat9nq 2021-02-05 13:45:10 -05:00
parent 82dd376ba2
commit 47401016bf
3 changed files with 108 additions and 17 deletions

View file

@ -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(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_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) 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) set(LIBUSB_LIBRARIES usb)
endif() endif()
# Use system installed ffmpeg. if (YUZU_USE_BUNDLED_FFMPEG)
if (NOT MSVC) if (NOT WIN32)
find_package(FFmpeg REQUIRED) # Build FFmpeg from externals
else() 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_EXT_NAME "ffmpeg-4.2.1")
set(FFMPEG_PATH "${CMAKE_BINARY_DIR}/externals/${FFMPEG_EXT_NAME}") set(FFMPEG_PATH "${CMAKE_BINARY_DIR}/externals/${FFMPEG_EXT_NAME}")
download_bundled_external("ffmpeg/" ${FFMPEG_EXT_NAME} "") download_bundled_external("ffmpeg/" ${FFMPEG_EXT_NAME} "")
set(FFMPEG_FOUND YES) set(FFMPEG_FOUND YES)
set(FFMPEG_INCLUDE_DIR "${FFMPEG_PATH}/include" CACHE PATH "Path to FFmpeg headers" FORCE) 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_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_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()
# Use system installed FFmpeg
find_package(FFmpeg REQUIRED VERSION 4.0)
endif() endif()
# Prefer the -pthread flag on Linux. # Prefer the -pthread flag on Linux.

View file

@ -273,14 +273,13 @@ create_target_directory_groups(video_core)
target_link_libraries(video_core PUBLIC common core) target_link_libraries(video_core PUBLIC common core)
target_link_libraries(video_core PRIVATE glad xbyak) target_link_libraries(video_core PRIVATE glad xbyak)
if (MSVC) if (YUZU_USE_BUNDLED_FFMPEG AND NOT WIN32)
target_include_directories(video_core PRIVATE ${FFMPEG_INCLUDE_DIR}) add_dependencies(video_core ffmpeg-build)
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})
endif() endif()
target_include_directories(video_core PRIVATE ${FFMPEG_INCLUDE_DIR})
target_link_libraries(video_core PRIVATE ${FFMPEG_LIBRARIES})
add_dependencies(video_core host_shaders) add_dependencies(video_core host_shaders)
target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE}) target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE})
target_include_directories(video_core PRIVATE sirit ../../externals/Vulkan-Headers/include) target_include_directories(video_core PRIVATE sirit ../../externals/Vulkan-Headers/include)

View file

@ -13,7 +13,7 @@
#include "video_core/memory_manager.h" #include "video_core/memory_manager.h"
extern "C" { extern "C" {
#include <libavutil/opt.h> #include "libavutil/opt.h"
} }
namespace Tegra { namespace Tegra {