From 01392e03ac6b81086ae418328b4a39aea787eb33 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Mon, 23 Mar 2026 16:16:54 -0600 Subject: [PATCH 001/134] Update docs for DEIMv2 support (#22598) --- docs/docs/configuration/object_detectors.md | 106 ++++++++++++++++++-- 1 file changed, 98 insertions(+), 8 deletions(-) diff --git a/docs/docs/configuration/object_detectors.md b/docs/docs/configuration/object_detectors.md index 9bdacfb28d..4eb7933cdc 100644 --- a/docs/docs/configuration/object_detectors.md +++ b/docs/docs/configuration/object_detectors.md @@ -330,7 +330,7 @@ detectors: | [YOLO-NAS](#yolo-nas) | ✅ | ✅ | | | [MobileNet v2](#ssdlite-mobilenet-v2) | ✅ | ✅ | Fast and lightweight model, less accurate than larger models | | [YOLOX](#yolox) | ✅ | ? | | -| [D-FINE](#d-fine) | ❌ | ❌ | | +| [D-FINE / DEIMv2](#d-fine--deimv2) | ❌ | ❌ | | #### SSDLite MobileNet v2 @@ -464,13 +464,13 @@ model: -#### D-FINE +#### D-FINE / DEIMv2 -[D-FINE](https://github.com/Peterande/D-FINE) is a DETR based model. The ONNX exported models are supported, but not included by default. See [the models section](#downloading-d-fine-model) for more information on downloading the D-FINE model for use in Frigate. +[D-FINE](https://github.com/Peterande/D-FINE) and [DEIMv2](https://github.com/Intellindust-AI-Lab/DEIMv2) are DETR based models that share the same ONNX input/output format. The ONNX exported models are supported, but not included by default. See the models section for downloading [D-FINE](#downloading-d-fine-model) or [DEIMv2](#downloading-deimv2-model) for use in Frigate. :::warning -Currently D-FINE models only run on OpenVINO in CPU mode, GPUs currently fail to compile the model +Currently D-FINE / DEIMv2 models only run on OpenVINO in CPU mode, GPUs currently fail to compile the model ::: @@ -499,6 +499,31 @@ Note that the labelmap uses a subset of the complete COCO label set that has onl +
+ DEIMv2 Setup & Config + +After placing the downloaded onnx model in your `config/model_cache` folder, you can use the following configuration: + +```yaml +detectors: + ov: + type: openvino + device: CPU + +model: + model_type: dfine + width: 640 + height: 640 + input_tensor: nchw + input_dtype: float + path: /config/model_cache/deimv2_hgnetv2_n.onnx + labelmap_path: /labelmap/coco-80.txt +``` + +Note that the labelmap uses a subset of the complete COCO label set that has only 80 objects. + +
+ ## Apple Silicon detector The NPU in Apple Silicon can't be accessed from within a container, so the [Apple Silicon detector client](https://github.com/frigate-nvr/apple-silicon-detector) must first be setup. It is recommended to use the Frigate docker image with `-standard-arm64` suffix, for example `ghcr.io/blakeblackshear/frigate:stable-standard-arm64`. @@ -648,7 +673,7 @@ The AMD GPU kernel is known problematic especially when converting models to mxr See [ONNX supported models](#supported-models) for supported models, there are some caveats: -- D-FINE models are not supported +- D-FINE / DEIMv2 models are not supported - YOLO-NAS models are known to not run well on integrated GPUs ## ONNX @@ -693,7 +718,7 @@ detectors: | [RF-DETR](#rf-detr) | ✅ | ❌ | Supports CUDA Graphs for optimal Nvidia performance | | [YOLO-NAS](#yolo-nas-1) | ⚠️ | ⚠️ | Not supported by CUDA Graphs | | [YOLOX](#yolox-1) | ✅ | ✅ | Supports CUDA Graphs for optimal Nvidia performance | -| [D-FINE](#d-fine) | ⚠️ | ❌ | Not supported by CUDA Graphs | +| [D-FINE / DEIMv2](#d-fine--deimv2-1) | ⚠️ | ❌ | Not supported by CUDA Graphs | There is no default model provided, the following formats are supported: @@ -822,9 +847,9 @@ model: -#### D-FINE +#### D-FINE / DEIMv2 -[D-FINE](https://github.com/Peterande/D-FINE) is a DETR based model. The ONNX exported models are supported, but not included by default. See [the models section](#downloading-d-fine-model) for more information on downloading the D-FINE model for use in Frigate. +[D-FINE](https://github.com/Peterande/D-FINE) and [DEIMv2](https://github.com/Intellindust-AI-Lab/DEIMv2) are DETR based models that share the same ONNX input/output format. The ONNX exported models are supported, but not included by default. See the models section for downloading [D-FINE](#downloading-d-fine-model) or [DEIMv2](#downloading-deimv2-model) for use in Frigate.
D-FINE Setup & Config @@ -848,6 +873,28 @@ model:
+
+ DEIMv2 Setup & Config + +After placing the downloaded onnx model in your `config/model_cache` folder, you can use the following configuration: + +```yaml +detectors: + onnx: + type: onnx + +model: + model_type: dfine + width: 640 + height: 640 + input_tensor: nchw + input_dtype: float + path: /config/model_cache/deimv2_hgnetv2_n.onnx + labelmap_path: /labelmap/coco-80.txt +``` + +
+ Note that the labelmap uses a subset of the complete COCO label set that has only 80 objects. ## CPU Detector (not recommended) @@ -1512,6 +1559,49 @@ COPY --from=build /dfine/output/dfine_${MODEL_SIZE}_obj2coco.onnx /dfine-${MODEL EOF ``` +### Downloading DEIMv2 Model + +[DEIMv2](https://github.com/Intellindust-AI-Lab/DEIMv2) can be exported as ONNX by running the command below. Pretrained weights are available on Hugging Face for two backbone families: + +- **HGNetv2** (smaller/faster): `atto`, `femto`, `pico`, `n` +- **DINOv3** (larger/more accurate): `s`, `m`, `l`, `x` + +Set `BACKBONE` and `MODEL_SIZE` in the first line to match your desired variant. Hugging Face model names use uppercase (e.g. `HGNetv2_N`, `DINOv3_S`), while config files use lowercase (e.g. `hgnetv2_n`, `dinov3_s`). + +```sh +docker build . --rm --build-arg BACKBONE=hgnetv2 --build-arg MODEL_SIZE=n --output . -f- <<'EOF' +FROM python:3.11-slim AS build +RUN apt-get update && apt-get install --no-install-recommends -y git libgl1 libglib2.0-0 && rm -rf /var/lib/apt/lists/* +COPY --from=ghcr.io/astral-sh/uv:0.8.0 /uv /bin/ +WORKDIR /deimv2 +RUN git clone https://github.com/Intellindust-AI-Lab/DEIMv2.git . +# Install CPU-only PyTorch first to avoid pulling CUDA variant +RUN uv pip install --no-cache --system torch torchvision --index-url https://download.pytorch.org/whl/cpu +RUN uv pip install --no-cache --system -r requirements.txt +RUN uv pip install --no-cache --system onnx safetensors huggingface_hub +RUN mkdir -p output +ARG BACKBONE +ARG MODEL_SIZE +# Download from Hugging Face and convert safetensors to pth +RUN python3 -c "\ +from huggingface_hub import hf_hub_download; \ +from safetensors.torch import load_file; \ +import torch; \ +backbone = '${BACKBONE}'.replace('hgnetv2','HGNetv2').replace('dinov3','DINOv3'); \ +size = '${MODEL_SIZE}'.upper(); \ +st = load_file(hf_hub_download('Intellindust/DEIMv2_' + backbone + '_' + size + '_COCO', 'model.safetensors')); \ +torch.save({'model': st}, 'output/deimv2.pth')" +RUN sed -i "s/data = torch.rand(2/data = torch.rand(1/" tools/deployment/export_onnx.py +# HuggingFace safetensors omits frozen constants that the model constructor initializes +RUN sed -i "s/cfg.model.load_state_dict(state)/cfg.model.load_state_dict(state, strict=False)/" tools/deployment/export_onnx.py +RUN python3 tools/deployment/export_onnx.py -c configs/deimv2/deimv2_${BACKBONE}_${MODEL_SIZE}_coco.yml -r output/deimv2.pth +FROM scratch +ARG BACKBONE +ARG MODEL_SIZE +COPY --from=build /deimv2/output/deimv2.onnx /deimv2_${BACKBONE}_${MODEL_SIZE}.onnx +EOF +``` + ### Downloading RF-DETR Model RF-DETR can be exported as ONNX by running the command below. You can copy and paste the whole thing to your terminal and execute, altering `MODEL_SIZE=Nano` in the first line to `Nano`, `Small`, or `Medium` size. From 0371b60c715b8e53deed419f742f69d08ccef491 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Tue, 31 Mar 2026 08:51:55 -0500 Subject: [PATCH 002/134] limit access to admin-only websocket topics for viewer users (#22710) --- frigate/comms/ws.py | 102 ++++++++++++++++++++- frigate/test/test_ws_auth.py | 166 +++++++++++++++++++++++++++++++++++ 2 files changed, 265 insertions(+), 3 deletions(-) create mode 100644 frigate/test/test_ws_auth.py diff --git a/frigate/comms/ws.py b/frigate/comms/ws.py index 6cfe4ecc0b..2f16ab7141 100644 --- a/frigate/comms/ws.py +++ b/frigate/comms/ws.py @@ -17,9 +17,90 @@ from frigate.comms.base_communicator import Communicator from frigate.config import FrigateConfig +from frigate.const import ( + CLEAR_ONGOING_REVIEW_SEGMENTS, + EXPIRE_AUDIO_ACTIVITY, + INSERT_MANY_RECORDINGS, + INSERT_PREVIEW, + NOTIFICATION_TEST, + REQUEST_REGION_GRID, + UPDATE_AUDIO_ACTIVITY, + UPDATE_AUDIO_TRANSCRIPTION_STATE, + UPDATE_BIRDSEYE_LAYOUT, + UPDATE_CAMERA_ACTIVITY, + UPDATE_EMBEDDINGS_REINDEX_PROGRESS, + UPDATE_EVENT_DESCRIPTION, + UPDATE_MODEL_STATE, + UPDATE_REVIEW_DESCRIPTION, + UPSERT_REVIEW_SEGMENT, +) logger = logging.getLogger(__name__) +# Internal IPC topics — NEVER allowed from WebSocket, regardless of role +_WS_BLOCKED_TOPICS = frozenset( + { + INSERT_MANY_RECORDINGS, + INSERT_PREVIEW, + REQUEST_REGION_GRID, + UPSERT_REVIEW_SEGMENT, + CLEAR_ONGOING_REVIEW_SEGMENTS, + UPDATE_CAMERA_ACTIVITY, + UPDATE_AUDIO_ACTIVITY, + EXPIRE_AUDIO_ACTIVITY, + UPDATE_EVENT_DESCRIPTION, + UPDATE_REVIEW_DESCRIPTION, + UPDATE_MODEL_STATE, + UPDATE_EMBEDDINGS_REINDEX_PROGRESS, + UPDATE_BIRDSEYE_LAYOUT, + UPDATE_AUDIO_TRANSCRIPTION_STATE, + NOTIFICATION_TEST, + } +) + +# Read-only topics any authenticated user (including viewer) can send +_WS_VIEWER_TOPICS = frozenset( + { + "onConnect", + "modelState", + "audioTranscriptionState", + "birdseyeLayout", + "embeddingsReindexProgress", + } +) + + +def _check_ws_authorization( + topic: str, + role_header: str | None, + separator: str, +) -> bool: + """Check if a WebSocket message is authorized. + + Args: + topic: The message topic. + role_header: The HTTP_REMOTE_ROLE header value, or None. + separator: The role separator character from proxy config. + + Returns: + True if authorized, False if blocked. + """ + # Block IPC-only topics unconditionally + if topic in _WS_BLOCKED_TOPICS: + return False + + # No role header: default to viewer (fail-closed) + if role_header is None: + return topic in _WS_VIEWER_TOPICS + + # Check if any role is admin + roles = [r.strip() for r in role_header.split(separator)] + if "admin" in roles: + return True + + # Non-admin: only viewer topics allowed + return topic in _WS_VIEWER_TOPICS + class WebSocket(WebSocket_): # type: ignore[misc] def unhandled_error(self, error: Any) -> None: @@ -49,6 +130,7 @@ def start(self) -> None: class _WebSocketHandler(WebSocket): receiver = self._dispatcher + role_separator = self.config.proxy.separator or "," def received_message(self, message: WebSocket.received_message) -> None: # type: ignore[name-defined] try: @@ -63,11 +145,25 @@ def received_message(self, message: WebSocket.received_message) -> None: # type ) return - logger.debug( - f"Publishing mqtt message from websockets at {json_message['topic']}." + topic = json_message["topic"] + + # Authorization check (skip when environ is None — direct internal connection) + role_header = ( + self.environ.get("HTTP_REMOTE_ROLE") if self.environ else None ) + if self.environ is not None and not _check_ws_authorization( + topic, role_header, self.role_separator + ): + logger.warning( + "Blocked unauthorized WebSocket message: topic=%s, role=%s", + topic, + role_header, + ) + return + + logger.debug(f"Publishing mqtt message from websockets at {topic}.") self.receiver( - json_message["topic"], + topic, json_message["payload"], ) diff --git a/frigate/test/test_ws_auth.py b/frigate/test/test_ws_auth.py new file mode 100644 index 0000000000..b762f4384c --- /dev/null +++ b/frigate/test/test_ws_auth.py @@ -0,0 +1,166 @@ +"""Tests for WebSocket authorization checks.""" + +import unittest + +from frigate.comms.ws import _check_ws_authorization +from frigate.const import INSERT_MANY_RECORDINGS, UPDATE_CAMERA_ACTIVITY + + +class TestCheckWsAuthorization(unittest.TestCase): + """Tests for the _check_ws_authorization pure function.""" + + DEFAULT_SEPARATOR = "," + + # --- IPC topic blocking (unconditional, regardless of role) --- + + def test_ipc_topic_blocked_for_admin(self): + self.assertFalse( + _check_ws_authorization( + INSERT_MANY_RECORDINGS, "admin", self.DEFAULT_SEPARATOR + ) + ) + + def test_ipc_topic_blocked_for_viewer(self): + self.assertFalse( + _check_ws_authorization( + UPDATE_CAMERA_ACTIVITY, "viewer", self.DEFAULT_SEPARATOR + ) + ) + + def test_ipc_topic_blocked_when_no_role(self): + self.assertFalse( + _check_ws_authorization( + INSERT_MANY_RECORDINGS, None, self.DEFAULT_SEPARATOR + ) + ) + + # --- Viewer allowed topics --- + + def test_viewer_can_send_on_connect(self): + self.assertTrue( + _check_ws_authorization("onConnect", "viewer", self.DEFAULT_SEPARATOR) + ) + + def test_viewer_can_send_model_state(self): + self.assertTrue( + _check_ws_authorization("modelState", "viewer", self.DEFAULT_SEPARATOR) + ) + + def test_viewer_can_send_audio_transcription_state(self): + self.assertTrue( + _check_ws_authorization( + "audioTranscriptionState", "viewer", self.DEFAULT_SEPARATOR + ) + ) + + def test_viewer_can_send_birdseye_layout(self): + self.assertTrue( + _check_ws_authorization("birdseyeLayout", "viewer", self.DEFAULT_SEPARATOR) + ) + + def test_viewer_can_send_embeddings_reindex_progress(self): + self.assertTrue( + _check_ws_authorization( + "embeddingsReindexProgress", "viewer", self.DEFAULT_SEPARATOR + ) + ) + + # --- Viewer blocked from admin topics --- + + def test_viewer_blocked_from_restart(self): + self.assertFalse( + _check_ws_authorization("restart", "viewer", self.DEFAULT_SEPARATOR) + ) + + def test_viewer_blocked_from_camera_detect_set(self): + self.assertFalse( + _check_ws_authorization( + "front_door/detect/set", "viewer", self.DEFAULT_SEPARATOR + ) + ) + + def test_viewer_blocked_from_camera_ptz(self): + self.assertFalse( + _check_ws_authorization("front_door/ptz", "viewer", self.DEFAULT_SEPARATOR) + ) + + def test_viewer_blocked_from_global_notifications_set(self): + self.assertFalse( + _check_ws_authorization( + "notifications/set", "viewer", self.DEFAULT_SEPARATOR + ) + ) + + def test_viewer_blocked_from_camera_notifications_suspend(self): + self.assertFalse( + _check_ws_authorization( + "front_door/notifications/suspend", "viewer", self.DEFAULT_SEPARATOR + ) + ) + + def test_viewer_blocked_from_arbitrary_unknown_topic(self): + self.assertFalse( + _check_ws_authorization( + "some_random_topic", "viewer", self.DEFAULT_SEPARATOR + ) + ) + + # --- Admin access --- + + def test_admin_can_send_restart(self): + self.assertTrue( + _check_ws_authorization("restart", "admin", self.DEFAULT_SEPARATOR) + ) + + def test_admin_can_send_camera_detect_set(self): + self.assertTrue( + _check_ws_authorization( + "front_door/detect/set", "admin", self.DEFAULT_SEPARATOR + ) + ) + + def test_admin_can_send_camera_ptz(self): + self.assertTrue( + _check_ws_authorization("front_door/ptz", "admin", self.DEFAULT_SEPARATOR) + ) + + # --- Comma-separated roles --- + + def test_comma_separated_admin_viewer_grants_admin(self): + self.assertTrue( + _check_ws_authorization("restart", "admin,viewer", self.DEFAULT_SEPARATOR) + ) + + def test_comma_separated_viewer_admin_grants_admin(self): + self.assertTrue( + _check_ws_authorization("restart", "viewer,admin", self.DEFAULT_SEPARATOR) + ) + + def test_comma_separated_with_spaces(self): + self.assertTrue( + _check_ws_authorization("restart", "viewer, admin", self.DEFAULT_SEPARATOR) + ) + + # --- Custom separator --- + + def test_pipe_separator(self): + self.assertTrue(_check_ws_authorization("restart", "viewer|admin", "|")) + + def test_pipe_separator_no_admin(self): + self.assertFalse(_check_ws_authorization("restart", "viewer|editor", "|")) + + # --- No role header (fail-closed) --- + + def test_no_role_header_blocks_admin_topics(self): + self.assertFalse( + _check_ws_authorization("restart", None, self.DEFAULT_SEPARATOR) + ) + + def test_no_role_header_allows_viewer_topics(self): + self.assertTrue( + _check_ws_authorization("onConnect", None, self.DEFAULT_SEPARATOR) + ) + + +if __name__ == "__main__": + unittest.main() From 1c26bc289e585bc7844aecfd93b609b42132e8d5 Mon Sep 17 00:00:00 2001 From: Abinila Siva <163017635+abinila4@users.noreply.github.com> Date: Tue, 31 Mar 2026 13:22:23 -0400 Subject: [PATCH 003/134] docs: update MemryX docs (#22712) --- docs/docs/configuration/object_detectors.md | 23 ++++++++++++++++++--- docs/docs/frigate/installation.md | 8 ++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/docs/docs/configuration/object_detectors.md b/docs/docs/configuration/object_detectors.md index 4eb7933cdc..5c068e11c3 100644 --- a/docs/docs/configuration/object_detectors.md +++ b/docs/docs/configuration/object_detectors.md @@ -994,7 +994,7 @@ MemryX `.dfp` models are automatically downloaded at runtime, if enabled, to the #### YOLO-NAS -The [YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS.md) model included in this detector is downloaded from the [Models Section](#downloading-yolo-nas-model) and compiled to DFP with [mx_nc](https://developer.memryx.com/tools/neural_compiler.html#usage). +The [YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS.md) model included in this detector is downloaded from the [Models Section](#downloading-yolo-nas-model) and compiled to DFP with [mx_nc](https://developer.memryx.com/2p1/tools/neural_compiler.html#usage). **Note:** The default model for the MemryX detector is YOLO-NAS 320x320. @@ -1028,7 +1028,7 @@ model: #### YOLOv9 -The YOLOv9s model included in this detector is downloaded from [the original GitHub](https://github.com/WongKinYiu/yolov9) like in the [Models Section](#yolov9-1) and compiled to DFP with [mx_nc](https://developer.memryx.com/tools/neural_compiler.html#usage). +The YOLOv9s model included in this detector is downloaded from [the original GitHub](https://github.com/WongKinYiu/yolov9) like in the [Models Section](#yolov9-1) and compiled to DFP with [mx_nc](https://developer.memryx.com/2p1/tools/neural_compiler.html#usage). ##### Configuration @@ -1122,7 +1122,24 @@ To use your own model: 5. Update the `labelmap_path` to match your custom model's labels. -For detailed instructions on compiling models, refer to the [MemryX Compiler](https://developer.memryx.com/tools/neural_compiler.html#usage) docs and [Tutorials](https://developer.memryx.com/tutorials/tutorials.html). +#### Compile the Model + +Custom models must be compiled using **MemryX SDK 2.1**. + +Before compiling your model, install the MemryX Neural Compiler tools from the +[Install Tools](https://developer.memryx.com/2p1/get_started/install_tools.html) page on the **host**. + +Once the SDK 2.1 environment is set up, follow the +[MemryX Compiler](https://developer.memryx.com/2p1/tools/neural_compiler.html#usage) documentation to compile your model. + +Example: + +```bash +mx_nc -m ./yolov9.onnx --dfp_fname ./yolov9.dfp -is "1,3,640,640" -c 4 --autocrop -v +``` +> **Note:** `-is` specifies the input shape. Use your model's input dimensions. + +For detailed instructions on compiling models, refer to the [MemryX Compiler](https://developer.memryx.com/2p1/tools/neural_compiler.html#usage) docs and [Tutorials](https://developer.memryx.com/2p1/tutorials/tutorials.html). ```yaml # The detector automatically selects the default model if nothing is provided in the config. diff --git a/docs/docs/frigate/installation.md b/docs/docs/frigate/installation.md index 8bc5cb6521..53e978c450 100644 --- a/docs/docs/frigate/installation.md +++ b/docs/docs/frigate/installation.md @@ -297,7 +297,7 @@ The MemryX MX3 Accelerator is available in the M.2 2280 form factor (like an NVM #### Installation -To get started with MX3 hardware setup for your system, refer to the [Hardware Setup Guide](https://developer.memryx.com/get_started/hardware_setup.html). +To get started with MX3 hardware setup for your system, refer to the [Hardware Setup Guide](https://developer.memryx.com/2p1/get_started/hardware_setup.html). Then follow these steps for installing the correct driver/runtime configuration: @@ -306,6 +306,12 @@ Then follow these steps for installing the correct driver/runtime configuration: 3. Run the script with `./user_installation.sh` 4. **Restart your computer** to complete driver installation. +:::warning + +For manual setup, use **MemryX SDK 2.1** only. Other SDK versions are not supported for this setup. See the [SDK 2.1 documentation](https://developer.memryx.com/2p1/index.html) + +::: + #### Setup To set up Frigate, follow the default installation instructions, for example: `ghcr.io/blakeblackshear/frigate:stable` From 6b71feffab8d7b4963c1b6b1405d2c70a0f8c693 Mon Sep 17 00:00:00 2001 From: Abinila Siva <163017635+abinila4@users.noreply.github.com> Date: Fri, 3 Apr 2026 13:32:32 -0400 Subject: [PATCH 004/134] Memryx docs update (#22746) * docs: update MemryX documentation section * docs: update MemryX documentation section --- docs/docs/configuration/object_detectors.md | 29 ++++++++++++--------- docs/docs/frigate/installation.md | 2 +- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/docs/configuration/object_detectors.md b/docs/docs/configuration/object_detectors.md index 5c068e11c3..4a0f014d49 100644 --- a/docs/docs/configuration/object_detectors.md +++ b/docs/docs/configuration/object_detectors.md @@ -1110,17 +1110,7 @@ model: #### Using a Custom Model -To use your own model: - -1. Package your compiled model into a `.zip` file. - -2. The `.zip` must contain the compiled `.dfp` file. - -3. Depending on the model, the compiler may also generate a cropped post-processing network. If present, it will be named with the suffix `_post.onnx`. - -4. Bind-mount the `.zip` file into the container and specify its path using `model.path` in your config. - -5. Update the `labelmap_path` to match your custom model's labels. +To use your own custom model, first compile it into a [.dfp](https://developer.memryx.com/2p1/specs/files.html#dataflow-program) file, which is the format used by MemryX. #### Compile the Model @@ -1129,18 +1119,31 @@ Custom models must be compiled using **MemryX SDK 2.1**. Before compiling your model, install the MemryX Neural Compiler tools from the [Install Tools](https://developer.memryx.com/2p1/get_started/install_tools.html) page on the **host**. +> **Note:** It is recommended to compile the model on the host machine, or on another separate machine, rather than inside the Frigate Docker container. Installing the compiler inside Docker may conflict with container packages. It is recommended to create a Python virtual environment and install the compiler there. + Once the SDK 2.1 environment is set up, follow the [MemryX Compiler](https://developer.memryx.com/2p1/tools/neural_compiler.html#usage) documentation to compile your model. Example: ```bash -mx_nc -m ./yolov9.onnx --dfp_fname ./yolov9.dfp -is "1,3,640,640" -c 4 --autocrop -v +mx_nc -m yolonas.onnx -c 4 --autocrop -v --dfp_fname yolonas.dfp ``` -> **Note:** `-is` specifies the input shape. Use your model's input dimensions. For detailed instructions on compiling models, refer to the [MemryX Compiler](https://developer.memryx.com/2p1/tools/neural_compiler.html#usage) docs and [Tutorials](https://developer.memryx.com/2p1/tutorials/tutorials.html). +#### Package the Compiled Model + +1. Package your compiled model into a `.zip` file. + +2. The `.zip` file must contain the compiled `.dfp` file. + +3. Depending on the model, the compiler may also generate a cropped post-processing network. If present, it will be named with the suffix `_post.onnx`. + +4. Bind-mount the `.zip` file into the container and specify its path using `model.path` in your config. + +5. Update `labelmap_path` to match your custom model's labels. + ```yaml # The detector automatically selects the default model if nothing is provided in the config. # diff --git a/docs/docs/frigate/installation.md b/docs/docs/frigate/installation.md index 53e978c450..3722a23ba2 100644 --- a/docs/docs/frigate/installation.md +++ b/docs/docs/frigate/installation.md @@ -297,7 +297,7 @@ The MemryX MX3 Accelerator is available in the M.2 2280 form factor (like an NVM #### Installation -To get started with MX3 hardware setup for your system, refer to the [Hardware Setup Guide](https://developer.memryx.com/2p1/get_started/hardware_setup.html). +To get started with MX3 hardware setup for your system, refer to the [Hardware Setup Guide](https://developer.memryx.com/2p1/get_started/install_hardware.html). Then follow these steps for installing the correct driver/runtime configuration: From 58c93c2e9e3a2f6c80ea6c5108a2d6949a63bd4a Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Mon, 13 Apr 2026 08:07:09 -0500 Subject: [PATCH 005/134] clarify emergency cleanup (#22864) --- docs/docs/configuration/record.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/configuration/record.md b/docs/docs/configuration/record.md index 4d696dad0e..e805cc2d7d 100644 --- a/docs/docs/configuration/record.md +++ b/docs/docs/configuration/record.md @@ -68,7 +68,7 @@ record: ## Will Frigate delete old recordings if my storage runs out? -As of Frigate 0.12 if there is less than an hour left of storage, the oldest 2 hours of recordings will be deleted. +If there is less than an hour left of storage, the oldest hour of recordings will be deleted and a message will be printed in the Frigate logs. This emergency cleanup deletes the oldest recordings first regardless of retention settings to reclaim space as quickly as possible. ## Configuring Recording Retention From 67837f61d06254bb5220d69b0dbdc049aed8d753 Mon Sep 17 00:00:00 2001 From: Mark Date: Tue, 14 Apr 2026 21:00:18 +0200 Subject: [PATCH 006/134] Update restream.md docs and clarify output config (#22860) * Update restream.md Clarified that exec output must be put in curly braces ONLY in case of RTSP, not pipe, as per go2rtc docs. Added additional example use case for exec function (rpi5b cam set-up). * Cleanup Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> --------- Co-authored-by: Nicolas Mowen Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> --- docs/docs/configuration/restream.md | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/docs/docs/configuration/restream.md b/docs/docs/configuration/restream.md index 875d9a2921..5955770a22 100644 --- a/docs/docs/configuration/restream.md +++ b/docs/docs/configuration/restream.md @@ -208,7 +208,7 @@ Enabling arbitrary exec sources allows execution of arbitrary commands through g ## Advanced Restream Configurations -The [exec](https://github.com/AlexxIT/go2rtc/tree/v1.9.10#source-exec) source in go2rtc can be used for custom ffmpeg commands. An example is below: +The [exec](https://github.com/AlexxIT/go2rtc/tree/v1.9.10#source-exec) source in go2rtc can be used for custom ffmpeg commands and other applications. An example is below: :::warning @@ -216,16 +216,11 @@ The `exec:`, `echo:`, and `expr:` sources are disabled by default for security. ::: -:::warning - -The `exec:`, `echo:`, and `expr:` sources are disabled by default for security. You must set `GO2RTC_ALLOW_ARBITRARY_EXEC=true` to use them. See [Security: Restricted Stream Sources](#security-restricted-stream-sources) for more information. - -::: - -NOTE: The output will need to be passed with two curly braces `{{output}}` +NOTE: RTSP output will need to be passed with two curly braces `{{output}}`, whereas pipe output must be passed without curly braces. ```yaml go2rtc: streams: stream1: exec:ffmpeg -hide_banner -re -stream_loop -1 -i /media/BigBuckBunny.mp4 -c copy -rtsp_transport tcp -f rtsp {{output}} + stream2: exec:rpicam-vid -t 0 --libav-format h264 -o - ``` From 81b0d947931f1dd436fdbc00d606cafe41cb6787 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Sat, 18 Apr 2026 17:50:28 -0500 Subject: [PATCH 007/134] fix broken docs links with hash fragments that resolve wrong on reload (#22925) --- docs/docs/configuration/face_recognition.md | 2 +- docs/docs/frigate/installation.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/configuration/face_recognition.md b/docs/docs/configuration/face_recognition.md index c44f76dea2..74fd810710 100644 --- a/docs/docs/configuration/face_recognition.md +++ b/docs/docs/configuration/face_recognition.md @@ -9,7 +9,7 @@ Face recognition identifies known individuals by matching detected faces with pr ### Face Detection -When running a Frigate+ model (or any custom model that natively detects faces) should ensure that `face` is added to the [list of objects to track](../plus/#available-label-types) either globally or for a specific camera. This will allow face detection to run at the same time as object detection and be more efficient. +When running a Frigate+ model (or any custom model that natively detects faces) should ensure that `face` is added to the [list of objects to track](../plus/index.md#available-label-types) either globally or for a specific camera. This will allow face detection to run at the same time as object detection and be more efficient. When running a default COCO model or another model that does not include `face` as a detectable label, face detection will run via CV2 using a lightweight DNN model that runs on the CPU. In this case, you should _not_ define `face` in your list of objects to track. diff --git a/docs/docs/frigate/installation.md b/docs/docs/frigate/installation.md index 3722a23ba2..8839c6bf0f 100644 --- a/docs/docs/frigate/installation.md +++ b/docs/docs/frigate/installation.md @@ -7,7 +7,7 @@ Frigate is a Docker container that can be run on any Docker host including as a :::tip -If you already have Frigate installed as a Home Assistant App, check out the [getting started guide](../guides/getting_started#configuring-frigate) to configure Frigate. +If you already have Frigate installed as a Home Assistant App, check out the [getting started guide](../guides/getting_started.md#configuring-frigate) to configure Frigate. ::: From 2cfb530dbfa90314e67909c0e905a0c3a4b2267d Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Tue, 21 Apr 2026 12:08:10 -0500 Subject: [PATCH 008/134] fix yolonas colab notebook (#22936) --- notebooks/YOLO_NAS_Pretrained_Export.ipynb | 179 +++++++++++---------- 1 file changed, 93 insertions(+), 86 deletions(-) diff --git a/notebooks/YOLO_NAS_Pretrained_Export.ipynb b/notebooks/YOLO_NAS_Pretrained_Export.ipynb index e9ee223149..23c55d1dcb 100644 --- a/notebooks/YOLO_NAS_Pretrained_Export.ipynb +++ b/notebooks/YOLO_NAS_Pretrained_Export.ipynb @@ -1,88 +1,95 @@ { - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "rmuF9iKWTbdk" - }, - "outputs": [], - "source": [ - "! pip install -q git+https://github.com/Deci-AI/super-gradients.git" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "NiRCt917KKcL" - }, - "outputs": [], - "source": [ - "! sed -i 's/sghub.deci.ai/sg-hub-nv.s3.amazonaws.com/' /usr/local/lib/python3.12/dist-packages/super_gradients/training/pretrained_models.py\n", - "! sed -i 's/sghub.deci.ai/sg-hub-nv.s3.amazonaws.com/' /usr/local/lib/python3.12/dist-packages/super_gradients/training/utils/checkpoint_utils.py" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "dTB0jy_NNSFz" - }, - "outputs": [], - "source": [ - "from super_gradients.common.object_names import Models\n", - "from super_gradients.conversion import DetectionOutputFormatMode\n", - "from super_gradients.training import models\n", - "\n", - "model = models.get(Models.YOLO_NAS_S, pretrained_weights=\"coco\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "GymUghyCNXem" - }, - "outputs": [], - "source": [ - "# export the model for compatibility with Frigate\n", - "\n", - "model.export(\"yolo_nas_s.onnx\",\n", - " output_predictions_format=DetectionOutputFormatMode.FLAT_FORMAT,\n", - " max_predictions_per_image=20,\n", - " num_pre_nms_predictions=300,\n", - " confidence_threshold=0.4,\n", - " input_image_shape=(320,320),\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "uBhXV5g4Nh42" - }, - "outputs": [], - "source": [ - "from google.colab import files\n", - "\n", - "files.download('yolo_nas_s.onnx')" - ] - } - ], - "metadata": { - "colab": { - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3", - "name": "python3" - }, - "language_info": { - "name": "python" - } + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "runtime-notice" + }, + "source": [ + "**Before running:** go to **Runtime → Change runtime type → Fallback runtime version: 2025.07** (Python 3.11). The current Colab default (Python 3.12+) is incompatible with `super-gradients`." + ] }, - "nbformat": 4, - "nbformat_minor": 0 -} + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "rmuF9iKWTbdk" + }, + "outputs": [], + "source": [ + "! pip install -q \"jedi>=0.16\"\n", + "! pip install -q git+https://github.com/Deci-AI/super-gradients.git" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "NiRCt917KKcL" + }, + "outputs": [], + "source": "! sed -i 's/sghub\\.deci\\.ai/d2gjn4b69gu75n.cloudfront.net/g; s/sg-hub-nv\\.s3\\.amazonaws\\.com/d2gjn4b69gu75n.cloudfront.net/g' /usr/local/lib/python*/dist-packages/super_gradients/training/pretrained_models.py\n! sed -i 's/sghub\\.deci\\.ai/d2gjn4b69gu75n.cloudfront.net/g; s/sg-hub-nv\\.s3\\.amazonaws\\.com/d2gjn4b69gu75n.cloudfront.net/g' /usr/local/lib/python*/dist-packages/super_gradients/training/utils/checkpoint_utils.py" + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "dTB0jy_NNSFz" + }, + "outputs": [], + "source": [ + "from super_gradients.common.object_names import Models\n", + "from super_gradients.conversion import DetectionOutputFormatMode\n", + "from super_gradients.training import models\n", + "\n", + "model = models.get(Models.YOLO_NAS_S, pretrained_weights=\"coco\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "GymUghyCNXem" + }, + "outputs": [], + "source": [ + "# export the model for compatibility with Frigate\n", + "\n", + "model.export(\"yolo_nas_s.onnx\",\n", + " output_predictions_format=DetectionOutputFormatMode.FLAT_FORMAT,\n", + " max_predictions_per_image=20,\n", + " num_pre_nms_predictions=300,\n", + " confidence_threshold=0.4,\n", + " input_image_shape=(320,320),\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "uBhXV5g4Nh42" + }, + "outputs": [], + "source": [ + "from google.colab import files\n", + "\n", + "files.download('yolo_nas_s.onnx')" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file From 2dcaeb680939576def4582bdc6f75b79cc46ef07 Mon Sep 17 00:00:00 2001 From: Abhilash Kishore Date: Wed, 22 Apr 2026 06:12:14 -0700 Subject: [PATCH 009/134] fix: bump OpenVINO to 2025.4.x to resolve LXC container detector crash (#22859) * fix: bump OpenVINO to 2025.4.x to resolve LXC container crash * fix: replace openvino + onnxruntime with onnxruntime-openvino 1.24.* onnxruntime-openvino 1.24.* bundles OpenVINO 2025.4.1, which fixes a crash in constrained CPU environments (e.g. Proxmox LXC) where lin_system_conf.cpp calls stoi("") on empty strings read from offline CPU sysfs entries. Consolidating to onnxruntime-openvino also ensures the OpenVINO runtime and ONNX Runtime OpenVINO EP are always compatible versions. * revert: restore onnxruntime, keep openvino bump Reverting onnxruntime-openvino consolidation - onnxruntime is used with multiple execution providers (CUDA, TensorRT, MIGraphX, CPU) and cannot be replaced wholesale with the openvino-specific wheel. --- docker/main/requirements-wheels.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/main/requirements-wheels.txt b/docker/main/requirements-wheels.txt index f81fefea47..5956e2a99b 100644 --- a/docker/main/requirements-wheels.txt +++ b/docker/main/requirements-wheels.txt @@ -42,7 +42,7 @@ opencv-python-headless == 4.11.0.* opencv-contrib-python == 4.11.0.* scipy == 1.16.* # OpenVino & ONNX -openvino == 2025.3.* +openvino == 2025.4.* onnxruntime == 1.22.* # Embeddings transformers == 4.45.* From f4ac063b37dd74054fc6d14cda71b8d1c6a85639 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Wed, 22 Apr 2026 08:15:17 -0500 Subject: [PATCH 010/134] Add camera wizard improvements (#22963) * warn in camera wizard when detect stream resolution cannot be determined * add timeout and tcp fallback for rtsp urls only --- frigate/util/services.py | 15 ++++++++-- web/public/locales/en/views/settings.json | 1 + .../settings/wizard/Step4Validation.tsx | 29 ++++++++++++++----- 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/frigate/util/services.py b/frigate/util/services.py index f0bf2de1ed..c20ab27653 100644 --- a/frigate/util/services.py +++ b/frigate/util/services.py @@ -807,10 +807,15 @@ async def get_video_properties( ) -> dict[str, Any]: async def probe_with_ffprobe( url: str, + rtsp_transport: Optional[str] = None, ) -> tuple[bool, int, int, Optional[str], float]: """Fallback using ffprobe: returns (valid, width, height, codec, duration).""" - cmd = [ - ffmpeg.ffprobe_path, + cmd = [ffmpeg.ffprobe_path] + if rtsp_transport: + cmd += ["-rtsp_transport", rtsp_transport] + cmd += [ + "-rw_timeout", + "5000000", "-v", "quiet", "-print_format", @@ -879,6 +884,12 @@ def probe_with_cv2(url: str) -> tuple[bool, int, int, Optional[str], float]: if not has_video or (get_duration and duration < 0): has_video, width, height, fourcc, duration = await probe_with_ffprobe(url) + # last resort for RTSP: try TCP transport, since default UDP may be blocked + if (not has_video or (get_duration and duration < 0)) and url.startswith("rtsp://"): + has_video, width, height, fourcc, duration = await probe_with_ffprobe( + url, rtsp_transport="tcp" + ) + result: dict[str, Any] = {"has_valid_video": has_video} if has_video: result.update({"width": width, "height": height}) diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index a1e14452e5..012023b374 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -415,6 +415,7 @@ "audioCodecGood": "Audio codec is {{codec}}.", "resolutionHigh": "A resolution of {{resolution}} may cause increased resource usage.", "resolutionLow": "A resolution of {{resolution}} may be too low for reliable detection of small objects.", + "resolutionUnknown": "The resolution of this stream could not be probed. This will cause issues on startup. You should manually set the detect resolution in Settings or your config.", "noAudioWarning": "No audio detected for this stream, recordings will not have audio.", "audioCodecRecordError": "The AAC audio codec is required to support audio in recordings.", "audioCodecRequired": "An audio stream is required to support audio detection.", diff --git a/web/src/components/settings/wizard/Step4Validation.tsx b/web/src/components/settings/wizard/Step4Validation.tsx index 8352a1c759..b739fe1ab5 100644 --- a/web/src/components/settings/wizard/Step4Validation.tsx +++ b/web/src/components/settings/wizard/Step4Validation.tsx @@ -607,23 +607,38 @@ function StreamIssues({ } } - if (stream.roles.includes("detect") && stream.resolution) { - const [width, height] = stream.resolution.split("x").map(Number); - if (!isNaN(width) && !isNaN(height) && width > 0 && height > 0) { - const minDimension = Math.min(width, height); - const maxDimension = Math.max(width, height); + if (stream.roles.includes("detect") && stream.testResult) { + const probedResolution = stream.testResult.resolution; + let probedWidth = 0; + let probedHeight = 0; + if (probedResolution) { + const [w, h] = probedResolution.split("x").map(Number); + if (!isNaN(w) && !isNaN(h)) { + probedWidth = w; + probedHeight = h; + } + } + + if (probedWidth <= 0 || probedHeight <= 0) { + result.push({ + type: "error", + message: t("cameraWizard.step4.issues.resolutionUnknown"), + }); + } else { + const minDimension = Math.min(probedWidth, probedHeight); + const maxDimension = Math.max(probedWidth, probedHeight); if (minDimension > 1080) { result.push({ type: "warning", message: t("cameraWizard.step4.issues.resolutionHigh", { - resolution: stream.resolution, + resolution: probedResolution, }), }); } else if (maxDimension < 640) { result.push({ type: "error", message: t("cameraWizard.step4.issues.resolutionLow", { - resolution: stream.resolution, + resolution: probedResolution, }), }); } From 20705a3e97667603ad08857c7df7cbe32769bf99 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Wed, 22 Apr 2026 08:50:37 -0600 Subject: [PATCH 011/134] Update oneVPL (#22966) --- docker/main/install_deps.sh | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/docker/main/install_deps.sh b/docker/main/install_deps.sh index 11812e9edc..ad0fea91a8 100755 --- a/docker/main/install_deps.sh +++ b/docker/main/install_deps.sh @@ -87,43 +87,43 @@ if [[ "${TARGETARCH}" == "amd64" ]]; then # intel packages use zst compression so we need to update dpkg apt-get install -y dpkg - # use intel apt intel packages + # use intel apt repo for libmfx1 (legacy QSV, pre-Gen12) wget -qO - https://repositories.intel.com/gpu/intel-graphics.key | gpg --yes --dearmor --output /usr/share/keyrings/intel-graphics.gpg echo "deb [arch=amd64 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/gpu/ubuntu jammy client" | tee /etc/apt/sources.list.d/intel-gpu-jammy.list apt-get -qq update + # intel-media-va-driver-non-free is built from source in the # intel-media-driver Dockerfile stage for Battlemage (Xe2) support apt-get -qq install --no-install-recommends --no-install-suggests -y \ - libmfx1 libmfxgen1 libvpl2 - - apt-get -qq install -y ocl-icd-libopencl1 - - # install libtbb12 for NPU support - apt-get -qq install -y libtbb12 - + libmfx1 rm -f /usr/share/keyrings/intel-graphics.gpg rm -f /etc/apt/sources.list.d/intel-gpu-jammy.list - # install legacy and standard intel icd and level-zero-gpu - # see https://github.com/intel/compute-runtime/blob/master/LEGACY_PLATFORMS.md for more info - # newer intel packages (gmmlib 22.9+, igc 2.32+) require libstdc++ >= 13.1 and libzstd >= 1.5.5 + # upgrade libva2, oneVPL runtime, and libvpl2 from trixie for Battlemage support echo "deb http://deb.debian.org/debian trixie main" > /etc/apt/sources.list.d/trixie.list apt-get -qq update - apt-get -qq install -y -t trixie libstdc++6 libzstd1 + apt-get -qq install -y -t trixie libva2 libva-drm2 libzstd1 + apt-get -qq install -y -t trixie libmfx-gen1.2 libvpl2 rm -f /etc/apt/sources.list.d/trixie.list apt-get -qq update + apt-get -qq install -y ocl-icd-libopencl1 + # install libtbb12 for NPU support + apt-get -qq install -y libtbb12 + + # install legacy and standard intel compute packages + # see https://github.com/intel/compute-runtime/blob/master/LEGACY_PLATFORMS.md for more info # needed core package wget https://github.com/intel/compute-runtime/releases/download/26.14.37833.4/libigdgmm12_22.9.0_amd64.deb dpkg -i libigdgmm12_22.9.0_amd64.deb rm libigdgmm12_22.9.0_amd64.deb - # legacy packages + # legacy compute-runtime packages wget https://github.com/intel/compute-runtime/releases/download/24.35.30872.36/intel-opencl-icd-legacy1_24.35.30872.36_amd64.deb wget https://github.com/intel/compute-runtime/releases/download/24.35.30872.36/intel-level-zero-gpu-legacy1_1.5.30872.36_amd64.deb wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-opencl_1.0.17537.24_amd64.deb wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.17537.24/intel-igc-core_1.0.17537.24_amd64.deb - # standard packages + # standard compute-runtime packages wget https://github.com/intel/compute-runtime/releases/download/26.14.37833.4/intel-opencl-icd_26.14.37833.4-0_amd64.deb wget https://github.com/intel/compute-runtime/releases/download/26.14.37833.4/libze-intel-gpu1_26.14.37833.4-0_amd64.deb wget https://github.com/intel/intel-graphics-compiler/releases/download/v2.32.7/intel-igc-opencl-2_2.32.7+21184_amd64.deb @@ -137,6 +137,10 @@ if [[ "${TARGETARCH}" == "amd64" ]]; then dpkg -i *.deb rm *.deb apt-get -qq install -f -y + + # Battlemage uses the xe kernel driver, but the VA-API driver is still iHD. + # The oneVPL runtime may look for a driver named after the kernel module. + ln -sf /usr/lib/x86_64-linux-gnu/dri/iHD_drv_video.so /usr/lib/x86_64-linux-gnu/dri/xe_drv_video.so fi if [[ "${TARGETARCH}" == "arm64" ]]; then From ad9092d0da551b9396068556e59cd0486e5720fa Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Wed, 22 Apr 2026 10:19:30 -0500 Subject: [PATCH 012/134] Tweaks (#22965) * use ffmpeg to probe rtsp urls instead of cv2 cv2 is faster (no subprocess launch) and will continue to be used for recording segments * tweak faq * change unsaved color to orange avoids confusion with validation errors (red) * don't use any variant of orange as a profile color avoids confusion with unsaved changes * more unsaved color tweaks --- docs/docs/troubleshooting/faqs.md | 30 +++++++------------ frigate/util/services.py | 18 +++++++---- .../CameraReviewClassification.tsx | 4 +-- .../config-form/sections/BaseSection.tsx | 4 +-- .../theme/fields/KnownPlatesField.tsx | 2 +- .../theme/fields/ReplaceRulesField.tsx | 2 +- .../theme/templates/FieldTemplate.tsx | 6 ++-- .../theme/templates/ObjectFieldTemplate.tsx | 2 +- web/src/pages/Settings.tsx | 4 +-- web/src/utils/profileColors.ts | 20 ++++++------- .../settings/Go2RtcStreamsSettingsView.tsx | 4 ++- web/src/views/settings/SingleSectionPage.tsx | 4 +-- web/tailwind.config.cjs | 1 + 13 files changed, 51 insertions(+), 50 deletions(-) diff --git a/docs/docs/troubleshooting/faqs.md b/docs/docs/troubleshooting/faqs.md index 6cd67ba889..e11ae63159 100644 --- a/docs/docs/troubleshooting/faqs.md +++ b/docs/docs/troubleshooting/faqs.md @@ -111,26 +111,16 @@ TCP ensures that all data packets arrive in the correct order. This is crucial f You can still configure Frigate to use UDP by using ffmpeg input args or the preset `preset-rtsp-udp`. See the [ffmpeg presets](/configuration/ffmpeg_presets) documentation. -### Frigate hangs on startup with a "probing detect stream" message in the logs +### Frigate is slow to start up with a "probing detect stream" message in the logs -On startup, Frigate probes each camera's detect stream with OpenCV to auto-detect its resolution. OpenCV's FFmpeg backend may attempt RTSP over UDP during this probe regardless of the `-rtsp_transport tcp` in your `input_args` or preset. For cameras that do not respond to UDP (common on some Reolink models and others behind firewalls that block UDP), the probe can hang indefinitely and block Frigate from finishing startup, or it can return zeroed-out dimensions that show up as width `0` and height `0` in Camera Probe Info under System Metrics. +When `detect.width` and `detect.height` are not set, Frigate probes each camera's detect stream on startup (and when saving the config) to auto-detect its resolution. For RTSP streams Frigate probes with ffprobe and automatically retries over TCP if UDP doesn't respond, with a 5 second timeout per attempt. A camera that cannot be reached over either transport will add up to ~10 seconds to startup before Frigate falls through with default dimensions, which may show up as width `0` and height `0` in Camera Probe Info under System Metrics. -There are two ways to avoid this: +To skip the probe entirely and make startup instant, set `detect.width` and `detect.height` explicitly in your camera config: -1. Set `detect.width` and `detect.height` explicitly in your camera config. When both are set, Frigate skips the auto-detect probe entirely: - - ```yaml - cameras: - my_camera: - detect: - width: 1280 - height: 720 - ``` - -2. Force OpenCV's FFmpeg backend to use TCP for RTSP by setting the environment variable on your Frigate container: - - ``` - OPENCV_FFMPEG_CAPTURE_OPTIONS=rtsp_transport;tcp - ``` - - This is a process-wide setting and applies to all cameras. If you have any cameras that require `preset-rtsp-udp`, use option 1 instead. +```yaml +cameras: + my_camera: + detect: + width: 1280 + height: 720 +``` diff --git a/frigate/util/services.py b/frigate/util/services.py index c20ab27653..15c439d484 100644 --- a/frigate/util/services.py +++ b/frigate/util/services.py @@ -877,15 +877,23 @@ def probe_with_cv2(url: str) -> tuple[bool, int, int, Optional[str], float]: cap.release() return valid, width, height, fourcc, duration - # try cv2 first - has_video, width, height, fourcc, duration = probe_with_cv2(url) + is_rtsp = url.startswith("rtsp://") - # fallback to ffprobe if needed - if not has_video or (get_duration and duration < 0): + if is_rtsp: + # skip cv2 for RTSP: its FFmpeg backend has a hardcoded ~30s internal + # timeout that cannot be shortened per-call, and ffprobe bounded by + # -rw_timeout handles RTSP probing reliably has_video, width, height, fourcc, duration = await probe_with_ffprobe(url) + else: + # try cv2 first for local files, HTTP, RTMP + has_video, width, height, fourcc, duration = probe_with_cv2(url) + + # fallback to ffprobe if needed + if not has_video or (get_duration and duration < 0): + has_video, width, height, fourcc, duration = await probe_with_ffprobe(url) # last resort for RTSP: try TCP transport, since default UDP may be blocked - if (not has_video or (get_duration and duration < 0)) and url.startswith("rtsp://"): + if (not has_video or (get_duration and duration < 0)) and is_rtsp: has_video, width, height, fourcc, duration = await probe_with_ffprobe( url, rtsp_transport="tcp" ) diff --git a/web/src/components/config-form/sectionExtras/CameraReviewClassification.tsx b/web/src/components/config-form/sectionExtras/CameraReviewClassification.tsx index ffe9b19b2a..86f363aec7 100644 --- a/web/src/components/config-form/sectionExtras/CameraReviewClassification.tsx +++ b/web/src/components/config-form/sectionExtras/CameraReviewClassification.tsx @@ -218,7 +218,7 @@ export default function CameraReviewClassification({