Repository navigation
v2.0.2 — live NVR add, AI defaults, overlay cleanup, memory pooling
v2.0.2 — quality-of-life patch
Field-reported bugs and a memory pass. Drop-in over v2.0.1; configuration is preserved.
Fixes
Adding an NVR no longer requires an app restart
Adding, removing, renaming, or reconfiguring an NVR in Setup → NVR → Apply used to trigger a restart prompt. It now lives-applies:
- Add — wires a new
NvrSession, connects, and binds cameras on the next reconcile step. New cameras come up without dropping the live image on the other NVRs. - Remove — detaches every tile bound to that NVR, cancels active AI-reveals on those tiles, clears the per-NVR banner, disposes the session.
- Connection change (host / port / user / password) — tears down the old session and recreates with the new credentials. Restart of just that NVR's connection, not the whole app.
- Rename — propagates through the next camera reconcile; no session restart.
The only remaining structural changes are grid size and privacy mode flip — both rebuild state-contracts that are unsafe to mutate in-place.
AI default for new cameras is now OFF
Previously a freshly-added camera (or a v1.x upgrade) defaulted to AiEnabled=true, which surprised customers who never asked for AI. Default flipped to false in three places (DTO, JSON deserialization default, runtime VM default). Upgrade matrix:
- v1.x → v2.0.2: AI stays off on every camera (matches v1.x behaviour exactly).
- v2.0.0 / v2.0.1 → v2.0.2: explicit values from JSON are preserved; cameras the operator had AI on for stay on.
- Brand-new camera row: AI off, operator opts in via the AI… dialog.
Disabling AI now clears the existing overlay
When the operator turned AI off in Setup → Apply, the last batch of detections stayed painted on the tile until the next mass-mask or restart. The TileViewModel.AiEnabled setter now clears Detections on the true → false transition. Active AI-reveal windows are also cancelled cleanly (audit reason ai-disabled) before the flip — including in the previously-missed step 4 of ApplyCameraChangesLive (existing-tile, config-only edit).
Performance
Memory pooling on the AI hot path
Three per-frame allocations in the AI pipeline now go through ArrayPool<T>.Shared:
| Allocation | Size | Where |
|---|---|---|
| Per-frame BGRA byte[] | ~8 MB @ 1080p, ~33 MB @ 4K | TileViewModel.OnFrameDecoded |
| YOLO preprocess float[] | ~4.9 MB | InferenceCoordinator.PreprocessForYolo |
| Per-detection protoMask float[] | up to ~100 KB | BuildSegmentationMask |
On a populated grid (4 active AI cameras at the configured cadence) this dropped the steady-state AI-pipeline allocation rate by roughly an order of magnitude. BitmapFrameRef became IDisposable with explicit pool-rented vs caller-owned variants; the InferenceCoordinator disposes frames in all three exit paths (slot-drop, processed, shutdown). No behavioural change.
Installer
InteractiveMask-2.0.2.msi (180.9 MB, signed by IDIS Nederland BV)
- SHA-256:
E29B8EA1FEB13F021E2BCABA9987FAE73A8B277568329AE365D5EC645AD13881 - Certificate: CN=IDIS Nederland BV, valid until 4 April 2027
- Upgrade: double-click on a host running v2.0.0 / v2.0.1 / v1.x — old version replaced in-place, configuration preserved.
Unattended deployment
msiexec /i InteractiveMask-2.0.2.msi /qn INTERACTIVEMASK_LANGUAGE=en(Replace en with nl, de, fr, or es.)
Full v2.0 feature list
See v2.0.0 release notes for the headline AI-masking features. Patch history: v2.0.1 (fresh-install crash + mass-mask perf + diagnostic bootstrap log).