Skip to content

Fix flaky real MP4 encoder tests (MF_E_SINK_NO_SAMPLES_PROCESSED) - #966

Merged
Nikola Metulev (nmetulev) merged 6 commits into
mainfrom
nmetulev-fix-flaky-mp4-encoder-test
Oct 6, 2026
Merged

Nikola Metulev (nmetulev) merged 6 commits into
mainfrom
nmetulev-fix-flaky-mp4-encoder-test

Conversation

@nmetulev

Copy link
Copy Markdown
Member

Description

Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete intermittently failed in CI with COMException 0xC00D4A44 (MF_E_SINK_NO_SAMPLES_PROCESSED) from IMFSinkWriter.Finalize().

The test wrote exactly one frame to a real Media Foundation H.264 encoder and then called Complete(). The encoder holds a lookahead of input frames before it emits anything, so a single frame reaches Finalize() with nothing delivered to the MP4 sink, and the test depended entirely on the encoder's end-of-stream drain producing a sample. On some hosts it doesn't.

Measured locally with IMFSinkWriter.GetStatistics (Microsoft software H.264 encoder, 64x64 @ 1 fps, stats read just before Finalize()):

Frames written Samples processed by the sink before Finalize()
1–12 0
20 8
30 18

The tests now write 30 frames (well past the 12-frame lookahead) through a small shared helper, so the encoder emits samples during normal input processing and Finalize() no longer depends on the drain. Everything the test covered is preserved: the short-buffer ArgumentException, idempotent second Complete(), and the published-file assertions.

The same one-frame-then-Complete() pattern was in two UiCommandTests encoder tests (MoveFails_TempFileCleanedUp, NoClobberRacePreservesLateDestinationAndCleansTemp). They expect an IOException thrown after Finalize() succeeds, so they had the same latent flake and use the same helper.

No product behavior changes. UiRecordingService already treats a failing encoder.Complete() as a recoverable video-output failure. The only production-file edits are two doc-comment wording updates that referred to "one-frame" coverage.

I chose this over treating 0xC00D4A44 as inconclusive, because that would hollow out the assertion that a completed MP4 is published. I also didn't add a product-side statistics accessor to poll the sink, since it would add surface only for tests.

Related Issue

Fixes #834

Type of Change

  • 🧪 Test update

Checklist

  • Tested locally on Windows

Additional Notes

Limitation: I couldn't reproduce the original failure locally. 1,000 single-frame encodes at 32-way parallelism with every core saturated all passed on an ARM64 host, while CI is x64. The fix targets the mechanism the measurements show (no samples reach the sink before Finalize() for one frame) rather than a reproduced failure.

Validation: 20 consecutive runs of dotnet run --project src/winapp-CLI/WinApp.Cli.Tests/WinApp.Cli.Tests.csproj -c Debug --no-build -- --filter "FullyQualifiedName~Mp4SinkWriterEncoder" passed 7/7 every run, with 0 skipped or inconclusive.

The real-encoder tests wrote exactly one frame before Complete(). The
H.264 encoder MFT holds a multi-frame lookahead (12 frames measured with
the Microsoft software encoder), so a single frame reaches
IMFSinkWriter.Finalize() with nothing delivered to the MP4 sink and
relies entirely on the end-of-stream drain. On some hosts that yields no
sample and Finalize() throws MF_E_SINK_NO_SAMPLES_PROCESSED.

Write 30 frames, well past the lookahead, so the encoder emits samples
during normal input processing. Applied to the three tests that encode a
single frame and then complete.

Fixes #834

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 1, 2026 22:39
@nmetulev Nikola Metulev (nmetulev) added the agent-preparing Agent is addressing feedback or completing required validation and CI label Oct 1, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The targeted build succeeded and all seven MP4 encoder tests passed with no unresolved findings.

Review effort: Balanced
Findings: None

What changed in this PR

Improves Media Foundation encoder test reliability without changing product behavior.

Changes:

  • Writes 30 frames before finalization to exceed encoder lookahead.
  • Reuses the helper in three real-encoder tests.
  • Updates outdated one-frame coverage comments.
File Description
Mp4SinkWriterEncoder.cs Updates coverage comments.
UiCommandTests.Record.Encoder.cs Uses robust multi-frame encoding setup.
Mp4SinkWriterEncoderTests.cs Adds the shared frame-writing helper.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Build Metrics Report

