Constrain hi-res phase refine and update beat 14

This commit is contained in:
Melbar
2026-05-08 13:45:09 +02:00
parent 5611902eb5
commit 430a81a988
6 changed files with 30 additions and 5 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+5
View File
@@ -166,6 +166,11 @@ eine kurze Geste erst korrekt erkannt und anschließend in eine spätere
derselben Source-Szene ähnlich gut scoren und die Beat-Dauer abdecken,
bevorzugt der Matcher die frühere Phase.
Der zusätzliche Hi-Res-Phasenrefine bleibt lokal um den bereits validierten
Inpoint und übernimmt nur klare Verbesserungen. Er darf keine ganze lange
Dialogszene nach ähnlichen Layouts durchsuchen, weil sonst dieselbe Location
mit anderer Gestik als falsche Phase gewinnen kann und die Laufzeit explodiert.
## Multi-Shot-Beats
Enthält ein Trailerbeat selbst einen harten Umschnitt, werden Kandidaten an
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 21 KiB

+24 -4
View File
@@ -316,14 +316,31 @@ def _hires_phase_refine(
scan_templates = [(off, feat, sp) for off, feat, sp, _ in ref_templates]
max_ref_offset = max(off for off, _, _ in scan_templates)
# Scan the full scene
# Scan only a local window around the already validated in-point. A full
# scene scan can jump to a different phase of the same shot (same room,
# same actor, different gesture) and it is unnecessarily expensive.
local_window_s = max(0.8, min(2.0, cfg.cv.deep_scan.content_align_window_seconds * 3.0))
scan_start_s = max(scene_start_s, in_point_s - local_window_s)
scan_end_s = min(scene_end_s, in_point_s + local_window_s)
original_scores: list[float] = []
with open_video(cfg.paths.source_movie) as cap:
for off, ref_feat, ref_spatial in scan_templates:
src_frame = grab_frame_at(cap, in_point_s + off)
if src_frame is not None:
original_scores.append(_hires_phase_score(ref_feat, ref_spatial, src_frame))
original_score = -1.0
if original_scores:
original_score = (sum(original_scores) / len(original_scores)) * 0.7 + min(original_scores) * 0.3
# Scan the local neighbourhood.
best_t = in_point_s
best_score = -1.0
best_score = original_score
scan_step_s = max(1.0 / (cfg.export.edl_frame_rate or 24.0), 0.04)
with open_video(cfg.paths.source_movie) as cap:
t = scene_start_s
while t + max_ref_offset <= scene_end_s:
t = scan_start_s
while t + max_ref_offset <= scan_end_s:
scores: list[float] = []
all_ok = True
for off, ref_feat, ref_spatial in scan_templates:
@@ -340,6 +357,9 @@ def _hires_phase_refine(
best_t = t
t = round(t + scan_step_s, 6)
if best_score < original_score + 0.025:
return in_point_s
if best_t != in_point_s:
logger.info(
'Beat %d: hi-res phase refine moved in-point %.3fs -> %.3fs '