Files
LlamaCasty/HANDOFF.md
T
gramps bd396e488c fix(rec): recordings played ~1.4x fast — CFR emission, drop -re
Root cause (measured, not guessed): the take-3 'rebase on overrun' reset
nextTick to wall-now, erasing every missed slot. Pump delivered 215-219/300
per 5s (~43fps) but rawvideo carries no timestamps — ffmpeg muxes by frame
count at -framerate 60, so every recording played fast with honest-looking
stats. A second pacer, ffmpeg -re, throttled the demux separately
('Resumed reading ... after a lag' 0.79s->4.82s).

Fix follows libobs video-io.c (https://github.com/obsproject/obs-studio)
- the video thread never resets its deadline; one frame per interval slot,
a late render repeats content (judder), never skips time:
1. FramePump: count-based emission, while(now>=nextTick){Submit; nextTick+=I}
2. FfmpegArgs: -re removed - the pump is the pacer

Muxed duration is now frame-count/fps == wall time by construction. Covers
game background + webcam (one shared pump). 0 warnings; suite 288/289 -
the one failure (Composite_FullScene_MasterPixels 1380,700) also fails with
this change stashed: pre-existing, untouched, recorded as follow-up.
2026-09-10 08:35:30 -07:00

3.3 KiB

HANDOFF — 2026-09-10

Branch / Commit State

main HEAD = 1a39b09, ahead of origin by 12, working tree carries THE recording-timing fix (uncommitted): count-based CFR emission in FramePump.cs + -re removal in FfmpegArgs.cs, plus this handoff / ai.md slice 9 / MyMistakes.md recipe correction. tools/ holds ticker.c + the built ticker (WSL, unused by git yet).

Recording TIMING — the fix (the "plays too fast" saga)

Root cause, proven by measurement (not guessed): the pump's take-3 "rebase on overrun" reset nextTick to wall-now every time it fell behind, silently erasing missed slots. The pump delivered 215-219/300 per 5s (~43fps) but ffmpeg muxes rawvideo by frame count at -framerate 60 — no per-frame timestamps — so every recording played ~1.4x fast with stats that looked honest (a rebased frame is never "late"). -re on the demux was a second fighting pacer ("Resumed reading … after a lag" grew 0.79s→4.82s).

Fix (the OBS video-io.c shape — one frame per interval slot, deadline never reset):

  1. FramePump.PumpAsync: while (now >= nextTick) { SubmitFrame(frame); nextTick += intervalTicks; } — one submit per crossed slot; a slow render re-writes the current composite (judder, never a skip). nextTick NEVER rebases to wall-now.
  2. FfmpegArgs: -re deleted from the rawvideo input; the pump is the pacer.

Verified: build 0 warnings; full suite 288/289 — the sole failure (Composite_FullScene_MasterPixels line 109, pixel (1380,700) cyan vs magenta) ALSO fails with this fix stashed, i.e. pre-existing and untouched by it. DO NOT fix it here; it is a separate compositor investigation.

NEXT STEP (ONE user run required)

Record ~30s with the WSL ticker visible in the preview (cd tools && ./ticker in a terminal, Ctrl-C to stop), then check:

  • recording duration ≈ wall time (should be, by frame-count construction)
  • %APPDATA%\ytLlive\startup.log "FramePump stats:" shows ≈ n/n per 5s, n = 300 @60fps
  • NO "Resumed reading … after a lag" lines remain
  • ticker advances ~1s per second of footage

Still Open

  • Web overlay: the pre-parse transparency injection (committed 1a39b09) is NOT yet proven — both recorded diagnostic PNGs (%TEMP%\ytLive-web-<id>.png) were 100% alpha=0 AND RGB=0 (an EMPTY capture, not an opaque one). Diagnosis "capture is empty" needs a fresh run; the first-capture dump may be the pre-load about:blank frame. Frozen pending the timing verification.
  • Audio silence: no audio.mp4 measured -91dB (digital silence), 3KiB muxed audio stream — the named-pipe audio delivered ~nothing. Separate from timing; not yet touched.
  • Pre-existing: Composite_FullScene_MasterPixels (see above).

Landmines

  • testhost shares startup.log with app — filter by time when triaging
  • testhost/exe lock DLLs: taskkill /F /IM testhost.exe /IM ytLive.exe before rebuild
  • Build via the Windows dotnet host: /mnt/c/Program Files/dotnet/dotnet.exe build …
  • Kill app before build: /mnt/c/Windows/System32/taskkill.exe /F /IM ytLive.exe
  • No Linux ffmpeg / no sudo on this box — probing uses /mnt/c/Program Files/Krita (x64)/bin/ffmpeg.exe via WSL interop; frames landed in /mnt/c/Users/gramp/AppData/Local/Temp/ylf/
  • tools/ticker: constant ~+982ms offset on the FIRST line is cosmetic (t0 captured a beat late)