From aa0a26280dbc13f7fd02b4b30b1629720dd532b4 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 21 Nov 2024 14:54:58 +0100 Subject: [PATCH 01/12] libedgetpu: use dedicated coral group --- pkgs/by-name/li/libedgetpu/package.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkgs/by-name/li/libedgetpu/package.nix b/pkgs/by-name/li/libedgetpu/package.nix index 9ead9c5f60b3..563e4d56dda1 100644 --- a/pkgs/by-name/li/libedgetpu/package.nix +++ b/pkgs/by-name/li/libedgetpu/package.nix @@ -43,6 +43,12 @@ stdenv.mkDerivation { }) ]; + postPatch = '' + # Use dedicated group for coral devices + substituteInPlace debian/edgetpu-accelerator.rules \ + --replace-fail "plugdev" "coral" + ''; + makeFlags = [ "-f" "makefile_build/Makefile" From 2b2a669741df5025854714a9bb4ee61b02aef682 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 21 Nov 2024 14:56:52 +0100 Subject: [PATCH 02/12] nixos/coral: init Provides a small wrapper to enable support for Coral USB and PCIe devices. --- .../manual/release-notes/rl-2411.section.md | 2 + nixos/modules/hardware/coral.nix | 38 +++++++++++++++++++ nixos/modules/module-list.nix | 1 + 3 files changed, 41 insertions(+) create mode 100644 nixos/modules/hardware/coral.nix diff --git a/nixos/doc/manual/release-notes/rl-2411.section.md b/nixos/doc/manual/release-notes/rl-2411.section.md index e62065775b91..22ae9f241409 100644 --- a/nixos/doc/manual/release-notes/rl-2411.section.md +++ b/nixos/doc/manual/release-notes/rl-2411.section.md @@ -85,6 +85,8 @@ ## New Modules {#sec-release-24.11-new-modules} +- [Coral](https://coral.ai/), hardware support for Coral.ai Edge TPU devices. Available as [hardware.coral.usb.enable](#opt-hardware.coral.usb.enable) and [hardware.coral.pcie.enable](#opt-hardware.coral.pcie.enable). + - [Cyrus IMAP](https://github.com/cyrusimap/cyrus-imapd), an email, contacts and calendar server. Available as [services.cyrus-imap](#opt-services.cyrus-imap.enable) service. - [TaskChampion Sync-Server](https://github.com/GothenburgBitFactory/taskchampion-sync-server), a [Taskwarrior 3](https://taskwarrior.org/docs/upgrade-3/) sync server. Available as [services.taskchampion-sync-server](#opt-services.taskchampion-sync-server.enable). diff --git a/nixos/modules/hardware/coral.nix b/nixos/modules/hardware/coral.nix new file mode 100644 index 000000000000..4b0cadfc3cf0 --- /dev/null +++ b/nixos/modules/hardware/coral.nix @@ -0,0 +1,38 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (lib) + mkEnableOption + mkIf + mkMerge + ; + + cfg = config.hardware.coral; +in + +{ + options.hardware.coral = { + usb.enable = mkEnableOption "Coral USB support"; + pcie.enable = mkEnableOption "Coral PCIe support"; + }; + + config = mkMerge [ + (mkIf (cfg.usb.enable || cfg.pcie.enable) { + users.groups.coral = { }; + }) + (mkIf cfg.usb.enable { + services.udev.packages = with pkgs; [ libedgetpu ]; + }) + (mkIf cfg.pcie.enable { + boot.extraModulePackages = with config.boot.kernelPackages; [ gasket ]; + services.udev.extraRules = '' + SUBSYSTEM=="apex",MODE="0660",GROUP="coral" + ''; + }) + ]; +} diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index cc107eefe505..a1b8f52c0773 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -52,6 +52,7 @@ ./hardware/bladeRF.nix ./hardware/brillo.nix ./hardware/ckb-next.nix + ./hardware/coral.nix ./hardware/corectrl.nix ./hardware/cpu/amd-microcode.nix ./hardware/cpu/amd-sev.nix From b96c4a67b9b8438039bb109b88cf03e7429dc27d Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 21 Nov 2024 15:04:40 +0100 Subject: [PATCH 03/12] nixos/frigate: add support for Coral devices --- nixos/modules/services/video/frigate.nix | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix index 72e96df5442e..754c2b00f2c6 100644 --- a/nixos/modules/services/video/frigate.nix +++ b/nixos/modules/services/video/frigate.nix @@ -6,12 +6,17 @@ let inherit (lib) - literalExpression + any + attrValues + hasPrefix + makeLibraryPath mkDefault mkEnableOption mkPackageOption mkIf mkOption + optionalAttrs + optionals types; cfg = config.services.frigate; @@ -94,6 +99,11 @@ let proxy_connect_timeout 360; ''; + # Discover configured detectors for acceleration support + detectors = attrValues cfg.settings.detectors or {}; + withCoralUSB = any (d: d.type == "edgetpu" && hasPrefix "usb" d.device or "") detectors; + withCoralPCI = any (d: d.type == "edgetpu" && hasPrefix "pci" d.device or "") detectors; + withCoral = withCoralPCI || withCoralUSB; in { @@ -492,6 +502,11 @@ in "frigate" ]; + hardware.coral = { + usb.enable = mkDefault withCoralUSB; + pcie.enable = mkDefault withCoralPCI; + }; + users.users.frigate = { isSystemUser = true; group = "frigate"; @@ -510,6 +525,8 @@ in CONFIG_FILE = format.generate "frigate.yml" filteredConfig; HOME = "/var/lib/frigate"; PYTHONPATH = cfg.package.pythonPath; + } // optionalAttrs withCoral { + LD_LIBRARY_PATH = makeLibraryPath (with pkgs; [ libedgetpu ]); }; path = with pkgs; [ # unfree: @@ -530,6 +547,7 @@ in User = "frigate"; Group = "frigate"; + SupplementaryGroups = optionals withCoral [ "coral" ]; UMask = "0027"; From d31bf00e2baf9144de90e24a508b3bec79bbcd26 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 21 Nov 2024 15:07:12 +0100 Subject: [PATCH 04/12] nixos/frigate: stop enabling recommendedProxySettings globally Closes: #320512 --- nixos/modules/services/video/frigate.nix | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix index 754c2b00f2c6..6e8f78029a5a 100644 --- a/nixos/modules/services/video/frigate.nix +++ b/nixos/modules/services/video/frigate.nix @@ -181,7 +181,6 @@ in set-misc vod ]; - recommendedProxySettings = mkDefault true; recommendedGzipSettings = mkDefault true; mapHashBucketSize = mkDefault 128; upstreams = { @@ -212,6 +211,7 @@ in # auth_location.conf "/auth" = { proxyPass = "http://frigate-api/auth"; + recommendedProxySettings = true; extraConfig = '' internal; @@ -316,11 +316,13 @@ in }; "/ws" = { proxyPass = "http://frigate-mqtt-ws/"; + recommendedProxySettings = true; proxyWebsockets = true; extraConfig = nginxAuthRequest + nginxProxySettings; }; "/live/jsmpeg" = { proxyPass = "http://frigate-jsmpeg/"; + recommendedProxySettings = true; proxyWebsockets = true; extraConfig = nginxAuthRequest + nginxProxySettings; }; @@ -328,6 +330,7 @@ in "/live/mse/api/ws" = { proxyPass = "http://frigate-go2rtc/api/ws"; proxyWebsockets = true; + recommendedProxySettings = true; extraConfig = nginxAuthRequest + nginxProxySettings + '' limit_except GET { deny all; @@ -337,6 +340,7 @@ in "/live/webrtc/api/ws" = { proxyPass = "http://frigate-go2rtc/api/ws"; proxyWebsockets = true; + recommendedProxySettings = true; extraConfig = nginxAuthRequest + nginxProxySettings + '' limit_except GET { deny all; @@ -346,6 +350,7 @@ in # pass through go2rtc player "/live/webrtc/webrtc.html" = { proxyPass = "http://frigate-go2rtc/webrtc.html"; + recommendedProxySettings = true; extraConfig = nginxAuthRequest + nginxProxySettings + '' limit_except GET { deny all; @@ -355,6 +360,7 @@ in # frontend uses this to fetch the version "/api/go2rtc/api" = { proxyPass = "http://frigate-go2rtc/api"; + recommendedProxySettings = true; extraConfig = nginxAuthRequest + nginxProxySettings + '' limit_except GET { deny all; @@ -365,6 +371,7 @@ in "/api/go2rtc/webrtc" = { proxyPass = "http://frigate-go2rtc/api/webrtc"; proxyWebsockets = true; + recommendedProxySettings = true; extraConfig = nginxAuthRequest + nginxProxySettings + '' limit_except GET { deny all; @@ -373,12 +380,14 @@ in }; "~* /api/.*\.(jpg|jpeg|png|webp|gif)$" = { proxyPass = "http://frigate-api"; + recommendedProxySettings = true; extraConfig = nginxAuthRequest + nginxProxySettings + '' rewrite ^/api/(.*)$ $1 break; ''; }; "/api/" = { proxyPass = "http://frigate-api/"; + recommendedProxySettings = true; extraConfig = nginxAuthRequest + nginxProxySettings + '' add_header Cache-Control "no-store"; expires off; From 4abc3dfc2811e49e4f79c874cba7460b0e22fc60 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 21 Nov 2024 15:18:11 +0100 Subject: [PATCH 05/12] frigate: provide the tflite audio model --- pkgs/by-name/fr/frigate/package.nix | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/pkgs/by-name/fr/frigate/package.nix b/pkgs/by-name/fr/frigate/package.nix index 7ee4f6eba606..03229c25c5f9 100644 --- a/pkgs/by-name/fr/frigate/package.nix +++ b/pkgs/by-name/fr/frigate/package.nix @@ -29,6 +29,12 @@ let }; }; + # Tensorflow audio model + tflite_audio_model = fetchurl { + url = "https://www.kaggle.com/api/v1/models/google/yamnet/tfLite/classification-tflite/1/download"; + hash = "sha256-G5cbITJ2AnOl+49dxQToZ4OyeFO7MTXVVa4G8eHjZfM="; + }; + # Tensorflow Lite models # https://github.com/blakeblackshear/frigate/blob/v0.13.0/docker/main/Dockerfile#L96-L97 tflite_cpu_model = fetchurl { @@ -76,10 +82,15 @@ python.pkgs.buildPythonApplication rec { substituteInPlace frigate/ptz/onvif.py \ --replace-fail dist-packages site-packages + # provide default paths for models and maps that are shipped with frigate substituteInPlace frigate/config.py \ --replace-fail "/cpu_model.tflite" "${tflite_cpu_model}" \ --replace-fail "/edgetpu_model.tflite" "${tflite_edgetpu_model}" + substituteInPlace frigate/events/audio.py \ + --replace-fail "/cpu_audio_model.tflite" "${placeholder "out"}/share/frigate/cpu_audio_model.tflite" \ + --replace-fail "/audio-labelmap.txt" "${placeholder "out"}/share/frigate/audio-labelmap.txt" + substituteInPlace frigate/test/test_config.py \ --replace-fail "(MODEL_CACHE_DIR" "('/build/model_cache'" \ --replace-fail "/config/model_cache" "/build/model_cache" @@ -131,7 +142,10 @@ python.pkgs.buildPythonApplication rec { cp -R frigate/* $out/${python.sitePackages}/frigate/ mkdir -p $out/share/frigate - cp -R {migrations,labelmap.txt} $out/share/frigate/ + cp -R {migrations,labelmap.txt,audio-labelmap.txt} $out/share/frigate/ + + tar --extract --gzip --file ${tflite_audio_model} + cp --no-preserve=mode ./1.tflite $out/share/frigate/cpu_audio_model.tflite cp --no-preserve=mode ${openvino_model} $out/share/frigate/coco_91cl_bkgr.txt sed -i 's/truck/car/g' $out/share/frigate/coco_91cl_bkgr.txt From 7e33e470df5dcbb9c84d6a08a1128953c4281e17 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 21 Nov 2024 16:15:59 +0100 Subject: [PATCH 06/12] nixos/frigate: provide ffmpeg-full for nvidia hw accel Closes: #344114 --- nixos/modules/services/video/frigate.nix | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix index 6e8f78029a5a..1f4a6ee96cba 100644 --- a/nixos/modules/services/video/frigate.nix +++ b/nixos/modules/services/video/frigate.nix @@ -10,6 +10,7 @@ let attrValues hasPrefix makeLibraryPath + match mkDefault mkEnableOption mkPackageOption @@ -104,6 +105,10 @@ let withCoralUSB = any (d: d.type == "edgetpu" && hasPrefix "usb" d.device or "") detectors; withCoralPCI = any (d: d.type == "edgetpu" && hasPrefix "pci" d.device or "") detectors; withCoral = withCoralPCI || withCoralUSB; + + # Provide ffmpeg-full for NVIDIA hardware acceleration + ffmpegArgs = cfg.settings.ffmpeg.hwaccel_args or ""; + ffmpeg' = if match "/nvidia/" ffmpegArgs != null then pkgs.ffmpeg-full else pkgs.ffmpeg-headless; in { @@ -540,7 +545,7 @@ in path = with pkgs; [ # unfree: # config.boot.kernelPackages.nvidiaPackages.latest.bin - ffmpeg-headless + ffmpeg' libva-utils procps radeontop From 81001625a7a756dbfc50fbe5ae75d52b26c93e3f Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 21 Nov 2024 17:09:17 +0100 Subject: [PATCH 07/12] linuxPackages_latest.gasket: fix build with 6.12 --- pkgs/os-specific/linux/gasket/default.nix | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/pkgs/os-specific/linux/gasket/default.nix b/pkgs/os-specific/linux/gasket/default.nix index a25bbeee4033..65516be7dcd1 100644 --- a/pkgs/os-specific/linux/gasket/default.nix +++ b/pkgs/os-specific/linux/gasket/default.nix @@ -1,4 +1,10 @@ -{ stdenv, lib, fetchFromGitHub, kernel }: +{ + stdenv, + lib, + fetchFromGitHub, + fetchpatch2, + kernel +}: stdenv.mkDerivation rec { pname = "gasket"; @@ -11,6 +17,20 @@ stdenv.mkDerivation rec { sha256 = "O17+msok1fY5tdX1DvqYVw6plkUDF25i8sqwd6mxYf8="; }; + patches = [ + (fetchpatch2 { + # https://github.com/google/gasket-driver/issues/36 + # https://github.com/google/gasket-driver/pull/35 + name = "linux-6.12-compat.patch"; + url = "https://github.com/google/gasket-driver/commit/4b2a1464f3b619daaf0f6c664c954a42c4b7ce00.patch"; + hash = "sha256-UOoOSEnpUMa4QXWVFpGFxBoF5szXaLEfcWtfKatO5XY="; + }) + ]; + + postPatch = '' + cd src + ''; + makeFlags = kernel.makeFlags ++ [ "-C" "${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" @@ -21,7 +41,6 @@ stdenv.mkDerivation rec { installFlags = [ "INSTALL_MOD_PATH=${placeholder "out"}" ]; installTargets = [ "modules_install" ]; - sourceRoot = "${src.name}/src"; hardeningDisable = [ "pic" "format" ]; nativeBuildInputs = kernel.moduleBuildDependencies; From a810c07ff275612177aa5aed5bf37ec7658577de Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 21 Nov 2024 22:31:27 +0100 Subject: [PATCH 08/12] nixos/frigate: inherit required functions from lib --- nixos/modules/services/video/frigate.nix | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix index 1f4a6ee96cba..0d93ae1eec8c 100644 --- a/nixos/modules/services/video/frigate.nix +++ b/nixos/modules/services/video/frigate.nix @@ -8,6 +8,9 @@ let inherit (lib) any attrValues + converge + elem + filterAttrsRecursive hasPrefix makeLibraryPath match @@ -24,7 +27,7 @@ let format = pkgs.formats.yaml { }; - filteredConfig = lib.converge (lib.filterAttrsRecursive (_: v: ! lib.elem v [ null ])) cfg.settings; + filteredConfig = converge (filterAttrsRecursive (_: v: ! elem v [ null ])) cfg.settings; cameraFormat = with types; submodule { freeformType = format.type; @@ -549,7 +552,7 @@ in libva-utils procps radeontop - ] ++ lib.optionals (!stdenv.hostPlatform.isAarch64) [ + ] ++ optionals (!stdenv.hostPlatform.isAarch64) [ # not available on aarch64-linux intel-gpu-tools ]; From 2b56a916ca59813eb73fd12ba42d8c335f21b4ef Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Thu, 21 Nov 2024 23:57:35 +0100 Subject: [PATCH 09/12] nixos/frigate: use shellscript to clear frigate cache Shell expansions apparently do not work correctly in systemd command lines. Co-Authored-By: Joshua Manchester --- nixos/modules/services/video/frigate.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix index 0d93ae1eec8c..43faa3a19ded 100644 --- a/nixos/modules/services/video/frigate.nix +++ b/nixos/modules/services/video/frigate.nix @@ -557,7 +557,9 @@ in intel-gpu-tools ]; serviceConfig = { - ExecStartPre = "-rm /var/cache/frigate/*.mp4"; + ExecStartPre = pkgs.writeShellScript "frigate-clear-cache" '' + rm --recursive --force /var/cache/frigate/* + ''; ExecStart = "${cfg.package.python.interpreter} -m frigate"; Restart = "on-failure"; SyslogIdentifier = "frigate"; From 7411b8562915f37d5dec7127b89cf34aabcc1424 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Fri, 22 Nov 2024 02:41:52 +0100 Subject: [PATCH 10/12] nixos/frigate: allow GPU use for video acceleration The `render` group is required to acces the graphic cards decoding, encoding and transcoding capabilities. It is required for using fancy `ffmpeg.hwaccel-args` values, like `preset-vaapi`. --- nixos/modules/services/video/frigate.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix index 43faa3a19ded..f04aed08f99a 100644 --- a/nixos/modules/services/video/frigate.nix +++ b/nixos/modules/services/video/frigate.nix @@ -566,7 +566,7 @@ in User = "frigate"; Group = "frigate"; - SupplementaryGroups = optionals withCoral [ "coral" ]; + SupplementaryGroups = [ "render" ] ++ optionals withCoral [ "coral" ]; UMask = "0027"; From 1c07d92099551535ed7f74d64c87aca4a6c6514b Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Fri, 22 Nov 2024 03:12:50 +0100 Subject: [PATCH 11/12] nixos/frigate: allow configuring a libva driver In my testing this helped steer VA-API towards the correct card and also made it show GPU statistics in performance monitoring. --- nixos/modules/services/video/frigate.nix | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/nixos/modules/services/video/frigate.nix b/nixos/modules/services/video/frigate.nix index f04aed08f99a..bc0f5d496afb 100644 --- a/nixos/modules/services/video/frigate.nix +++ b/nixos/modules/services/video/frigate.nix @@ -132,6 +132,27 @@ in ''; }; + vaapiDriver = mkOption { + type = nullOr (enum [ "i965" "iHD" "nouveau" "vdpau" "nvidia" "radeonsi" ]); + default = null; + example = "radeonsi"; + description = '' + Force usage of a particular VA-API driver for video acceleration. Use together with `settings.ffmpeg.hwaccel_args`. + + Setting this *is not required* for VA-API to work, but it can help steer VA-API towards the correct card if you have multiple. + + :::{.note} + For VA-API to work you must enable {option}`hardware.graphics.enable` (sufficient for AMDGPU) and pass for example + `pkgs.intel-media-driver` (required for Intel 5th Gen. and newer) into {option}`hardware.graphics.extraPackages`. + ::: + + See also: + + - https://docs.frigate.video/configuration/hardware_acceleration + - https://docs.frigate.video/configuration/ffmpeg_presets#hwaccel-presets + ''; + }; + settings = mkOption { type = submodule { freeformType = format.type; @@ -542,6 +563,8 @@ in CONFIG_FILE = format.generate "frigate.yml" filteredConfig; HOME = "/var/lib/frigate"; PYTHONPATH = cfg.package.pythonPath; + } // optionalAttrs (cfg.vaapiDriver != null) { + LIBVA_DRIVER_NAME = cfg.vaapiDriver; } // optionalAttrs withCoral { LD_LIBRARY_PATH = makeLibraryPath (with pkgs; [ libedgetpu ]); }; @@ -568,6 +591,8 @@ in Group = "frigate"; SupplementaryGroups = [ "render" ] ++ optionals withCoral [ "coral" ]; + AmbientCapabilities = optionals (elem cfg.vaapiDriver [ "i965" "iHD" ]) [ "CAP_PERFMON" ]; # for intel_gpu_top + UMask = "0027"; StateDirectory = "frigate"; From 591ebd39fb053579566ffe15519c71a4e29b0788 Mon Sep 17 00:00:00 2001 From: Martin Weinelt Date: Fri, 22 Nov 2024 17:42:03 +0100 Subject: [PATCH 12/12] frigate: patch path to birdseye graphic --- pkgs/by-name/fr/frigate/package.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkgs/by-name/fr/frigate/package.nix b/pkgs/by-name/fr/frigate/package.nix index 03229c25c5f9..4578d709a0ac 100644 --- a/pkgs/by-name/fr/frigate/package.nix +++ b/pkgs/by-name/fr/frigate/package.nix @@ -78,6 +78,9 @@ python.pkgs.buildPythonApplication rec { substituteInPlace frigate/detectors/detector_config.py \ --replace-fail "/labelmap.txt" "${placeholder "out"}/share/frigate/labelmap.txt" + substituteInPlace frigate/output/birdseye.py \ + --replace-fail "/opt/frigate/" "${placeholder "out"}/${python.sitePackages}/" + # work around onvif-zeep idiosyncrasy substituteInPlace frigate/ptz/onvif.py \ --replace-fail dist-packages site-packages