Adds the codec-agnostic decoder half of the media source. Spawns ffmpeg with -f rawvideo -pix_fmt bgra (reusing the already-shipped ffmpeg via IFfmpegLocator) and drains the raw BGRA stdout pipe into VideoFrames. - Services/RawVideoFrameReader.cs: pure rawvideo BGRA stream -> frames (partial reads kept across Feed; no ffmpeg needed to test) - Services/IDecodeProcess.cs + FfmpegDecodeProcess.cs: binary-stdout subprocess seam, mirror of the encoder's IEncoderProcess - Services/MediaVideoSource.cs: owns the decode, raises FrameReady/Completed - MediaVideoSourceTests: 3 pure reader + 1 integration (fake decode process through the real source loop, frames in order) Reference (external scan): ffmpeg rawvideo pipe decode is the canonical codec-agnostic frame feeds pattern (ffmpeg docs -f rawvideo; how OBS/media pipelines push frames to a compositor). Verified: 4/4 tests, build 0 warnings. Native-FPS pacing + resolver/compositor wiring are the next slice.
2.9 KiB
HANDOFF — Session State
Branch / Commit State
main, working through TASK 21 (media source). Local commits ahead of
origin/main (not yet pushed — user pushes at agreed checkpoints):
f89b9f9— docs: default-device audio assumption (README + startup log)e8ff4df— TASK 22: global audio sync offset (positive delay at the mixer out)670fe3a— TASK 31 (already pushed; listed for context)
Prior milestones pushed through origin/main: TASK 31 (3bf053a..670fe3a), plus
the full refactor series (Commit F 3107f92, Commit G 85893ea).
What's In Flight
TASK 21 (media source) — Increment B (the decoder) implemented, uncommitted-or-pending-commit, awaiting next unit.
Increment A (the Source model: MediaSourceType, SourceType.MediaSource,
MediaPath/MediaIsLooping/MediaVolume/MediaPlaybackState + LayoutStore
persistence) shipped earlier. This session shipped Increment B — the decoder:
New files:
Services/RawVideoFrameReader.cs— pure: parses a rawvideo BGRA stream intoVideoFrames (exactly W×H×4 per frame; partial reads kept acrossFeed).Services/IDecodeProcess.cs+Services/FfmpegDecodeProcess.cs— binary-stdout subprocess seam (mirror ofIEncoderProcess).Services/MediaVideoSource.cs— spawns ffmpeg-f rawvideo -pix_fmt bgra -an, drains the pipe, raisesFrameReadyper frame;Completedon EOF.ytLive.Tests/MediaVideoSourceTests.cs— 3 pure reader tests + 1 integration (fakeIDecodeProcess+IFfmpegLocatorthrough the real source loop, frames in order). Verified: 4/4 pass, build 0 warnings.
Still open (next slices): native-FPS pacing (ffprobe probe), loop control, volume,
the ResolveOutputFrame resolver case + wire into SceneCompositor, the file-picker
UI, and the remaining tests.
Landmine: a stale testhost can lock ytLive.Tests's ytLive.dll and break
dotnet build of the test project — kill it first (cmd.exe /c "taskkill /PID N /F")
on MSB3027. Full-suite vstest hangs headless (RealAppHost/WASAPI) — only filtered
pure tests run in WSL; user verifies the GUI suites on native Windows PowerShell
(which may also hang if WASAPI startup blocks — pre-existing, not this change).
Next
- Commit Increment B (decoder) as one work unit (scope-check + docs already staged in ai.md/TASKS.md/HANDOFF.md).
- Next slice: native-FPS pacing + wire media into
ResolveOutputFrameand the compositor, per TASK 21 steps 6–7. - Await user push checkpoint for the TASK 22/21 commits.
The directive (2026-08-31, user)
Rewrite the project into functional components to aid AI retrieval —
Services/ChatOverlayLayer.cs / SceneGraph.cs style (owner-state extraction),
not line-count chasing. Audio assumption is now an explicit contract (README
"Audio Assumption"): the app uses system defaults, never fights Windows device
locking, and does not debug user audio issues — OS's problem, not ours.