Commit Graph
5 Commits
Author SHA1 Message Date
gramps 55ca1029a3 UNIT 0: make a dropped webcam frame measurable, not just inferable
The creator is DHH and lipreads their own recordings, so a webcam that
judders is an accessibility defect, not a polish item. Take
ty-20261005-1001-821-0001.mp4 holds 25.6 distinct webcam images/s against
the camera's 30fps with 281 gaps of 50-100ms - roughly one hitch in five -
in a file that muxes flawlessly. Nothing in the app could see that: rawvideo
carries no per-frame timestamps (ffmpeg stamps by ARRIVAL at the declared
60fps), and the stats line divided every average by the number of frames
SUBMITTED, which deadline padding always fills to the full target. So the
pump reported "300/300 frames, avg render 12.4ms" while producing 60
distinct composites.

Helpers/FrameCadence.cs is one pure counter fed from three points:
MediaCaptureFrameSource logs the device's own SystemRelativeTime stamps
against our arrival times (TryAcquireLatestFrame keeps only the LATEST
frame, so falling behind is silent by design), and FramePump logs the
distinct webcam Epoch values that reached a composite. Read together they
name the culprit - device/USB, our reader, or our compositor - instead of
guessing. Render/resolve/wait now divide by the real render count, and
"frames per 5s from R renders" is the duplicate-on-lag ratio stated
honestly.

An out-of-order timestamp counts as a frame but produces no gap and does not
become the next interval's reference, so one bad stamp cannot invent a
multi-second hitch twice.

Also corrects a stale ai.md line (the "webcam renders at ~18fps" figure
came from a different session and counted every newly rendered layer) and
re-records the background-removal ruling as permanently out. Records the
agreed-but-unbuilt Units 1-2, the no-fallback-camera ruling, and the
SetFormatAsync dead end found by probing the 19041 projection.

Suite 402/402, 0 warnings. The one red, LayerReorderPersistenceTests'
RealMouseDrag, fails identically on a stashed clean tree - it needs an
interactive desktop session this shell lacks.
2026-10-05 11:10:22 -07:00
gramps 7dd140a4c0 Backgrounds: one locked Background per screen + mini rule (TASK 25) 2026-08-23 13:33:33 -07:00
gramps 3f7f1880c5 Webcam resource validation + first-frame proof + CameraConflictProbe: MediaCaptureFrameSource validates post-init (VideoDeviceId match, stream properties, reader StartAsync status), subscribes Failed/CameraStreamStateChanged → SourceFailed; CameraManager.AcquireAsync requires first-frame proof (4s timeout) — silent empty box impossible; MainViewModel surfaces WebcamError chip + MessageBox with suspect-app names; fallback ladder VideoPreview → VideoRecord; 19041 SDK projection gaps documented; AGENTS.md + schema.md + HANDOFF.md memory-map rules added; 81 tests passing, 0 warnings 2026-08-12 07:21:15 -07:00
gramps 4afe11e718 OAuth session persists via DPAPI; sign-in lives in the Start Stream dialog; add xUnit test project (6 passing) 2026-08-06 09:38:35 -07:00
gramps a74162e34e Resolution dropdown, list-focus preservation, unified dark theme, startup logging, and memory map
- Bottom-bar resolution dropdown (1080p60/1080p30/720p60/480p30) with tooltip
  on finding upload bandwidth; disabled while live; no in-app speed test
- FocusPreservingListBox keeps selection/focus coherent when a selected
  scene/source is deleted (skip hidden scenes; leave list when empty)
- Themes/Controls.xaml: single dark-theme dictionary merged once in App.xaml;
  custom ComboBox template fixes SelectionBoxItem rendering; GoLiveWindow and
  ReuseImageDialog consolidated onto shared styles
- AppLog file logger + AppDomain/Dispatcher exception hooks; checkpointed
  MainWindow/VM/dialog constructors (caught MenuItemRole.Separator XAML crash)
- Memory map: schema.md conventions, per-directory index.md, updated ai.md/
  TASKS.md/README.md (OAuth creds real; token persistence still pending)
2026-08-06 08:33:05 -07:00