mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-04-16 01:28:26 +00:00
frigate: coral tpu support, audio model, nvidia ffmpeg hwaccel, other fixes (#357717)
This commit is contained in:
commit
7eb0c197fb
@ -87,6 +87,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).
|
||||
|
38
nixos/modules/hardware/coral.nix
Normal file
38
nixos/modules/hardware/coral.nix
Normal file
@ -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"
|
||||
'';
|
||||
})
|
||||
];
|
||||
}
|
@ -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
|
||||
|
@ -6,19 +6,28 @@
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
literalExpression
|
||||
any
|
||||
attrValues
|
||||
converge
|
||||
elem
|
||||
filterAttrsRecursive
|
||||
hasPrefix
|
||||
makeLibraryPath
|
||||
match
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkPackageOption
|
||||
mkIf
|
||||
mkOption
|
||||
optionalAttrs
|
||||
optionals
|
||||
types;
|
||||
|
||||
cfg = config.services.frigate;
|
||||
|
||||
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;
|
||||
@ -94,6 +103,15 @@ 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;
|
||||
|
||||
# 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
|
||||
|
||||
{
|
||||
@ -114,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;
|
||||
@ -171,7 +210,6 @@ in
|
||||
set-misc
|
||||
vod
|
||||
];
|
||||
recommendedProxySettings = mkDefault true;
|
||||
recommendedGzipSettings = mkDefault true;
|
||||
mapHashBucketSize = mkDefault 128;
|
||||
upstreams = {
|
||||
@ -202,6 +240,7 @@ in
|
||||
# auth_location.conf
|
||||
"/auth" = {
|
||||
proxyPass = "http://frigate-api/auth";
|
||||
recommendedProxySettings = true;
|
||||
extraConfig = ''
|
||||
internal;
|
||||
|
||||
@ -306,11 +345,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;
|
||||
};
|
||||
@ -318,6 +359,7 @@ in
|
||||
"/live/mse/api/ws" = {
|
||||
proxyPass = "http://frigate-go2rtc/api/ws";
|
||||
proxyWebsockets = true;
|
||||
recommendedProxySettings = true;
|
||||
extraConfig = nginxAuthRequest + nginxProxySettings + ''
|
||||
limit_except GET {
|
||||
deny all;
|
||||
@ -327,6 +369,7 @@ in
|
||||
"/live/webrtc/api/ws" = {
|
||||
proxyPass = "http://frigate-go2rtc/api/ws";
|
||||
proxyWebsockets = true;
|
||||
recommendedProxySettings = true;
|
||||
extraConfig = nginxAuthRequest + nginxProxySettings + ''
|
||||
limit_except GET {
|
||||
deny all;
|
||||
@ -336,6 +379,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;
|
||||
@ -345,6 +389,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;
|
||||
@ -355,6 +400,7 @@ in
|
||||
"/api/go2rtc/webrtc" = {
|
||||
proxyPass = "http://frigate-go2rtc/api/webrtc";
|
||||
proxyWebsockets = true;
|
||||
recommendedProxySettings = true;
|
||||
extraConfig = nginxAuthRequest + nginxProxySettings + ''
|
||||
limit_except GET {
|
||||
deny all;
|
||||
@ -363,12 +409,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;
|
||||
@ -492,6 +540,11 @@ in
|
||||
"frigate"
|
||||
];
|
||||
|
||||
hardware.coral = {
|
||||
usb.enable = mkDefault withCoralUSB;
|
||||
pcie.enable = mkDefault withCoralPCI;
|
||||
};
|
||||
|
||||
users.users.frigate = {
|
||||
isSystemUser = true;
|
||||
group = "frigate";
|
||||
@ -510,26 +563,35 @@ 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 ]);
|
||||
};
|
||||
path = with pkgs; [
|
||||
# unfree:
|
||||
# config.boot.kernelPackages.nvidiaPackages.latest.bin
|
||||
ffmpeg-headless
|
||||
ffmpeg'
|
||||
libva-utils
|
||||
procps
|
||||
radeontop
|
||||
] ++ lib.optionals (!stdenv.hostPlatform.isAarch64) [
|
||||
] ++ optionals (!stdenv.hostPlatform.isAarch64) [
|
||||
# not available on aarch64-linux
|
||||
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";
|
||||
|
||||
User = "frigate";
|
||||
Group = "frigate";
|
||||
SupplementaryGroups = [ "render" ] ++ optionals withCoral [ "coral" ];
|
||||
|
||||
AmbientCapabilities = optionals (elem cfg.vaapiDriver [ "i965" "iHD" ]) [ "CAP_PERFMON" ]; # for intel_gpu_top
|
||||
|
||||
UMask = "0027";
|
||||
|
||||
|
@ -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 {
|
||||
@ -72,14 +78,22 @@ 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
|
||||
|
||||
# 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 +145,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
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user