"""DRM render-node identity for this host. Arc B580 PCI id 0xe20b (today often renderD128). iGPU UHD 770 PCI id 0xa780 (today often renderD129). Card indexes swap; never hardcode which is Arc. Encode belongs on the iGPU. The Arc is kmssink wall only. LiveKit PreEncoded publish does not need a VA bind-mount. """ from __future__ import annotations import logging import os from pathlib import Path log = logging.getLogger("cameras.vaapi") ARC_PCI = "0xe20b" IGPU_PCI = "0xa780" def _pci_id_of_render(node: str) -> str: name = Path(node).name p = Path("/sys/class/drm") / name / "device" / "device" try: return p.read_text().strip().lower() except OSError: return "" def classify_render_nodes( nodes: list[str] | None = None, pci_id_of=None, ) -> dict: reader = pci_id_of or _pci_id_of_render if nodes is None: dri = Path("/dev/dri") nodes = sorted(str(p) for p in dri.glob("renderD*")) if dri.is_dir() else [] arc = igpu = None ids: dict[str, str] = {} for n in nodes: pid = (reader(n) or "").strip().lower() if not pid.startswith("0x"): try: pid = hex(int(pid, 16)) except ValueError: pass ids[n] = pid if pid == ARC_PCI: arc = n elif pid == IGPU_PCI: igpu = n return {"arc": arc, "igpu": igpu, "ids": ids} def igpu_render() -> str: found = classify_render_nodes()["igpu"] if found: return found fallback = "/dev/dri/renderD129" log.warning("iGPU PCI %s not found; falling back to %s", IGPU_PCI, fallback) return fallback def arc_render() -> str: found = classify_render_nodes()["arc"] if found: return found fallback = "/dev/dri/renderD128" log.warning("Arc PCI %s not found; falling back to %s", ARC_PCI, fallback) return fallback def pin_encode_env(env: dict | None = None, igpu: str | None = None) -> dict: out = dict(os.environ if env is None else env) node = igpu or igpu_render() out["LIBVA_DRIVER_NAME"] = "iHD" out["GST_VA_ALL_DRIVERS"] = "1" out["LIVEKIT_ENCODE_RENDER"] = node out.pop("LIBVA_DRM_DEVICE", None) return out def should_pin_vaapi(preencoded: bool) -> bool: return not bool(preencoded) def pin_arc_vaapi_env(env: dict | None = None) -> dict: """Deprecated: PreEncoded does not encode in libwebrtc.""" out = dict(os.environ if env is None else env) out["LIBVA_DRIVER_NAME"] = "iHD" out["GST_VA_ALL_DRIVERS"] = "1" return out def apply_env(env: dict) -> None: for k, v in env.items(): os.environ[k] = v def bind_arc_over_igpu_render(arc: str | None = None, igpu: str | None = None) -> bool: """Deprecated leftover. Do not call from capture or publisher.""" del arc, igpu log.warning("bind_arc_over_igpu_render is deprecated; skipped") return False