From 851b1008a881010b90002f4af9d0a4ac36710fea Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 30 Dec 2022 00:29:53 -0800 Subject: [PATCH] cmake: Integrate bundled FFmpeg for Android. --- CMakeModules/DownloadExternals.cmake | 7 ++- externals/ffmpeg/CMakeLists.txt | 64 ++++++++++++++++++++++++---- src/video_core/CMakeLists.txt | 2 +- 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/CMakeModules/DownloadExternals.cmake b/CMakeModules/DownloadExternals.cmake index 8fe5ba48df..814069f0b3 100644 --- a/CMakeModules/DownloadExternals.cmake +++ b/CMakeModules/DownloadExternals.cmake @@ -7,6 +7,7 @@ # prefix_var: name of a variable which will be set with the path to the extracted contents function(download_bundled_external remote_path lib_name prefix_var) +set(package_base_url "https://github.com/yuzu-emu/") set(package_repo "no_platform") set(package_extension "no_platform") if (WIN32) @@ -15,10 +16,14 @@ if (WIN32) elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(package_repo "ext-linux-bin/raw/main/") set(package_extension ".tar.xz") +elseif (ANDROID) + set(package_base_url "https://gitlab.com/tertius42/") + set(package_repo "ext-android-bin/-/raw/main/") + set(package_extension ".tar.xz") #ffmpeg/ffmpeg-android-20221229.tar.xz") else() message(FATAL_ERROR "No package available for this platform") endif() -set(package_url "https://github.com/yuzu-emu/${package_repo}") +set(package_url "${package_base_url}${package_repo}") set(prefix "${CMAKE_BINARY_DIR}/externals/${lib_name}") if (NOT EXISTS "${prefix}") diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt index 03fad0778c..0936166291 100644 --- a/externals/ffmpeg/CMakeLists.txt +++ b/externals/ffmpeg/CMakeLists.txt @@ -1,7 +1,7 @@ # SPDX-FileCopyrightText: 2021 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later -if (NOT WIN32) +if (NOT WIN32 AND NOT ANDROID) # Build FFmpeg from externals message(STATUS "Using FFmpeg from externals") @@ -44,10 +44,12 @@ if (NOT WIN32) endforeach() find_package(PkgConfig REQUIRED) - pkg_check_modules(LIBVA libva) - pkg_check_modules(CUDA cuda) - pkg_check_modules(FFNVCODEC ffnvcodec) - pkg_check_modules(VDPAU vdpau) + if (NOT ANDROID) + pkg_check_modules(LIBVA libva) + pkg_check_modules(CUDA cuda) + pkg_check_modules(FFNVCODEC ffnvcodec) + pkg_check_modules(VDPAU vdpau) + endif() set(FFmpeg_HWACCEL_LIBRARIES) set(FFmpeg_HWACCEL_FLAGS) @@ -121,6 +123,26 @@ if (NOT WIN32) list(APPEND FFmpeg_HWACCEL_FLAGS --disable-vdpau) endif() + find_program(BASH_PROGRAM bash REQUIRED) + + set(FFmpeg_CROSS_COMPILE_FLAGS "") + if (ANDROID) + 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 + --arch=arm64 + #--cpu=${FFmpeg_CPU} + --enable-cross-compile + --cross-prefix=${TOOLCHAIN}/bin/aarch64-linux-android- + --sysroot=${SYSROOT} + --target-os=android + --extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld" + --extra-ldflags="-nostdlib" + ) + endif() + # `configure` parameters builds only exactly what yuzu needs from FFmpeg # `--disable-vdpau` is needed to avoid linking issues set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER}) @@ -129,7 +151,7 @@ if (NOT WIN32) OUTPUT ${FFmpeg_MAKEFILE} COMMAND - /bin/bash ${FFmpeg_PREFIX}/configure + ${BASH_PROGRAM} ${FFmpeg_PREFIX}/configure --disable-avdevice --disable-avformat --disable-doc @@ -146,12 +168,14 @@ if (NOT WIN32) --cc="${FFmpeg_CC}" --cxx="${FFmpeg_CXX}" ${FFmpeg_HWACCEL_FLAGS} + ${FFmpeg_CROSS_COMPILE_FLAGS} WORKING_DIRECTORY ${FFmpeg_BUILD_DIR} ) unset(FFmpeg_CC) unset(FFmpeg_CXX) unset(FFmpeg_HWACCEL_FLAGS) + unset(FFmpeg_CROSS_COMPILE_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. @@ -197,7 +221,32 @@ if (NOT WIN32) else() message(FATAL_ERROR "FFmpeg not found") endif() -else(WIN32) +elseif(ANDROID) + # Use yuzu FFmpeg binaries + set(FFmpeg_EXT_NAME "ffmpeg-android-v4.4.LTS") + 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}/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-5.1.3") set(FFmpeg_PATH "${CMAKE_BINARY_DIR}/externals/${FFmpeg_EXT_NAME}") @@ -206,7 +255,6 @@ else(WIN32) 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 diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 308d013d63..027259f572 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -281,7 +281,7 @@ create_target_directory_groups(video_core) target_link_libraries(video_core PUBLIC common core) target_link_libraries(video_core PUBLIC glad shader_recompiler stb) -if (YUZU_USE_BUNDLED_FFMPEG AND NOT WIN32) +if (YUZU_USE_BUNDLED_FFMPEG AND NOT (WIN32 OR ANDROID)) add_dependencies(video_core ffmpeg-build) endif()