Josh Hawkins 3a09d01bbe Debug replay resolution (#23287)
* unlink shm frames when camera is removed

* drop stale shm cache refs when cached segment is too small for requested shape

* skip new-object frame cache write when current_frame is unavailable

* add tests

* use setdefault when adding a new camera

Multiple subscribers in the same process each unpickle the ZMQ payload independently and would otherwise write divergent Python objects to the shared cameras dict — leaving long-lived references (e.g. CameraState.camera_config) pointing at a copy that subsequent in-place mutations like apply_section_update can never reach. setdefault collapses everyone onto the first writer's object so attribute mutations propagate to every consumer in this process.

* rebuild ffmpeg commands on detect update

Rebuild the cached ffmpeg cmd so the next process spawn picks up new resolution/fps. Running cameras keep their existing cmd (ffmpeg_cmds is only read at process startup); replay cameras are recycled by CameraMaintainer to pick up the rebuilt cmd

* drop stale shm cache refs when cached segment size doesn't match requested shape

The cached SharedMemoryFrameManager reference can point at a segment whose
size no longer matches the requested shape — the segment was unlinked and
recreated at a different size in a camera add/remove cycle. This catches
both a resolution increase (cached too small) and a decrease (cached too
large, pointing at an orphaned inode whose stale bytes would otherwise be
misinterpreted at the new shape, producing distorted/miscolored YUV frames).

After reopening, if the OS-level segment still doesn't match the requested
shape we're in a transient mid-recreate state — either the maintainer
hasn't allocated the new segment yet (size too small) or we opened a
pre-recycle segment (size too big). Either way, skip the frame and don't
cache the mismatched ref.

* recycle replay camera on detect update

* discard tracked-object state when detect resolution changes mid-session

When detect resolution changes mid-session every tracked object we hold
was localized against the old pixel grid. Their boxes no longer
correspond to anything in the new frame, and the `end` callback that
fires when their IDs disappear from the new detect process's detections
publishes those stale boxes to consumers (LPR, snapshot crop) that slice
the new frame and crash on empty arrays. Drop the tracked-object state
on a shape change so no stale boxes ever cross the CameraState boundary.

Belt-and-suspenders: also drop any incoming batch whose boxes exceed the
current detect resolution. These are in-flight queue entries from the
pre-recycle detect process that beat the new detect process to the
queue; processing them would re-introduce stale-resolution tracked
objects we just dropped above. The per-camera detect process clamps
legitimate boxes to detect.width-1 / detect.height-1, so any coord
beyond that is unambiguously stale.

* rebuild motion and object filter masks on detect resolution change

Apply the detect update first so frame_shape reflects the new resolution
before we rebuild dependents.

Motion's rasterized_mask is sized to frame_shape at construction. When
detect resolution changes we must rebuild RuntimeMotionConfig so the
mask matches the new frame size; otherwise consumers like the LPR
processor and motion detector hit a shape mismatch when they index
frames with the stale mask.

Same story for per-object filter masks — rebuild RuntimeFilterConfig at
the new frame_shape so the merged global+per-object masks they hold
match what they'll be indexed against.

* republish motion and objects on in-memory detect resize

A detect resolution change also invalidates the rasterized masks on
motion and per-object filters. apply_section_update has rebuilt them at
the new frame_shape; publish them too so other processes replace their
old values.

* add test

* frontend

* add refresh topic for camera maintainer recycle action

The maintainer's recycle branch is doing an action (recycle the camera)
in response to a section-level signal. Introduce a
CameraConfigUpdateEnum.refresh case as an explicit action signal — the
maintainer subscribes to refresh instead of detect, parallel with add
and remove. Publishers fire refresh alongside detect when a recycle is
needed; section-level subscribers keep their existing topic.

Since no main-process subscriber listens for detect anymore, the
refresh handler calls recreate_ffmpeg_cmds() explicitly so the shared
CameraConfig's ffmpeg_cmds is rebuilt before the new subprocesses
spawn.

* factor stale-resolution state drop into a CameraState method
2026-05-22 08:39:52 -06:00
2026-02-27 08:55:36 -07:00
2026-05-20 08:36:49 -06:00
2026-03-20 07:24:34 -06:00
2026-05-20 08:36:49 -06:00
2026-05-22 07:52:01 -06:00
2026-05-22 08:39:52 -06:00
2026-05-22 08:39:52 -06:00
2021-02-25 07:01:59 -06:00
2026-05-20 08:36:49 -06:00
2023-07-01 08:18:33 -05:00
2026-05-20 08:36:49 -06:00
2026-05-01 11:25:26 -06:00
2023-01-06 07:03:16 -06:00
2026-01-01 09:56:09 -06:00
2026-02-27 20:02:46 -07:00
2023-11-18 08:04:43 -06:00

logo

Frigate NVR™ - Realtime Object Detection for IP Cameras

License: MIT

Translation status

[English] | 简体中文

A complete and local NVR designed for Home Assistant with AI object detection. Uses OpenCV and Tensorflow to perform realtime object detection locally for IP cameras.

Use of a GPU or AI accelerator is highly recommended. AI accelerators will outperform even the best CPUs with very little overhead. See Frigate's supported object detectors.

  • Tight integration with Home Assistant via a custom component
  • Designed to minimize resource use and maximize performance by only looking for objects when and where it is necessary
  • Leverages multiprocessing heavily with an emphasis on realtime over processing every frame
  • Uses a very low overhead motion detection to determine where to run object detection
  • Object detection with TensorFlow runs in separate processes for maximum FPS
  • Communicates over MQTT for easy integration into other systems
  • Records video with retention settings based on detected objects
  • 24/7 recording
  • Re-streaming via RTSP to reduce the number of connections to your camera
  • WebRTC & MSE support for low-latency live view

Documentation

View the documentation at https://docs.frigate.video

Donations

If you would like to make a donation to support development, please use Github Sponsors.

License

This project is licensed under the MIT License.

  • Code: The source code, configuration files, and documentation in this repository are available under the MIT License. You are free to use, modify, and distribute the code as long as you include the original copyright notice.
  • Trademarks: The "Frigate" name, the "Frigate NVR" brand, and the Frigate logo are trademarks of Frigate, Inc. and are not covered by the MIT License.

Please see our Trademark Policy for details on acceptable use of our brand assets.

Screenshots

Live dashboard

Live dashboard

Streamlined review workflow

Streamlined review workflow

Multi-camera scrubbing

Multi-camera scrubbing

Built-in mask and zone editor

Built-in mask and zone editor

Translations

We use Weblate to support language translations. Contributions are always welcome.

Translation status

Copyright © 2026 Frigate, Inc.

Description
No description provided
Readme MIT 742 MiB
Languages
TypeScript 53.7%
Python 44.9%
Shell 0.4%
CSS 0.4%
Dockerfile 0.2%
Other 0.2%