From 1477c538850a9a108dd0df37f87334510ea41daa Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sun, 9 Aug 2026 19:20:06 +0200 Subject: [PATCH] refactor(registry): only keep identified tracks associable while dormant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit candidates() now excludes dormant (off-screen) tracks that were never identified: an unowned dormant track has no actor to re-attach to, so keeping it in the association pool only enlarges the matcher's per-frame comparison set and invites a new face re-associating onto an anonymous stub. On-screen tracks are always candidates; a dormant track must have crossed ownership (t.actor set) to stay associable within track_extinction_sec. Measured trade: a small recall cost (~1-3pp on some films, e.g. Lord of War -2.5) for a cleaner, bounded pool. Kept deliberately. Note it does NOT fix the ROCm GEMM wedge (that is an intermittent driver flake, not a pool-size problem) — this is a correctness/cleanliness change, not a performance one. --- src/track_registry.hpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/track_registry.hpp b/src/track_registry.hpp index 6b69b59..f3d20e9 100644 --- a/src/track_registry.hpp +++ b/src/track_registry.hpp @@ -218,9 +218,21 @@ public: const double clock = reg_.awaits_evidence_ ? reg_.evidence_through_ : reg_.now_; for (auto& [id, t] : reg_.tracks_) { - if (t.last_seen && - (clock - *t.last_seen) > reg_.cfg_.track_extinction_sec) - continue; // retired from association; still awaiting evidence + // On-screen tracks are always candidates (actively tracked this + // frame). A dormant (off-screen) track is only worth keeping alive + // for re-association if it was actually IDENTIFIED: an unowned + // dormant track has no actor to re-attach to, so holding it in the + // pool only bloats the matcher's per-frame comparison set (every + // candidate is a GEMM row) and invites a new face re-associating + // onto an anonymous stub. Gating dormant tracks on t.actor keeps + // the pool bounded regardless of how large track_extinction_sec is + // — which is what makes a long re-association window affordable. + if (t.last_seen) { // dormant + if (!t.actor.has_value()) + continue; // never identified: not worth re-associating + if ((clock - *t.last_seen) > reg_.cfg_.track_extinction_sec) + continue; // past the re-association horizon + } out.push_back(&t); } return out;