Video and telemetry synchronisation
Source engine/src/dtta/engine/normalize/session.py (clocks), ui/src/app/sync.ts (mapping),
docs/proofs/phase-09/sync.md (measurements).
Three clocks
| clock | origin | used for |
|---|---|---|
| video clock | presentation time of the video track, 0 at the first frame of each chapter file | seeking and scrubbing the player |
| camera clock (STMP) | microseconds since camera boot, stamped on every telemetry packet, continuous across chapter files | master timeline of all telemetry |
| GPS clock | receiver UTC (per sample on HERO11, per packet on HERO9) | absolute time, cross-camera alignment |
The session clock is with the first accelerometer packet of the first chapter. Chapter starts at (its first packet on the session clock). Chapter continuity was verified on the real files: the last STMP of one chapter and the first of the next differ by exactly one packet interval.
The mapping
is the per-chapter, per-camera offset between the video's frame clock and the telemetry
packet clock. Its default is 0 (both clocks come from the same camera and the first telemetry packet
is at video time 0). The interface derives everything from one master value: the cursor's track
position s on the followed lap gives the session time through that lap's ; the session time
gives the video time; and while the video plays, its current time gives the session time and therefore
the position on every chart and the map.
Measured offsets (Phase 9)
Visible bumps in the video (frame-energy peaks) were matched against peaks of the vertical accelerometer,
after shifting GPS-derived channels by the measured gps_lag_s:
| camera | GPS lag | median | spread of the bump checks | gate crossings |
|---|---|---|---|---|
| HERO11 Black (I-35 driver) | −0.15 s | +0.051 s | 0.33 s | visually consistent with the computed crossing time |
| HERO9 Black (Hamilton driver) | −0.40 s | +0.85 s | 1.3 s | visually consistent |
The HERO9 spread reflects the camera's GPS time buffering (GoPro documents that GPS5 samples are
delayed relative to the live GPS time). Frames at the computed gate-crossing times are in
docs/proofs/phase-09/frames/.
Until a per-camera value is adopted, the interface uses and labels the sync "unverified"; the Engineer view shows the value in use. A racer should expect the video to be within a few tenths of a second of the telemetry on HERO11 and within about a second on HERO9.
Frame stepping
Single-frame steps use the chapter's real frame rate from the container (29.97 fps for the GoPro files inspected). The player only seeks when the target differs from the current time by more than 60 ms, so a scrubbing chart does not fight the decoder.
Limitations
- is not measured automatically per session; it is a per-camera calibration.
- Motion onset (first frame with visible motion vs first GPS speed > 1 m/s) only bounds the offset because GPS speed lags true motion.
- Proxy video generated for playback keeps the source presentation timestamps, so the mapping is the same for the original and the proxy (verified by frame counts and durations after generation).