Skip to content

ISO writer framesWritten/bytesWritten read 0 mid-recording for async independent writers (status-only) #551

Description

@iamfatness

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    backlogRanked in docs/BACKLOG.md

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions