Add PresenceMode::flood alongside the default track_extent. In flood mode the result sink snaps each presence claim to the shot it sits in, so an actor seen once anywhere in a shot is reported for the whole shot [prev_boundary, next_boundary]. This trades precision for recall against X-Ray's per-scene cast granularity and is a toggleable knob for the optimizer to weigh rather than a default. Boundaries come from the frame stream, now carried through SceneAnnotation (is_cut and is_scene_boundary). Flood prefers TransNetV2 shot boundaries when a scene detector populated them, otherwise falls back to the always-on histogram cuts (camera_position_change_detector); with no boundaries it degrades to track_extent per claim. The is_scene_boundary path stays dormant so an out-of-process scene detector can be revived later without re-wiring. Selected with --presence-mode flood|track_extent (default track_extent), so existing output is byte-for-byte unchanged. The dump_embeddings header note records why TransNetV2 scene detection is not run in that process.
49 lines
2.2 KiB
C++
49 lines
2.2 KiB
C++
#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 <string_view>
|
|
#include <utility>
|
|
|
|
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;
|
|
return sa;
|
|
}
|
|
};
|