On Wed Nov 12 17:49:04 2025 +0000, Charlotte Pabst wrote:
Essentially, the windows source seems to buffer one sample ahead (at least that's what it looks like), this means that when thinned is changed to non-thinned the next sample returned is still a keyframe, and after that it starts returning delta frames again. This is tested here: https://gitlab.winehq.org/wine/wine/-/merge_requests/8505/diffs#9c89a7a7f07e... However when non-thinned is changed to thinned, the already buffered sample is discarded until a keyframe is found, hence the line `thin = TRUE` (test here https://gitlab.winehq.org/wine/wine/-/merge_requests/8505/diffs#9c89a7a7f07e...).
This doesn't look right though. I think what happens is that there's more asynchronicity involved. Changing the test a bit, it passes too with something like this:
```C IMFMediaStream_RequestSample(stream, NULL); IMFMediaStream_RequestSample(stream, NULL); IMFMediaStream_RequestSample(stream, NULL); IMFRateControl_SetRate(rate_control, thin, rate); IMFMediaStream_RequestSample(stream, NULL); IMFMediaStream_RequestSample(stream, NULL); IMFMediaStream_RequestSample(stream, NULL);
ok(S_OK == wait_media_event(stream, callback, MEMediaSample, 100, &value), "\n"); ok(S_OK == wait_media_event(stream, callback, MEMediaSample, 100, &value), "\n"); ok(S_OK == wait_media_event(stream, callback, MEMediaSample, 100, &value), "\n"); ok(S_OK == wait_media_event(source, callback, MESourceRateChanged, 100, &value), "\n"); ok(S_OK == wait_media_event(stream, callback, MEMediaSample, 100, &value), "\n"); ok(S_OK == wait_media_event(stream, callback, MEMediaSample, 100, &value), "\n"); ok(S_OK == wait_media_event(stream, callback, MEMediaSample, 100, &value), "\n");
ok(MF_E_NO_EVENTS_AVAILABLE == wait_media_event(stream, callback, MEStreamThinMode, 1000, &value), "\n");
IMFMediaStream_RequestSample(stream, NULL); ok(S_OK == wait_media_event(stream, callback, MEStreamThinMode, 1000, &value), "\n"); ok(S_OK == wait_media_event(stream, callback, MEMediaSample, 100, &value), "\n"); ```
So I think what happens is that `IMFRateControl_SetRate` queues an asynchronous command to update the source rate and thinning mode, which queues the MESourceRateChanged event when it is executed and updates the source thin / rate.
Then, the source thin / rate gets committed to each stream when IMFMediaStream_RequestSample gets called. It could probably be written right away to the stream, but using an asynchronous command too would probably be nicer as it seems to be how everything works and it would make async commands sequence match the event sequence.