From 8b2f1ed9dd086143aaa32d7cf94e3e97674f0693 Mon Sep 17 00:00:00 2001 From: 514fpv Date: Wed, 10 Jan 2024 23:49:00 +0800 Subject: [PATCH] home(gyroflow): add package and module --- home/gyroflow/home.nix | 11 ++ home/gyroflow/nixos.nix | 19 ++ home/gyroflow/package/crash-dump.patch | 27 +++ home/gyroflow/package/default.nix | 253 +++++++++++++++++++++++++ 4 files changed, 310 insertions(+) create mode 100644 home/gyroflow/home.nix create mode 100644 home/gyroflow/nixos.nix create mode 100644 home/gyroflow/package/crash-dump.patch create mode 100644 home/gyroflow/package/default.nix diff --git a/home/gyroflow/home.nix b/home/gyroflow/home.nix new file mode 100644 index 00000000..a0e708a1 --- /dev/null +++ b/home/gyroflow/home.nix @@ -0,0 +1,11 @@ +{ pkgs +, lib +, config +, ... }: with lib; let + cfg = config.passthrough.gyroflow; +in mkIf cfg.enable { + home.packages = with pkgs; [ (pkgs.callPackage ./package { + inherit (pkgs.qt6) wrapQtAppsHook qmake + qtbase qtsvg qtwayland qtvirtualkeyboard qtdeclarative; + }) ]; +} diff --git a/home/gyroflow/nixos.nix b/home/gyroflow/nixos.nix new file mode 100644 index 00000000..34fe3356 --- /dev/null +++ b/home/gyroflow/nixos.nix @@ -0,0 +1,19 @@ +{ pkgs +, lib +, config +, ... }: with lib; let + cfg = config.home.gyroflow; +in { + options.home.gyroflow = { + enable = mkEnableOption "gyroflow stabilisation software"; + }; + + config = { + users.homeModules = [ + # this module passes gyroflow configuration to home-manager + { passthrough.gyroflow = cfg; } + ]; + + users.home.persist.directories = [ ".config/Gyroflow" ]; + }; +} diff --git a/home/gyroflow/package/crash-dump.patch b/home/gyroflow/package/crash-dump.patch new file mode 100644 index 00000000..bc953294 --- /dev/null +++ b/home/gyroflow/package/crash-dump.patch @@ -0,0 +1,27 @@ +diff --git a/src/util.rs b/src/util.rs +index 1d58ffb8..afee58d4 100644 +--- a/src/util.rs ++++ b/src/util.rs +@@ -302,22 +302,6 @@ pub fn install_crash_handler() -> std::io::Result<()> { + } + } + +- // Upload crash dumps +- crate::core::run_threaded(move || { +- if let Ok(files) = std::fs::read_dir(cur_dir) { +- for path in files.flatten() { +- let path = path.path(); +- if path.to_string_lossy().ends_with(".dmp") { +- if let Ok(content) = std::fs::read(&path) { +- if let Ok(Ok(body)) = ureq::post("https://api.gyroflow.xyz/upload_dump").set("Content-Type", "application/octet-stream").send_bytes(&content).map(|x| x.into_string()) { +- ::log::debug!("Minidump uploaded: {}", body.as_str()); +- let _ = std::fs::remove_file(path); +- } +- } +- } +- } +- } +- }); + Ok(()) + } + diff --git a/home/gyroflow/package/default.nix b/home/gyroflow/package/default.nix new file mode 100644 index 00000000..a35bdf43 --- /dev/null +++ b/home/gyroflow/package/default.nix @@ -0,0 +1,253 @@ +{ lib +, stdenv +, stdenvNoCC +, symlinkJoin +, fetchurl +, fetchpatch +, fetchFromGitHub +, writeShellScript +, writeShellScriptBin +, makeDesktopItem +, fetchzip +, rustPlatform +, alsaLib +, libpulseaudio +, ffmpeg +, libclang +, xorg +, wayland +, glfw +, libva +, mesa +, libdrm +, xz +, zlib +, ocl-icd +, opencv +, qtbase +, qtsvg +, qtwayland +, qtvirtualkeyboard +, qtdeclarative +, qmake +, clang +, imagemagick +, wrapQtAppsHook +, autoPatchelfHook +, pkg-config }: let + name = "gyroflow"; + version = "1.5.4"; + + src-unpatched = fetchFromGitHub { + name = "${name}-src-unpatched"; + owner = name; + repo = name; + rev = "v${version}"; + hash = "sha256-Pdqe8T03KpO3ApOjm/z7gd5waQOvEZBHcvdrLyot4O8="; + }; + + mdk-sdk = stdenvNoCC.mkDerivation rec { + name = "mdk-sdk"; + version = "20240110111804"; + src = fetchzip { + name = "mdk-sdk"; + # unfortunately the only way to pin the version + url = "https://web.archive.org/web/${version}if_/https://master.dl.sourceforge.net/project/mdk-sdk/mdk-sdk-linux.tar.xz?viasf=1"; + hash = "sha256-Jtdp0YKVOK5+0xBigezB2Oatsr00gAgJuCZlbzpZPHk="; + }; + + buildInputs = [ + stdenv.cc.cc.lib + alsaLib libpulseaudio + glfw libdrm mesa + xz wayland xorg.libX11 + ]; + + nativeBuildInputs = [ autoPatchelfHook ]; + + installPhase = '' + cp -r . "$out" + ''; + }; + + gyroflow-unwrapped = rustPlatform.buildRustPackage rec { + pname = "gyroflow-unwrapped"; + inherit version; + cargoHash = "sha256-KkGXKoVRZZ7HUTtWYBerrN36a7RqsHjYQb+bwG1JagY="; + cargoLock = { + outputHashes = { + "ahrs-0.6.0" = "sha256-CxWyX8t+BjqIyNj1p1LdkCmNrtJkudmKgZPv0MVcghY="; + "akaze-0.7.0" = "sha256-KkGXKoVRZZ7HUTtWYBerrN36a7RqsHjYQb+bwG1JagY="; + "d3d12-0.7.0" = "sha256-0b/LozKVPm+UQTO066s5uoebRxEWoC0V8T7a6e0z9YE="; + "fc-blackbox-0.2.0" = "sha256-gL8m9DpHJPVD8vvrmuYv+biJT4PA5LmtohJwFVO+khU="; + "glow-0.13.0" = "sha256-vhPWzsm7NZx9JiRZcVoUslTGySQbASRh/wNlo1nK5jg="; + "keep-awake-0.1.0" = "sha256-EoXhK4/Aij70f73+5NBUoCXqZISG1+n2eVavNqe8mq4="; + "nshare-0.9.0" = "sha256-PAV41mMLDmhkAz4+qyf+MZnYTAdMwjk83+f+RdaJji8="; + "qmetaobject-0.2.10" = "sha256-ldmpbOYoCOaAoipfcCSwuV+fzF9gg1PTbRz2Jm4zJvA="; + "qml-video-rs-0.1.0" = "sha256-yvA+Je50rF6SgTxDQuDPgyM2MgtD4AAV9uGnAj/ecf4="; + "rs-sync-0.1.0" = "sha256-sfym7zv5SUitopqNJ6uFP6AMzAGf4Y7U0dzXAKlvuGA="; + "simplelog-0.12.0" = "sha256-NvmtLbzahSw1WMS3LY+jWiX4SxfSRwidTMvICGcmDO4="; + "system_shutdown-4.0.1" = "sha256-arJWmEjDdaig/oAfwSolVmk9s1UovrQ5LNUgTpUvoOQ="; + "telemetry-parser-0.2.8" = "sha256-J4eHCojoGKKbqVKHkyQjxXbfrYsyYn7DR7ZdogbOQK4="; + }; + + lockFile = "${src}/Cargo.lock"; + }; + + # breaks some build.rs + dontCargoCheck = true; + + src = stdenvNoCC.mkDerivation { + name = "${name}-src"; + inherit version; + phases = [ "unpackPhase" "patchPhase" "installPhase" ]; + installPhase = '' + cp -r . "$out" + ''; + patches = [ + (fetchpatch { + name = "fix-ffmpeg.patch"; + url = "https://github.com/gyroflow/gyroflow/compare/v1.5.4...cdca1ee.patch"; + hash = "sha256-kEjKlFSa02sa2NvFyoFl1EWL4TuLeFsmYOY0/dYykrg="; + }) + ./crash-dump.patch + ]; + src = src-unpatched; + }; + + buildInputs = [ + alsaLib + ffmpeg + libclang + ocl-icd + opencv + zlib.static + qtdeclarative + wrapQtAppsHook + ]; + + nativeBuildInputs = [ pkg-config qmake clang ] ++ [ + # build.rs abuses qt path variables to get path to qmlcachegen + # it fails and falls back to calling qmlcachegen directly which doesn't work + # since it's in libexec, this derivation provides a wrapper to make it work + (writeShellScriptBin "qmlcachegen" '' + exec "${qtdeclarative}/libexec/qmlcachegen" "$@" + '') + ]; + + # build error debugging + RUST_BACKTRACE="full"; + # build script cannot find libclang + LIBCLANG_PATH="${libclang.lib}/lib"; + # proprietary mdk-sdk library has to be patched + MDK_SDK="${mdk-sdk}/"; + # compiler cannot find these for some reason + CPLUS_INCLUDE_PATH=lib.concatImapStrings (i: path: + (if i != 1 then ":" else "") + + "${qtdeclarative}/include/${path}") [ + "QtQuick" + "QtQuick/${qtdeclarative.version}" + "QtQuick/${qtdeclarative.version}/QtQuick" + "QtQml" + "QtQml/${qtdeclarative.version}" + "QtQml/${qtdeclarative.version}/QtQml" + "QtQuickControls2" + "QtQuickControls2/${qtdeclarative.version}" + "QtQuickControls2/${qtdeclarative.version}/QtQuickControls2" + ]; + # build.rs relies on these variables to point to deps + # instead of discovering them properly + OPENCV_LINK_PATHS="${opencv}"; + OPENCV_LINK_LIBS=lib.concatImapStrings (i: opt: + (if i != 1 then "," else "") + opt) [ + "opencv_core" + "opencv_calib3d" + "opencv_features2d" + "opencv_imgproc" + "opencv_video" + "opencv_flann" + "opencv_dnn" + "opencv_imgcodecs" + "opencv_objdetect" + "opencv_stitching" + "png" + ]; + FFMPEG_DIR="${ffmpeg.dev}"; + + installPhase = '' + CARGO_TARGET="target/x86_64-unknown-linux-gnu/release/" + FFMPEG_DIR=${ffmpeg.lib} + + mkdir -p "$out" + mkdir -p "$out/lib" + + cp -f "$CARGO_TARGET/libmdk.so.0" "$out/lib/" + cp -f "$CARGO_TARGET/libmdk-braw.so" "$out/lib/" + cp -f "$CARGO_TARGET/libmdk-r3d.so" "$out/lib/" + + cp -f "$CARGO_TARGET/gyroflow" "$out/" + strip "$out/gyroflow" + + cp -rf "${lens-profiles}" "$out/camera_presets" + ''; + }; + + lens-profiles = fetchFromGitHub { + name = "gyroflow-lens-profiles"; + owner = name; + repo = "lens_profiles"; + rev = "3e72169ae6b8601260497d7216d5fcbbc8b67194"; + hash = "sha256-18KtunSxTsJhBge+uOGBcNZRG3W26M/Osyxllu+N0UI="; + }; + + gyroflow-qt-runtime = symlinkJoin { + name = "gyroflow-qt-runtime"; + paths = [ + qtbase + qtsvg + qtwayland + qtdeclarative + qtvirtualkeyboard + ]; + }; + + desktopItem = makeDesktopItem { + inherit name; + exec = name; + icon = name; + comment = '' + Advanced gyro-based video stabilization tool for cinematography, drone videography and much more! + ''; + desktopName = "Gyroflow"; + genericName = "Video stabilization tool"; + }; +in stdenvNoCC.mkDerivation { + pname = name; + inherit version; + phases = [ "unpackPhase" "patchPhase" "installPhase" ]; + src = src-unpatched; + + nativeBuildInputs = [ imagemagick ]; + + installPhase = '' + mkdir -p "$out/bin" + + convert resources/icon.png -resize 128x128 icon-128.png + install -m 444 -D icon-128.png $out/share/icons/hicolor/128x128/apps/${name}.png + cp -r ${desktopItem}/share/applications $out/share/ + + # mdk-sdk reads program name as part of its license check + # therefore a custom wrapper that preserves the gyroflow name is required + cp ${writeShellScript "gyroflow-wrapper" '' + export QT_PLUGIN_PATH=${gyroflow-qt-runtime}/lib/qt-6/plugins + export QML2_IMPORT_PATH=${qtdeclarative}/lib/qt-6/qml + + # does not find drivers without this + export LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver/lib/dri:/run/opengl-driver/lib/vdpau:${libva.out}/lib" + # video acceleration in preview only works with this set + export MDK_DECODERS=VAAPI + + exec -a "$0" "${gyroflow-unwrapped}/gyroflow" "$@" + ''} $out/bin/gyroflow + ''; +}