Symptom
During a live 6-ISO recording (2026-09-18, beta-2026-09-18-c80ee51), the snapshot recording.streams[].framesWritten and .bytesWritten read 0 for every ISO writer for the whole run, while:
- the files were recording correctly on disk (96–140 MB and growing, finalized to h264+aac, full 1463 s), and
encoderEvidence.isoVideoBySource[id].written read the true counts (~1.7k–2.5k/source live, 301,204 total, 0 dropped).
Not data loss — a status-reporting gap. Cosmetic to the operator, but it makes the per-writer health fields (framesWritten, videoWorkUs ÷ framesWritten) useless for diagnosing a slow ISO writer live, which is exactly what a support bundle reads.
Cause
MediaFoundationEncoderSink::refreshIsoStreams() seeds status from iso.snapshot and then overlays some fields from the async worker's evidence:
status = iso.snapshot; // framesWritten / bytesWritten come from here
if (iso.worker) {
const auto evidence = iso.worker->evidence();
status.droppedVideoFrames = evidence.droppedVideo; // dropped/queued/workUs overlaid
status.videoWorkUs = evidence.videoWorkUs;
... // but NOT framesWritten / bytesWritten
}
The synchronous writer path updates iso.snapshot.framesWritten as it muxes (so the EncoderRecordingSession tests, which use that path, pass). The async independent writers (independentIsoWriters_, the live app's path) mux on their own thread and only advance their Evidence (acceptedVideo), never iso.snapshot — so status.framesWritten stays 0.
Fix direction
In the iso.worker branch of refreshIsoStreams, set the written count from evidence, e.g. status.framesWritten = evidence.acceptedVideo (minus dropped if the semantics call for muxed-only). For bytesWritten mid-recording: either derive from the on-disk file size (fragmented MP4 grows continuously) or leave 0 until finalize and document it. Add an async-path test to EncoderRecordingSessionTest (drive an independent writer, assert framesWritten advances mid-recording) — the current tests only cover the synchronous path, which is why this slipped through. Keep it status-only; do not touch the mux path.
Evidence
Live snapshot 2026-09-18: isoVideoBySource written 1685/1854/2481/1869/1873/1865, 0 dropped; recording.streams[].framesWritten all 0; files 97–140 MB. Found while validating #550 under real load.
Symptom
During a live 6-ISO recording (2026-09-18, beta-2026-09-18-c80ee51), the snapshot
recording.streams[].framesWrittenand.bytesWrittenread 0 for every ISO writer for the whole run, while:encoderEvidence.isoVideoBySource[id].writtenread the true counts (~1.7k–2.5k/source live, 301,204 total, 0 dropped).Not data loss — a status-reporting gap. Cosmetic to the operator, but it makes the per-writer health fields (
framesWritten,videoWorkUs ÷ framesWritten) useless for diagnosing a slow ISO writer live, which is exactly what a support bundle reads.Cause
MediaFoundationEncoderSink::refreshIsoStreams()seedsstatusfromiso.snapshotand then overlays some fields from the async worker's evidence:The synchronous writer path updates
iso.snapshot.framesWrittenas it muxes (so theEncoderRecordingSessiontests, which use that path, pass). The async independent writers (independentIsoWriters_, the live app's path) mux on their own thread and only advance theirEvidence(acceptedVideo), neveriso.snapshot— sostatus.framesWrittenstays 0.Fix direction
In the
iso.workerbranch ofrefreshIsoStreams, set the written count from evidence, e.g.status.framesWritten = evidence.acceptedVideo(minus dropped if the semantics call for muxed-only). ForbytesWrittenmid-recording: either derive from the on-disk file size (fragmented MP4 grows continuously) or leave 0 until finalize and document it. Add an async-path test toEncoderRecordingSessionTest(drive an independent writer, assertframesWrittenadvances mid-recording) — the current tests only cover the synchronous path, which is why this slipped through. Keep it status-only; do not touch the mux path.Evidence
Live snapshot 2026-09-18:
isoVideoBySourcewritten 1685/1854/2481/1869/1873/1865, 0 dropped;recording.streams[].framesWrittenall 0; files 97–140 MB. Found while validating #550 under real load.