nixos/ipu6, nixos/v4l2-relayd: fix device visibility, relay stability, and PipeWire integration (#511061)
This commit is contained in:
@@ -9,6 +9,7 @@ let
|
||||
inherit (lib)
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkForce
|
||||
mkIf
|
||||
mkOption
|
||||
optional
|
||||
@@ -38,6 +39,19 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
videoDeviceNumber = mkOption {
|
||||
type = types.int;
|
||||
default = 50;
|
||||
description = ''
|
||||
v4l2loopback device number for the relay output (`/dev/videoN`).
|
||||
|
||||
Must be fixed so application camera permission grants, which are keyed to
|
||||
the PipeWire node name (derived from the sysfs device path), survive
|
||||
reboots. Choose a number above the IPU6 raw node range (typically 3-34)
|
||||
and any other v4l2loopback devices on the system.
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
@@ -51,10 +65,32 @@ in
|
||||
ivsc-firmware
|
||||
];
|
||||
|
||||
# Restrict IPU6 raw nodes and media controller to root. DRIVERS== matches the
|
||||
# parent PCI device. TAG-="uaccess" blocks logind ACL grants at login.
|
||||
services.udev.extraRules = ''
|
||||
SUBSYSTEM=="intel-ipu6-psys", MODE="0660", GROUP="video"
|
||||
SUBSYSTEM=="media", DRIVERS=="intel-ipu6", MODE="0600", GROUP="root", TAG-="uaccess"
|
||||
SUBSYSTEM=="video4linux", DRIVERS=="intel-ipu6", MODE="0600", GROUP="root", TAG-="uaccess"
|
||||
'';
|
||||
|
||||
# ipu6-camera-hal writes AIQ tuning data and debug logs here.
|
||||
systemd.tmpfiles.rules = [ "d /run/camera 0755 root video -" ];
|
||||
|
||||
# Disable raw IPU6 nodes in WirePlumber. Matched via udev ID_V4L_PRODUCT=ipu6,
|
||||
# set by the kernel at device registration without requiring a device open.
|
||||
services.pipewire.wireplumber.extraConfig."ipu6-v4l2-rules" = {
|
||||
"monitor.v4l2.rules" = [
|
||||
{
|
||||
matches = [ { "device.product.name" = "ipu6"; } ];
|
||||
actions = {
|
||||
"update-props" = {
|
||||
"device.disabled" = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
services.v4l2-relayd.instances.ipu6 = {
|
||||
enable = mkDefault true;
|
||||
|
||||
@@ -72,5 +108,23 @@ in
|
||||
format = mkIf (cfg.platform != "ipu6") (mkDefault "NV12");
|
||||
};
|
||||
};
|
||||
|
||||
# Override preStart/postStop from the v4l2-relayd module:
|
||||
# - Use a fixed device number so PipeWire node names (and application permission
|
||||
# grants) are stable across reboots. Exit 17 (EEXIST) is success.
|
||||
# - Keep the device alive on stop so apps survive relay restarts via
|
||||
# VIDIOC_DQBUF blocking rather than receiving errors.
|
||||
systemd.services.v4l2-relayd-ipu6 = {
|
||||
preStart = mkForce ''
|
||||
mkdir -p "$(dirname "$V4L2_DEVICE_FILE")"
|
||||
${config.boot.kernelPackages.v4l2loopback.bin}/bin/v4l2loopback-ctl \
|
||||
add --name "Intel MIPI Camera" --exclusive-caps=1 ${toString cfg.videoDeviceNumber} || [ $? -eq 17 ]
|
||||
echo /dev/video${toString cfg.videoDeviceNumber} > "$V4L2_DEVICE_FILE"
|
||||
'';
|
||||
postStop = mkForce ''
|
||||
rm -rf "$(dirname "$V4L2_DEVICE_FILE")"
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -221,6 +221,11 @@ in
|
||||
boot = mkIf ((length enabledInstances) > 0) {
|
||||
extraModulePackages = [ kernelPackages.v4l2loopback ];
|
||||
kernelModules = [ "v4l2loopback" ];
|
||||
# Prevent v4l2loopback from auto-creating a device at load time. An
|
||||
# unconfigured device has a degenerate framerate range that breaks
|
||||
# GStreamer caps negotiation. All devices are created at runtime via
|
||||
# v4l2loopback-ctl add in each instance's preStart instead.
|
||||
extraModprobeConfig = "options v4l2loopback devices=0";
|
||||
};
|
||||
|
||||
systemd.services = mkInstanceServices enabledInstances;
|
||||
|
||||
Reference in New Issue
Block a user