Describe the bug
Mp4SinkWriterEncoderTests.Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete intermittently fails in CI when the real Media Foundation H.264 encoder produces no output samples for a single-frame encode.
Seen on main in run 34433989038 (commit 8c62f868), 1 failure out of 5409 tests:
failed Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete (2s 884ms)
Test method WinApp.Cli.Tests.Mp4SinkWriterEncoderTests.Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulComplete threw exception:
System.Runtime.InteropServices.COMException: The operation failed because no samples were processed by the sink. (0xC00D4A44)
at ...IMFSinkWriter.Finalize()
at ...Mp4SinkWriterEncoder.Complete() in src/winapp-CLI/WinApp.UIAutomation.Recording/Mp4SinkWriterEncoder.cs:264
at WinApp.Cli.Tests.Mp4SinkWriterEncoderTests...() in src/winapp-CLI/WinApp.Cli.Tests/Mp4SinkWriterEncoderTests.cs:67
0xC00D4A44 is MF_E_SINK_NO_SAMPLES_PROCESSED.
Cause. The test encodes exactly one 64×64 frame and then immediately calls Complete(), which calls IMFSinkWriter.Finalize():
encoder.WriteFrame(Enumerable.Repeat((byte)0x22, 64 * 64 * 4).ToArray(), 0, 10_000_000);
encoder.Complete();
H.264 MFTs buffer input, so a single frame can legitimately reach Finalize() before any compressed sample has reached the media sink. Whether it passes depends on which H.264 encoder MFT the host resolves and how it buffers, which makes it host-dependent rather than deterministic.
This is a test-robustness problem, not a product bug. In the real recording path, UiRecordingService already wraps encoder.Complete() in a catch (Exception ex) when (IsRecoverableVideoOutputFailure(ex)), and that predicate matches ExternalException, which COMException derives from. So winapp ui record degrades gracefully; only this unit test calls Complete() unguarded.
To Reproduce
Not deterministically reproducible by design — it depends on the H.264 encoder MFT available on the host.
- Run
dotnet test src/winapp-CLI/WinApp.Cli.Tests --filter "ClassName~Mp4SinkWriterEncoderTests" repeatedly, or let CI run main.
- On a host whose H.264 MFT buffers the single input frame past
Finalize(), the test throws COMException (0xC00D4A44).
Observed frequency on CI: 1 occurrence in run 34433989038; the two following main runs (122a6592, 4a2776ca) both passed with the same code, so it is intermittent rather than a regression. Mp4SinkWriterEncoder.cs has not changed since #799 (2026-09-02).
Expected behavior
The test should deterministically exercise encoder argument validation and a successful Complete()/publish, without depending on how a particular host's H.264 MFT buffers a single frame.
Suggested fix: write enough frames that the encoder must emit at least one compressed sample before finalizing (a short run of frames at the configured fps rather than exactly one). That preserves everything the test currently covers — the expected 16384 short-buffer ArgumentException, the idempotent second Complete(), and the atomic publish assertions — while removing the single-frame dependency.
Tolerating MF_E_SINK_NO_SAMPLES_PROCESSED as inconclusive would also make CI green, but it would hollow out the assertion that a completed MP4 is actually published, so it is not preferred.
OS Version and details
windows-latest GitHub-hosted runner (CI); .NET 10 SDK.
Describe the bug
Mp4SinkWriterEncoderTests.Mp4SinkWriterEncoder_RealEncoderCoversValidationAndSuccessfulCompleteintermittently fails in CI when the real Media Foundation H.264 encoder produces no output samples for a single-frame encode.Seen on
mainin run 34433989038 (commit8c62f868), 1 failure out of 5409 tests:0xC00D4A44isMF_E_SINK_NO_SAMPLES_PROCESSED.Cause. The test encodes exactly one 64×64 frame and then immediately calls
Complete(), which callsIMFSinkWriter.Finalize():H.264 MFTs buffer input, so a single frame can legitimately reach
Finalize()before any compressed sample has reached the media sink. Whether it passes depends on which H.264 encoder MFT the host resolves and how it buffers, which makes it host-dependent rather than deterministic.This is a test-robustness problem, not a product bug. In the real recording path,
UiRecordingServicealready wrapsencoder.Complete()in acatch (Exception ex) when (IsRecoverableVideoOutputFailure(ex)), and that predicate matchesExternalException, whichCOMExceptionderives from. Sowinapp ui recorddegrades gracefully; only this unit test callsComplete()unguarded.To Reproduce
Not deterministically reproducible by design — it depends on the H.264 encoder MFT available on the host.
dotnet test src/winapp-CLI/WinApp.Cli.Tests --filter "ClassName~Mp4SinkWriterEncoderTests"repeatedly, or let CI runmain.Finalize(), the test throwsCOMException (0xC00D4A44).Observed frequency on CI: 1 occurrence in run 34433989038; the two following
mainruns (122a6592,4a2776ca) both passed with the same code, so it is intermittent rather than a regression.Mp4SinkWriterEncoder.cshas not changed since #799 (2026-09-02).Expected behavior
The test should deterministically exercise encoder argument validation and a successful
Complete()/publish, without depending on how a particular host's H.264 MFT buffers a single frame.Suggested fix: write enough frames that the encoder must emit at least one compressed sample before finalizing (a short run of frames at the configured fps rather than exactly one). That preserves everything the test currently covers — the
expected 16384short-bufferArgumentException, the idempotent secondComplete(), and the atomic publish assertions — while removing the single-frame dependency.Tolerating
MF_E_SINK_NO_SAMPLES_PROCESSEDas inconclusive would also make CI green, but it would hollow out the assertion that a completed MP4 is actually published, so it is not preferred.OS Version and details
windows-latestGitHub-hosted runner (CI); .NET 10 SDK.