mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 15:46:35 +00:00
fix(kiosk): cleanup cameras removed from layouts
ONVIF: only subscribe to cameras actually in layout cells, not all bundle cameras. Purge warm camera pool entries for cameras removed from the bundle entirely — immediate stop, no cooling period. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7b9ba13e3a
commit
69e6ce1cbc
1 changed files with 46 additions and 6 deletions
|
|
@ -778,13 +778,25 @@ fn render_bundle(
|
|||
// Restart GPIO workers (always — even if list is empty, this drops the old set).
|
||||
gpio::start_workers(&bundle.gpio_bindings, server_url, kiosk_key);
|
||||
|
||||
// (Re)start ONVIF event subscriptions for all ONVIF cameras in the bundle.
|
||||
// Workers self-terminate when a new start() call replaces the generation.
|
||||
// Prefer per-kiosk encryption key over shared cluster key.
|
||||
let decrypt_key = server::load_encrypt_key().or_else(|| server::load_cluster_key());
|
||||
onvif_events::start(&bundle.cameras, decrypt_key.as_deref(), server_url, kiosk_key);
|
||||
|
||||
// Collect camera IDs actually referenced in layout cells.
|
||||
let displays = bundle.normalized_displays();
|
||||
let layout_cam_ids: std::collections::HashSet<u32> = displays
|
||||
.iter()
|
||||
.flat_map(|d| d.layouts.iter())
|
||||
.flat_map(|l| l.cells.iter())
|
||||
.filter_map(|c| c.camera_id)
|
||||
.collect();
|
||||
|
||||
// Only subscribe to ONVIF events for cameras in layouts (not all bundle cameras).
|
||||
let layout_cameras: Vec<_> = bundle.cameras.iter()
|
||||
.filter(|c| layout_cam_ids.contains(&c.id))
|
||||
.cloned()
|
||||
.collect();
|
||||
let decrypt_key = server::load_encrypt_key().or_else(|| server::load_cluster_key());
|
||||
onvif_events::start(&layout_cameras, decrypt_key.as_deref(), server_url, kiosk_key);
|
||||
|
||||
// Purge warm camera pool entries for cameras no longer in the bundle at all.
|
||||
purge_removed_cameras(&bundle.cameras);
|
||||
if displays.is_empty() {
|
||||
warn!("bundle has no displays");
|
||||
show_logo(pairing_window);
|
||||
|
|
@ -1526,6 +1538,34 @@ fn recompute_pool_states(
|
|||
}
|
||||
}
|
||||
|
||||
/// Remove warm camera entries for cameras no longer in the bundle.
|
||||
/// Immediately stops pipelines — no cooling period.
|
||||
fn purge_removed_cameras(bundle_cameras: &[crate::bundle::BundleCamera]) {
|
||||
let valid_ids: std::collections::HashSet<u32> = bundle_cameras.iter().map(|c| c.id).collect();
|
||||
let mut to_remove: Vec<PoolKey> = Vec::new();
|
||||
let mut to_stop: Vec<gstreamer::Pipeline> = Vec::new();
|
||||
|
||||
WARM_CAMERAS.with(|w| {
|
||||
let mut warm = w.borrow_mut();
|
||||
for (key, entry) in warm.iter() {
|
||||
if !valid_ids.contains(&key.0) {
|
||||
to_remove.push(*key);
|
||||
to_stop.push(entry.pipeline.clone());
|
||||
}
|
||||
}
|
||||
for k in &to_remove {
|
||||
warm.remove(k);
|
||||
}
|
||||
});
|
||||
|
||||
for pipe in &to_stop {
|
||||
pipeline::stop(pipe);
|
||||
}
|
||||
if !to_remove.is_empty() {
|
||||
info!("purged {} camera pipelines no longer in bundle", to_remove.len());
|
||||
}
|
||||
}
|
||||
|
||||
/// Drop any Cooling entries whose timer has expired. Called from the
|
||||
/// 1s watchdog tick.
|
||||
fn expire_cooling_pipelines() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue