From eeefbdb428a24a7d8cacb8c5812e5e4f11e7677b Mon Sep 17 00:00:00 2001 From: barts Date: Tue, 9 Jan 2024 20:58:48 +0100 Subject: [PATCH] tmp --- .github/workflows/release.yml | 71 ++++++++ .github/workflows/tests.yml | 14 +- .gitignore | 1 + README.md | 75 +++++++- cmake/FindFFmpeg.cmake | 333 ++++++++++++++++++++++++++++++++++ scripts/install-ffmpeg | 151 +++++++++++++++ scripts/install-qt | 33 ++-- src/CMakeLists.txt | 20 +- 8 files changed, 675 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 cmake/FindFFmpeg.cmake create mode 100755 scripts/install-ffmpeg diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..baf8c76 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,71 @@ +name: Release + +on: + push: + tags: + - 'v[0-9]+\.[0-9]+\.[0-9]+' + +jobs: + build-release: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Update apt-get database + run: | + sudo apt-get update -y + sudo apt-get upgrade -y + + - name: Install build dependencies + run: sudo apt-get install -y clang ninja-build git cmake llvm pkg-config + + - name: Install vulkan + run: | + wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo tee /etc/apt/trusted.gpg.d/lunarg.asc + sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-jammy.list http://packages.lunarg.com/vulkan/lunarg-vulkan-jammy.list + sudo apt update + sudo apt -y install vulkan-sdk + + - name: Install project dependencies + run: | + sudo apt-get install -y libboost-all-dev libspdlog-dev + sudo apt-get install -y '^libxcb.*-dev' build-essential libgl1-mesa-dev libgles2-mesa-dev libglu1-mesa-dev libpulse-dev libqt5x11extras5 libssl-dev libssl1.0 libwayland-dev libwayland-egl1-mesa libwayland-server0 libx11-xcb-dev libxi-dev libxkbcommon-dev libxkbcommon-dev libxkbcommon-x11-dev libxrender-dev openssl ffmpeg + + - name: Install ffmpeg + run: | + ./scripts/install-ffmpeg + + - name: Download Qt source + env: + QT_INSTALLER_JWT_TOKEN: ${{ secrets.QT_INSTALLER_JWT_TOKEN }} + run: | + mkdir /tmp/Qt + ./scripts/install-qt --root /tmp/Qt qt.qt6.661.src + + - name: Build Qt from source with static linking + env: + CC: gcc + CXX: g++ + CXXFLAGS: -Wall + run: | + src=/tmp/Qt/6.6.1/Src + $src/configure -release -static -prefix $PWD/3rdparty/Qt/ -submodules qtbase,qtmultimedia,qtwayland -no-pch -no-gstreamer -- -S $src -B $src/build -Wdev -DFFMPEG_DIR=$PWD/3rdparty/ffmpeg + cmake --build $src/build + cmake --install $src/build + echo "Apply patch to fix FindFFmpeg.cmake" + rm ./3rdparty/Qt/lib/cmake/Qt6/FindFFmpeg.cmake + cp ./scripts/FindFFmpeg.cmake ./3rdparty/Qt/lib/cmake/Qt6/ + + - name: Build project + run: | + cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DFFMPEG_DIR=$PWD/3rdparty/ffmpeg + cmake --build ./build --target package + + - name: Publish + uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + draft: true + files: ./build/*.tar.gz diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7199826..d59c51a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,7 +4,6 @@ on: push: branches: - main - - develop pull_request: branches: - main @@ -26,13 +25,20 @@ jobs: - name: Install build dependencies run: sudo apt-get install -y clang ninja-build git cmake + - name: Install vulkan + run: | + wget -qO- https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo tee /etc/apt/trusted.gpg.d/lunarg.asc + sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-jammy.list http://packages.lunarg.com/vulkan/lunarg-vulkan-jammy.list + sudo apt update + sudo apt install vulkan-sdk + - name: Install project dependencies env: QT_INSTALLER_JWT_TOKEN: ${{ secrets.QT_INSTALLER_JWT_TOKEN }} run: | - sudo apt-get install -y libboost-all-dev libspdlog-dev - sudo apt-get install -y build-essential openssl libssl-dev libssl1.0 libgl1-mesa-dev libqt5x11extras5 '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev libpulse-dev - ./scripts/install-qt + sudo apt-get install -y libboost-all-dev libspdlog-dev + sudo apt-get install -y build-essential openssl libssl-dev libssl1.0 libgl1-mesa-dev libqt5x11extras5 '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev libpulse-dev libwayland-dev libwayland-egl1-mesa libwayland-server0 + ./scripts/install-qt --root $PWD/3rdparty/Qt qt.qt6.661.gcc_64 qt.qt6.661.addons.qtmultimedia - name: Build project run: | diff --git a/.gitignore b/.gitignore index 5199ba6..3e19acd 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ Session.vim nvim.shada include/version.h 3rdparty/Qt +3rdparty/ffmpeg # This file is used to ignore files which are generated # ---------------------------------------------------------------------------- diff --git a/README.md b/README.md index cb88264..0eb4ffb 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # README +[![Tests](https://github.com/BartSte/snapshot/actions/workflows/tests.yml/badge.svg)](https://github.com/BartSte/snapshot/actions/workflows/tests.yml) +[![Release](https://github.com/BartSte/snapshot/actions/workflows/release.yml/badge.svg)](https://github.com/BartSte/snapshot/actions/workflows/release.yml) + > WORK IN PROGRESS! > This project is still under development. The code is still experimental and > is subject to change. @@ -414,7 +417,44 @@ more information. to run the app. - [ ] Publish the directory tree as an archive as a release. Other more sophisticated release methods can be used later. - - Issues: + - Issue FFmpeg: + + - On ubuntu, the includes (headers I guess) are not included in the apt + package, in contrast to the arch package. As a solution, I build ffmpeg + from source. I build them with static linking which gives some new + issues when building the project. Now I am thinking.. I guess I have 3 + options: + + 1. statical link ffmpeg to the project. + 2. dynamically link ffmpeg to the project and include the ffmpeg libs in + the release. + 3. dynamically link ffmpeg to the project and let the user install ffmpeg + themselves. This could be useful when the user needs different + versions of ffmpeg to make it work with their hardware. + + On arch, I can just install static ffmpeg using AUR (its located at + /opt/ffmpeg063). + + Update: I think I fixed it: + + - I created the install-ffmpeg script to build ffmpeg from source. It is + installed in ./3rdparty/ffmpeg. + - After that, the -DFFMPEG_DIR=$PWD/3rdparty/ffmpeg flag is added to the + cmake command. This makes sure that the ffmpeg libs are found. This + results in: + + ``` + cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DFFMPEG_DIR=$PWD/3rdparty/ffmpeg + ``` + + Now I hit a known bug: https://bugreports.qt.io/browse/QTBUG-115052 when + building ffmpeg statically. So, I can apply the patch that is provided + and try again. + + I applied the patch + build project with static ffmpeg. I got some errors + about va-api. Lets try what happens when I build ffmpeg shared. + + - Issues graphics: - On WSL I get the following error: @@ -425,11 +465,38 @@ more information. libEGL warning: egl: failed to create dri2 screen ``` - - On ubuntu, fresh install, I get the following error: + According to bing: ``` - barts@zbook:~$ ./snapshot-0.0.0-Linux/snapshot -h - 1012: __vdso_timeSegmentation fault + It seems that you are encountering an error while running your Qt app on + Arch Linux with WSL. The error message you provided indicates that the + vkCreateInstance function failed with the error code + VK_ERROR_INCOMPATIBLE_DRIVER. This error is usually caused by a mismatch + between the Vulkan driver and the hardware it is running on 1. + + One possible solution is to install the latest graphics drivers for your + system 2. Another possible solution is to try running the app without any + Vulkan layers at all 3. + + It’s also worth noting that there is an ongoing issue with + hardware-accelerated Vulkan in WSL2 4. You may want to check if this issue + is related to your problem. + + I hope this helps! ``` + An idea is to check for differences in the output of `pldd` when comparing + an snapshot app that uses a dynamic Qt6 and one that uses a static Qt6. I + the past, a dynamic Qt6 worked on WSL, so it is likely that something goes + wrong during the static linking. + + I think it has to do with support for the GPU. I think it is not possible + to make a stand-alone structure that support all GPU's. So it is likely to + be better that the user installs the GPU drivers themselves. I am not sure + what the best way is to do this. It does explain why the build on the + ubuntu server fails on my arch machine, but when I build it myself, it + works. This may also be the case on my WSL+arch machine when I install the + GPU drivers as is explained + [here](https://github.com/lutris/docs/blob/master/InstallingDrivers.md#amd--intel). + - [ ] Cross compile for raspberry pi diff --git a/cmake/FindFFmpeg.cmake b/cmake/FindFFmpeg.cmake new file mode 100644 index 0000000..83702e1 --- /dev/null +++ b/cmake/FindFFmpeg.cmake @@ -0,0 +1,333 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause +#.rst: +# FindFFmpeg +# ---------- +# +# Try to find the required ffmpeg components (default: AVFORMAT, AVUTIL, AVCODEC) +# +# Next variables can be used to hint FFmpeg libs search: +# +# :: +# +# PC__LIBRARY_DIRS +# PC_FFMPEG_LIBRARY_DIRS +# PC__INCLUDE_DIRS +# PC_FFMPEG_INCLUDE_DIRS +# +# Once done this will define +# +# :: +# +# FFMPEG_FOUND - System has the all required components. +# FFMPEG_INCLUDE_DIRS - Include directory necessary for using the required components headers. +# FFMPEG_LIBRARIES - Link these to use the required ffmpeg components. +# FFMPEG_LIBRARY_DIRS - Link directories +# FFMPEG_DEFINITIONS - Compiler switches required for using the required ffmpeg components. +# +# For each of the components it will additionally set. +# +# :: +# +# AVCODEC +# AVDEVICE +# AVFORMAT +# AVFILTER +# AVUTIL +# POSTPROC +# SWSCALE +# +# the following variables will be defined +# +# :: +# +# _FOUND - System has +# FFMPEG__FOUND - System has (as checked by FHSPA) +# _INCLUDE_DIRS - Include directory necessary for using the headers +# _LIBRARIES - Link these to use +# _LIBRARY_DIRS - Link directories +# _DEFINITIONS - Compiler switches required for using +# _VERSION - The components version +# +# the following import targets is created +# +# :: +# +# FFmpeg::FFmpeg - for all components +# FFmpeg:: - where in lower case (FFmpeg::avcodec) for each components +# +# Copyright (c) 2006, Matthias Kretz, +# Copyright (c) 2008, Alexander Neundorf, +# Copyright (c) 2011, Michael Jansen, +# Copyright (c) 2017, Alexander Drozdov, +# + +include(FindPackageHandleStandardArgs) + +# The default components were taken from a survey over other FindFFMPEG.cmake files +if (NOT FFmpeg_FIND_COMPONENTS) + set(FFmpeg_FIND_COMPONENTS AVCODEC AVFORMAT AVUTIL) +endif () + +# +### Macro: set_component_found +# +# Marks the given component as found if both *_LIBRARIES AND *_INCLUDE_DIRS is present. +# +macro(set_component_found _component ) + if (${_component}_LIBRARIES AND ${_component}_INCLUDE_DIRS) + # message(STATUS " - ${_component} found.") + set(${_component}_FOUND TRUE) + set(${CMAKE_FIND_PACKAGE_NAME}_${_component}_FOUND TRUE) + else () + # message(STATUS " - ${_component} not found.") + endif () +endmacro() + +find_package(PkgConfig QUIET) +if (NOT PKG_CONFIG_FOUND AND NOT FFMPEG_DIR) + set(FFMPEG_DIR "/usr/local") +endif() +# +### Macro: find_component +# +# Checks for the given component by invoking pkgconfig and then looking up the libraries and +# include directories. +# +macro(find_component _component _pkgconfig _library _header) + + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + if (PKG_CONFIG_FOUND AND NOT FFMPEG_DIR) + pkg_check_modules(PC_${_component} ${_pkgconfig}) + endif () + + if (FFMPEG_DIR OR FFMPEG_ROOT) + set(__find_ffmpeg_backup_root_dir "${CMAKE_FIND_ROOT_PATH}") + endif() + + if(FFMPEG_DIR) + list(APPEND CMAKE_FIND_ROOT_PATH "${FFMPEG_DIR}") + endif() + + if(FFMPEG_ROOT) + list(APPEND CMAKE_FIND_ROOT_PATH "${FFMPEG_ROOT}") + endif() + + find_path(${_component}_INCLUDE_DIRS ${_header} + HINTS + ${PC_${_component}_INCLUDEDIR} + ${PC_${_component}_INCLUDE_DIRS} + ${PC_FFMPEG_INCLUDE_DIRS} + PATHS + ${FFMPEG_DIR} + PATH_SUFFIXES + ffmpeg include + ) + + find_library(${_component}_LIBRARY NAMES ${PC_${_component}_LIBRARIES} ${_library} + HINTS + ${PC_${_component}_LIBDIR} + ${PC_${_component}_LIBRARY_DIRS} + ${PC_FFMPEG_LIBRARY_DIRS} + PATHS + ${FFMPEG_DIR} + PATH_SUFFIXES + lib + ) + + if(FFMPEG_DIR OR FFMPEG_ROOT) + set(CMAKE_FIND_ROOT_PATH "${__find_ffmpeg_backup_root_dir}") + endif() + + get_filename_component(${_component}_LIBRARY_DIR_FROM_FIND ${${_component}_LIBRARY} DIRECTORY) + get_filename_component(${_component}_LIBRARY_FROM_FIND ${${_component}_LIBRARY} NAME) + + set(${_component}_DEFINITIONS ${PC_${_component}_CFLAGS_OTHER} CACHE STRING "The ${_component} CFLAGS.") + set(${_component}_VERSION ${PC_${_component}_VERSION} CACHE STRING "The ${_component} version number.") + set(${_component}_LIBRARY_DIRS ${${_component}_LIBRARY_DIR_FROM_FIND} CACHE STRING "The ${_component} library dirs.") + set(${_component}_LIBRARIES ${${_component}_LIBRARY_FROM_FIND} CACHE STRING "The ${_component} libraries.") + +# message("Libs" ${FFMPEG_DIR} ${${_component}_LIBRARIES} ${${_component}_LIBRARY_DIRS}) + +# message(STATUS "L0: ${${_component}_LIBRARIES}") +# message(STATUS "L1: ${PC_${_component}_LIBRARIES}") +# message(STATUS "L2: ${_library}") +# message(STATUS "L3: ${${_component}_LIBRARY}") +# message(STATUS "L4: ${${_component}_LIBRARY_DIRS}") + + set_component_found(${_component}) + mark_as_advanced( + ${_component}_LIBRARY + ${_component}_INCLUDE_DIRS + ${_component}_LIBRARY_DIRS + ${_component}_LIBRARIES + ${_component}_DEFINITIONS + ${_component}_VERSION) + +endmacro() + +# Clear the previously cached variables, because they are recomputed every time +# the Find script is included. +set(FFMPEG_INCLUDE_DIRS "") +set(FFMPEG_LIBRARIES "") +set(FFMPEG_DEFINITIONS "") +set(FFMPEG_LIBRARY_DIRS "") + +# Check for all possible component. +find_component(AVCODEC libavcodec avcodec libavcodec/avcodec.h) +find_component(AVFORMAT libavformat avformat libavformat/avformat.h) +find_component(AVDEVICE libavdevice avdevice libavdevice/avdevice.h) +find_component(AVUTIL libavutil avutil libavutil/avutil.h) +find_component(AVFILTER libavfilter avfilter libavfilter/avfilter.h) +find_component(SWSCALE libswscale swscale libswscale/swscale.h) +find_component(POSTPROC libpostproc postproc libpostproc/postprocess.h) +find_component(SWRESAMPLE libswresample swresample libswresample/swresample.h) + +# Linking to private FFmpeg libraries is only needed if it was built statically +# Only one of the components needs to be tested +if(AVCODEC_LIBRARY AND ${AVCODEC_LIBRARY} MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$") + set(FFMPEG_IS_STATIC TRUE CACHE INTERNAL "") +endif() + +if (FFMPEG_IS_STATIC AND (ANDROID OR LINUX)) + set(ENABLE_DYNAMIC_RESOLVE_OPENSSL_SYMBOLS TRUE CACHE INTERNAL "") +endif() + +set(ENABLE_DYNAMIC_RESOLVE_VAAPI_SYMBOLS ${LINUX} CACHE INTERNAL "") + +function(__try_add_dynamic_resolve_dependency dep added) + set(added TRUE PARENT_SCOPE) + + if(ENABLE_DYNAMIC_RESOLVE_OPENSSL_SYMBOLS AND + (${dep} STREQUAL "ssl" OR ${dep} STREQUAL "crypto")) + set(DYNAMIC_RESOLVE_OPENSSL_SYMBOLS TRUE CACHE INTERNAL "") + elseif(ENABLE_DYNAMIC_RESOLVE_VAAPI_SYMBOLS AND ${dep} STREQUAL "va") + set(DYNAMIC_RESOLVE_VAAPI_SYMBOLS TRUE CACHE INTERNAL "") + elseif(ENABLE_DYNAMIC_RESOLVE_VAAPI_SYMBOLS AND ${dep} STREQUAL "va-drm") + set(DYNAMIC_RESOLVE_VA_DRM_SYMBOLS TRUE CACHE INTERNAL "") + elseif(ENABLE_DYNAMIC_RESOLVE_VAAPI_SYMBOLS AND ${dep} STREQUAL "va-x11") + set(DYNAMIC_RESOLVE_VA_X11_SYMBOLS TRUE CACHE INTERNAL "") + else() + set(added FALSE PARENT_SCOPE) + endif() +endfunction() + +# Function parses package config file to find the static library dependencies +# and adds them to the target library. +function(__ffmpeg_internal_set_dependencies lib) + set(PC_FILE ${FFMPEG_DIR}/lib/pkgconfig/lib${lib}.pc) + if(EXISTS ${PC_FILE}) + file(READ ${PC_FILE} pcfile) + + set(prefix_l "(^| )\\-l") + set(suffix_lib "\\.lib($| )") + + string(REGEX REPLACE ".*Libs:([^\n\r]+).*" "\\1" out "${pcfile}") + string(REGEX MATCHALL "${prefix_l}[^ ]+" libs_dependency ${out}) + string(REGEX MATCHALL "[^ ]+${suffix_lib}" libs_dependency_lib ${out}) + + string(REGEX REPLACE ".*Libs.private:([^\n\r]+).*" "\\1" out "${pcfile}") + string(REGEX MATCHALL "${prefix_l}[^ ]+" libs_private_dependency ${out}) + string(REGEX MATCHALL "[^ ]+${suffix_lib}" libs_private_dependency_lib ${out}) + + list(APPEND deps_no_suffix ${libs_dependency} ${libs_private_dependency}) + foreach(dependency ${deps_no_suffix}) + string(REGEX REPLACE ${prefix_l} "" dependency ${dependency}) + if(NOT ${lib} STREQUAL ${dependency}) + __try_add_dynamic_resolve_dependency(${dependency} added) + if(NOT added) + target_link_libraries(FFmpeg::${lib} INTERFACE ${dependency}) + endif() + endif() + endforeach() + + list(APPEND deps_lib_suffix ${libs_dependency_lib} ${libs_private_dependency_lib}) + foreach(dependency ${deps_lib_suffix}) + string(REGEX REPLACE ${suffix_lib} "" dependency ${dependency}) + target_link_libraries(FFmpeg::${lib} INTERFACE ${dependency}) + endforeach() + endif() +endfunction() + +# Check for cached results. If there are skip the costly part. +#if (NOT FFMPEG_LIBRARIES) + + # Check if the required components were found and add their stuff to the FFMPEG_* vars. + foreach (_component ${FFmpeg_FIND_COMPONENTS}) + if (${_component}_FOUND) + # message(STATUS "Libs: ${${_component}_LIBRARIES} | ${PC_${_component}_LIBRARIES}") + + # message(STATUS "Required component ${_component} present.") + set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} ${${_component}_LIBRARY}) + set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} ${${_component}_DEFINITIONS}) + + list(APPEND FFMPEG_INCLUDE_DIRS ${${_component}_INCLUDE_DIRS}) + list(APPEND FFMPEG_LIBRARY_DIRS ${${_component}_LIBRARY_DIRS}) + + string(TOLOWER ${_component} _lowerComponent) + if (NOT TARGET FFmpeg::${_lowerComponent}) + add_library(FFmpeg::${_lowerComponent} INTERFACE IMPORTED) + set_target_properties(FFmpeg::${_lowerComponent} PROPERTIES + INTERFACE_COMPILE_OPTIONS "${${_component}_DEFINITIONS}" + INTERFACE_INCLUDE_DIRECTORIES ${${_component}_INCLUDE_DIRS} + INTERFACE_LINK_LIBRARIES "${${_component}_LIBRARY}" + INTERFACE_LINK_DIRECTORIES "${${_component}_LIBRARY_DIRS}" + ) + target_link_libraries(FFmpeg::${_lowerComponent} INTERFACE "${${_component}_LIBRARY}") + if(FFMPEG_IS_STATIC) + __ffmpeg_internal_set_dependencies(${_lowerComponent}) + endif() + if (UNIX AND NOT APPLE) + target_link_options(FFmpeg::${_lowerComponent} INTERFACE "-Wl,--exclude-libs=lib${_lowerComponent}") + endif () + endif() + else() + # message(STATUS "Required component ${_component} missing.") + endif() + endforeach () + + # Build the include path with duplicates removed. + if (FFMPEG_INCLUDE_DIRS) + list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS) + endif () + + # cache the vars. + set(FFMPEG_INCLUDE_DIRS ${FFMPEG_INCLUDE_DIRS} CACHE STRING "The FFmpeg include directories." FORCE) + set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} CACHE STRING "The FFmpeg libraries." FORCE) + set(FFMPEG_DEFINITIONS ${FFMPEG_DEFINITIONS} CACHE STRING "The FFmpeg cflags." FORCE) + set(FFMPEG_LIBRARY_DIRS ${FFMPEG_LIBRARY_DIRS} CACHE STRING "The FFmpeg library dirs." FORCE) + + mark_as_advanced(FFMPEG_INCLUDE_DIRS + FFMPEG_LIBRARIES + FFMPEG_DEFINITIONS + FFMPEG_LIBRARY_DIRS) + +#endif () + +if (NOT TARGET FFmpeg::FFmpeg) + add_library(FFmpeg INTERFACE) + set_target_properties(FFmpeg PROPERTIES + INTERFACE_COMPILE_OPTIONS "${FFMPEG_DEFINITIONS}" + INTERFACE_INCLUDE_DIRECTORIES "${FFMPEG_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${FFMPEG_LIBRARIES}" + INTERFACE_LINK_DIRECTORIES "${FFMPEG_LIBRARY_DIRS}") + add_library(FFmpeg::FFmpeg ALIAS FFmpeg) +endif() + +# Now set the noncached _FOUND vars for the components. +foreach (_component AVCODEC AVDEVICE AVFORMAT AVUTIL POSTPROCESS SWSCALE) + set_component_found(${_component}) +endforeach () + +# Compile the list of required vars +set(_FFmpeg_REQUIRED_VARS FFMPEG_LIBRARIES FFMPEG_INCLUDE_DIRS) +foreach (_component ${FFmpeg_FIND_COMPONENTS}) + list(APPEND _FFmpeg_REQUIRED_VARS ${_component}_LIBRARIES ${_component}_INCLUDE_DIRS) +endforeach () + +# Give a nice error message if some of the required vars are missing. +find_package_handle_standard_args(FFmpeg + REQUIRED_VARS ${_FFmpeg_REQUIRED_VARS} + HANDLE_COMPONENTS +) diff --git a/scripts/install-ffmpeg b/scripts/install-ffmpeg new file mode 100755 index 0000000..0e5ca62 --- /dev/null +++ b/scripts/install-ffmpeg @@ -0,0 +1,151 @@ +#!/usr/bin/env bash +set -euxo pipefail + +this_dir=$(dirname "$(realpath "${BASH_SOURCE:-$0}")") +usage="$(basename "$0") [-h] [-s, --source-dir] [-b, --build-dir] -- Compiles ffmpeg from source + +The packages managers \`apt\` and \`pacman\` are supported. + +where: + -h, --help show this help text + -s, --source-dir ffmpeg source directory (default: $HOME/ffmpeg_sources) + -b, --build-dir ffmpeg build directory (default: $this_dir/../3rdparty/ffmpeg)" + +source_dir="$HOME/ffmpeg_sources" +build_dir="$this_dir/../3rdparty/ffmpeg" +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -h | --help) + echo "$usage" + exit + ;; + -s | --source-dir) + source_dir="$2" + shift + shift + ;; + -b | --build-dir) + build_dir="$2" + shift + shift + ;; + *) + echo "Unknown option: $key" + echo "$usage" + exit 1 + ;; + esac +done +bin_dir="$build_dir/bin" + +install_dependencies() { + if command -v apt-get &>/dev/null; then + echo "apt-get found" + install_dependencies_apt + elif command -v pacman &>/dev/null; then + echo "pacman found" + install_dependencies_pacman + else + echo "No supported package manager found" + exit 1 + fi +} + +install_dependencies_apt() { + echo "Updating apt-get" + sudo apt-get update -qq + echo "Installing build tools and dependencies" + sudo apt-get -y install autoconf automake build-essential cmake git-core libass-dev libfreetype6-dev libgnutls28-dev libmp3lame-dev libsdl2-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev meson ninja-build pkg-config texinfo wget yasm zlib1g-dev gnutls-bin libunistring-dev libaom-dev libdav1d-dev tar + + echo "Installing ffmpeg dependencies" + sudo apt-get -y install nasm libx264-dev libx265-dev libvpx-dev libfdk-aac-dev libopus-dev libdav1d-dev libnuma-dev +} + +install_dependencies_pacman() { + echo "Installing build tools and dependencies" + sudo pacman -S --noconfirm --needed autoconf automake cmake git libass freetype2 sdl2 libtool libva libvdpau libvorbis libxcb meson ninja pkgconf texinfo wget yasm zlib gnutls libunistring aom dav1d tar + + echo "Installing ffmpeg dependencies" + sudo pacman -S --noconfirm --needed nasm x264 x265 libvpx fdkaac opus numactl +} + +compile_libaom() { + echo "Compiling libaom" + cd ~/ffmpeg_sources && + git -C aom pull 2>/dev/null || git clone --depth 1 https://aomedia.googlesource.com/aom && + mkdir -p aom_build && + cd aom_build && + PATH="$bin_dir:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$build_dir" -DENABLE_TESTS=OFF -DENABLE_NASM=on ../aom && + PATH="$bin_dir:$PATH" make -j"$(nproc)" && + make install +} + +compile_libsvtav1() { + echo "Compiling libsvtav1" + cd ~/ffmpeg_sources && + git -C SVT-AV1 pull 2>/dev/null || git clone https://gitlab.com/AOMediaCodec/SVT-AV1.git && + mkdir -p SVT-AV1/build && + cd SVT-AV1/build && + PATH="$bin_dir:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$build_dir" -DCMAKE_BUILD_TYPE=Release -DBUILD_DEC=OFF -DBUILD_SHARED_LIBS=OFF .. && + PATH="$bin_dir:$PATH" make -j"$(nproc)" && + make install +} + +compile_libvmaf() { + echo "Compiling libvmaf" + cd ~/ffmpeg_sources && + wget https://github.com/Netflix/vmaf/archive/v2.3.1.tar.gz && tar xvf v2.3.1.tar.gz && + mkdir -p vmaf-2.3.1/libvmaf/build && + cd vmaf-2.3.1/libvmaf/build && + meson setup -Denable_tests=false -Denable_docs=false --buildtype=release --default-library=static .. --prefix "$build_dir" --bindir="$bin_dir" --libdir="$build_dir/lib" && + ninja && + ninja install +} + +compile_ffmpeg() { + echo "Compiling ffmpeg" + cd ~/ffmpeg_sources && + wget -O ffmpeg-snapshot.tar.bz2 https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && + tar xjvf ffmpeg-snapshot.tar.bz2 && + cd ffmpeg && + # --pkg-config-flags="--static" \ + PATH="$bin_dir:$PATH" PKG_CONFIG_PATH="$build_dir/lib/pkgconfig" ./configure \ + --prefix="$build_dir" \ + --enable-shared \ + --disable-static \ + --extra-cflags="-I$build_dir/include" \ + --extra-ldflags="-L$build_dir/lib" \ + --extra-libs="-lpthread -lm" \ + --ld="g++" \ + --bindir="$bin_dir" \ + --enable-gpl \ + --enable-gnutls \ + --enable-libaom \ + --enable-libass \ + --enable-libfdk-aac \ + --enable-libfreetype \ + --enable-libmp3lame \ + --enable-libopus \ + --enable-libsvtav1 \ + --enable-libdav1d \ + --enable-libvorbis \ + --enable-libvpx \ + --enable-libx264 \ + --enable-libx265 \ + --enable-nonfree && + PATH="$bin_dir:$PATH" make -j"$(nproc)" && + make install && + hash -r +} + +dir=$(pwd) + +mkdir -p "$source_dir" "$bin_dir" +install_dependencies +compile_libaom +compile_libsvtav1 +compile_libvmaf +compile_ffmpeg + +cd "$dir" diff --git a/scripts/install-qt b/scripts/install-qt index 55bbd48..5caae82 100755 --- a/scripts/install-qt +++ b/scripts/install-qt @@ -1,7 +1,7 @@ #!/usr/bin/env bash -set -euo pipefail +set -euxo pipefail -usage="Usage: $0 +usage="Usage: $0 Installs Qt 6.6.1 to 3rdparty/Qt. For this script to work, you need to set the QT_INSTALLER_JWT_TOKEN environment variable to your jwt token. Check the @@ -11,21 +11,32 @@ Optionally, you can add more Qt packages to install by adding them as arguments. Options: + -r, --root The root directory to install Qt to. -h, --help Show this help message and exit" -if [[ "$*" == *-h* ]] || [[ "$*" == *--help* ]]; then - echo "$usage" - exit 0 -fi +packages="" +while [[ $# -gt 0 ]]; do + case "$1" in + -r | --root) + install_dir="$2" + shift + shift + ;; + -h | --help) + echo "$usage" + exit 0 + ;; + *) + packages="$packages $1" + shift + ;; + esac +done tmp_dir=$(mktemp -d) -this_dir=$(dirname "$(realpath "${BASH_SOURCE:-$0}")") -install_dir="$this_dir/../3rdparty/Qt" -base="qt.qt6.661.gcc_64" -multimedia="qt.qt6.661.addons.qtmultimedia" curl "https://d13lb3tujbc8s0.cloudfront.net/onlineinstallers/qt-unified-linux-x64-4.6.1-online.run" -o "$tmp_dir/qt-installer.run" chmod +x "$tmp_dir/qt-installer.run" -"$tmp_dir/qt-installer.run" --root "$install_dir" --accept-licenses --accept-obligations --default-answer --confirm-command install $base $multimedia $@ +"$tmp_dir/qt-installer.run" --root "$install_dir" --accept-licenses --accept-obligations --default-answer --confirm-command install $packages rm -rf "$tmp_dir" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 04f0445..eb522f3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,7 +5,8 @@ list(APPEND CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/3rdparty/Qt/lib/cmake) set(Boost_USE_STATIC_LIBS ON) find_package(spdlog REQUIRED) find_package(Boost REQUIRED COMPONENTS filesystem) -find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia MultimediaWidgets) +find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia MultimediaWidgets + WaylandClient) message(STATUS "Qt6 was found at ${Qt6_DIR}") @@ -27,7 +28,18 @@ target_link_libraries( Qt6::Widgets Qt6::Multimedia Qt6::MultimediaWidgets - Qt6::QWaylandIntegrationPlugin) + Qt6::QWaylandEglPlatformIntegrationPlugin + Qt6::QWaylandIntegrationPlugin + Qt6::QXcbIntegrationPlugin + Qt6::QFFmpegMediaPlugin) -qt_import_plugins(snapshotapp INCLUDE_BY_TYPE platforms - Qt6::QWaylandIntegrationPlugin) +qt_import_plugins( + snapshotapp + INCLUDE_BY_TYPE + platforms + Qt6::QWaylandEglPlatformIntegrationPlugin + Qt6::QWaylandIntegrationPlugin + Qt6::QXcbIntegrationPlugin + INCLUDE_BY_TYPE + multimedia + Qt6::QFFmpegMediaPlugin)