Validation passed. All required build and validation jobs succeeded.

Binary Sizes

Artifact Baseline Current Delta
CLI (ARM64) 57.41 MB 57.41 MB ✅ 0.0 KB (0.00%)
CLI (x64) 57.45 MB 57.45 MB ✅ 0.0 KB (0.00%)
MSIX (ARM64) 23.85 MB 23.85 MB 📉 -0.1 KB (-0.00%)
MSIX (x64) 25.32 MB 25.32 MB 📉 -0.3 KB (-0.00%)
NPM Package 49.74 MB 49.74 MB 📉 -0.5 KB (-0.00%)
NuGet Package 49.84 MB 49.84 MB 📉 -0.2 KB (-0.00%)

.NET Test Results (TRX reports)

Other suites are reflected in the overall validation status above.

✅ 8046 passed, 37 skipped out of 8083 tests in 1131.0s (-225.0s vs. baseline)

Test Coverage

✅ 86.4% line coverage, 81% branch coverage · ✅ no change vs. baseline

CLI Startup Time

52ms median (x64, winapp --version) · ✅ -10ms vs. baseline

Try This Build

Installs the MSIX for your architecture, replacing any previously installed build. Needs the GitHub CLI — the command offers to install it and sign you in if it is missing.

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/microsoft/winappCli/main/scripts/winapp-pr.ps1))) 966
Switching between builds often?

Put the tool on your PATH once:

& ([scriptblock]::Create((irm https://raw.githubusercontent.com/microsoft/winappCli/main/scripts/winapp-pr.ps1))) -AddToPath

Then this build is just:

winapp-pr 966

Run winapp-pr with no arguments to pick from a list of open PRs.


Updated 2026-10-06 03:28:48 UTC · commit 7c6b25d · workflow run

@nmetulev Nikola Metulev (nmetulev) added ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge and removed agent-preparing Agent is addressing feedback or completing required validation and CI labels Oct 1, 2026

@zateutsch Zach Teutsch (zateutsch) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI-generated review (winappcli pr-review skill) — verify before acting.

The core fix is right: writing past the encoder lookahead so Finalize() doesn't depend on the end-of-stream drain is the correct fix for #834, and the GetStatistics measurements justify 30 frames. Build is clean.

One change requested: the longer write loop widens a pre-existing cross-test race on the process-wide s_testPublishAtomic seam in MoveFails_TempFileCleanedUp (inline note). It's a one-line move, and it keeps this de-flaking PR from introducing a new flake vector. Everything else looks good to merge once that's addressed.

Comment thread src/winapp-CLI/WinApp.Cli.Tests/UiCommandTests.Record.Encoder.cs Outdated
s_testPublishAtomic is process-wide, and real-encoder tests in other
classes can call Complete() in parallel. Setting it after the 30-frame
write loop keeps the throwing seam active only for the Complete() call
that needs it.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@nmetulev Nikola Metulev (nmetulev) added agent-preparing Agent is addressing feedback or completing required validation and CI and removed ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge labels Oct 2, 2026
@nmetulev Nikola Metulev (nmetulev) added ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge and removed agent-preparing Agent is addressing feedback or completing required validation and CI labels Oct 3, 2026
@nmetulev Nikola Metulev (nmetulev) added agent-preparing Agent is addressing feedback or completing required validation and CI and removed ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge labels Oct 6, 2026
@nmetulev Nikola Metulev (nmetulev) added ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge agent-preparing Agent is addressing feedback or completing required validation and CI and removed agent-preparing Agent is addressing feedback or completing required validation and CI ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge labels Oct 6, 2026
@nmetulev Nikola Metulev (nmetulev) added ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge and removed agent-preparing Agent is addressing feedback or completing required validation and CI labels Oct 6, 2026
@nmetulev
Nikola Metulev (nmetulev) merged commit 3f1e6b7 into main Oct 6, 2026
42 checks passed
@nmetulev
Nikola Metulev (nmetulev) deleted the nmetulev-fix-flaky-mp4-encoder-test branch October 6, 2026 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review Agent work and technical checks complete; awaiting review or re-review, not approval or merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flaky test: Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete intermittently fails with MF_E_SINK_NO_SAMPLES_PROCESSED

3 participants