#pragma once /// TRACES: AR-012, AR-013 | SR-002 /// /// FrameAnnotationFunc — project a matched frame into a per-frame annotation. /// /// Stateless, and that is the entire point of it. /// /// It replaces `SceneTrackerFunc`, which kept an extinction timer per actor and /// reported an actor as visible for `extinction_sec` (57.4 s) after their last /// detection. docs/SPEC.md specified that node's deletion -- "anneal_sec and /// extinction_sec are deleted, not re-tuned ... SceneTrackerFunc goes with /// them", with a removal list ending "grep for both names and expect no /// survivors" -- and docs/requirements.md recorded both constants as Withdrawn, /// deleted "rather than retained at zero", on the grounds that a field naming a /// mechanism the pipeline no longer has is actively misleading. None of that /// removal had happened. The node was still wired into both shipped pipelines /// and still printed its timeout at every startup. /// /// **Presence is not this node's business.** AR-012 moved it to TrackRegistry, /// where a window is `[first_seen, last_seen]` of a track an actor owns, and /// AR-013 ends that window at the last sighting rather than after it. A /// keep-alive here answered the same question a second time and answered it /// worse: it re-opened the trailing cool-down the registry exists to refuse. /// /// What a consumer sees change: `--verbosity standard`'s `frames[].identified` /// used to list every actor still inside the keep-alive, including ones absent /// from the frame. It now lists what was actually matched in that frame. The /// minimal and xray outputs are unaffected -- they were already built from /// registry claims and never consulted this node. #include "types.hpp" #include #include struct FrameAnnotationFunc { static constexpr std::string_view label() { return "frame_annotation"; } SceneAnnotation operator()(MatchedSceneFrame mf) { if (mf.source.eof) return {0.0, {}, /*eof=*/true}; SceneAnnotation sa; sa.timestamp_sec = mf.source.timestamp_sec; sa.visible_actors = std::move(mf.actors); sa.is_cut = mf.source.is_cut; sa.is_scene_boundary = mf.source.is_scene_boundary; sa.rgb_hist = std::move(mf.source.rgb_hist); return sa; } };