From: Brendan McGrath bmcgrath@codeweavers.com
The total of: 1. unsatisfied sample requests made to MF; plus 2. samples queued (i.e. satisfied requests)
should always equal 4. Thus, for example, if we flush 3 samples, we need to request 3 more.
The stop state appears to flush all samples from sample grabber and all requests outstanding with MF. Hence, starting playback from the stop state always makes four new sample requests. --- dlls/mf/samplegrabber.c | 31 ++++++++++------------ dlls/mf/tests/mf.c | 59 ++++++++++------------------------------- 2 files changed, 28 insertions(+), 62 deletions(-)
diff --git a/dlls/mf/samplegrabber.c b/dlls/mf/samplegrabber.c index 88da642b25e..8899c6d667f 100644 --- a/dlls/mf/samplegrabber.c +++ b/dlls/mf/samplegrabber.c @@ -1157,6 +1157,7 @@ static HRESULT sample_grabber_set_state(struct sample_grabber *grabber, enum sin [SINK_STATE_RUNNING] = MEStreamSinkStarted, }; BOOL do_callback = FALSE; + byte required_requests; HRESULT hr = S_OK; unsigned int i;
@@ -1173,25 +1174,21 @@ static HRESULT sample_grabber_set_state(struct sample_grabber *grabber, enum sin sample_grabber_cancel_timer(grabber); release_samples(grabber); grabber->sample_count = MAX_SAMPLE_QUEUE_LENGTH; + sample_grabber_release_pending_items(grabber); } - - if (state == SINK_STATE_RUNNING && grabber->state != SINK_STATE_RUNNING) + else if (state == SINK_STATE_RUNNING && + (grabber->state != SINK_STATE_RUNNING || offset != PRESENTATION_CURRENT_POSITION)) { - /* Every transition to running state sends a bunch requests to build up initial queue. */ - for (i = 0; i < grabber->sample_count; ++i) - { - if (grabber->state == SINK_STATE_PAUSED && offset == PRESENTATION_CURRENT_POSITION) - { - assert(grabber->samples[i]); - stream_queue_sample(grabber, grabber->samples[i]); - } - else - { - sample_grabber_stream_request_sample(grabber); - } - } - release_samples(grabber); - grabber->sample_count = 0; + required_requests = (grabber->state == SINK_STATE_STOPPED) ? + MAX_SAMPLE_QUEUE_LENGTH : min(grabber->samples_queued, MAX_SAMPLE_QUEUE_LENGTH); + + if (offset != PRESENTATION_CURRENT_POSITION) + sample_grabber_cancel_timer(grabber); + + sample_grabber_release_pending_items(grabber); + + for (i = 0; i < required_requests; i++) + sample_grabber_stream_request_sample(grabber); }
do_callback = state != grabber->state || state != SINK_STATE_PAUSED; diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index ba34ac5c287..0190adfc819 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -4332,7 +4332,6 @@ static HRESULT WINAPI timer_CancelTimer(IMFTimer *iface, IUnknown *cancel_key) { struct presentation_clock* pc = impl_from_IMFTimer(iface);
- todo_wine CHECK_EXPECT(timer_CancelTimer); ok(cancel_key == pc->cancel_key, "Unexpected cancel key %p\n", cancel_key);
@@ -4555,8 +4554,6 @@ static void supply_samples(IMFStreamSink *stream, int num_samples) } }
-static BOOL ignore_clock = FALSE; - #define count_samples_requested(stream) _count_samples_requested(__LINE__, stream) static int _count_samples_requested(int line, IMFStreamSink *stream) { @@ -4581,7 +4578,6 @@ static int _count_samples_requested(int line, IMFStreamSink *stream) } else if (met == MEStreamSinkMarker) { - todo_wine_if(!ignore_clock) CHECK_EXPECT(MEStreamSinkMarker); break; } @@ -4733,18 +4729,15 @@ static void test_sample_grabber_seek(void) SET_EXPECT(timer_CancelTimer); hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 1234); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine CHECK_CALLED(timer_CancelTimer);
samples_requested = count_samples_requested(stream); - todo_wine ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested);
/* test number of new sample requests on seek when in running state and 3 samples have been provided */ sample_pts = 0; SET_EXPECT(timer_SetTimer); supply_samples(stream, 2); - todo_wine CHECK_CALLED(timer_SetTimer); /* this marker gets silently discarded on the next seek */ hr = IMFStreamSink_PlaceMarker(stream, MFSTREAMSINK_MARKER_DEFAULT, NULL, NULL); @@ -4768,18 +4761,15 @@ static void test_sample_grabber_seek(void) SET_EXPECT(timer_CancelTimer); hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 1234); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine CHECK_CALLED(timer_CancelTimer);
samples_requested = count_samples_requested(stream); - todo_wine ok(samples_requested == 2, "Unexpected number of samples requested %d\n", samples_requested);
/* test number of new sample requests after a flush then seek */ sample_pts = expected_pts = 0; SET_EXPECT(timer_SetTimer); supply_samples(stream, 2); - todo_wine CHECK_CALLED(timer_SetTimer);
/* there is no cancel timer, or sample requests during a flush */ @@ -4792,11 +4782,9 @@ static void test_sample_grabber_seek(void) SET_EXPECT(timer_CancelTimer); hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 1234); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine CHECK_CALLED(timer_CancelTimer);
samples_requested = count_samples_requested(stream); - todo_wine ok(samples_requested == 3, "Unexpected number of samples requested %d\n", samples_requested);
/* test number of new sample requests on seek whilst stopped */ @@ -4813,37 +4801,27 @@ static void test_sample_grabber_seek(void) sample_pts = expected_pts = 0; SET_EXPECT(timer_SetTimer); supply_samples(stream, 1); - todo_wine CHECK_CALLED(timer_SetTimer); hr = IMFStreamSink_PlaceMarker(stream, MFSTREAMSINK_MARKER_DEFAULT, NULL, NULL); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); supply_samples(stream, 2);
- todo_wine hr = trigger_timer(mock_clock); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = WaitForSingleObject(grabber_callback_impl->ready_event, 1000); - todo_wine ok(hr == WAIT_OBJECT_0, "Unexpected hr %#lx.\n", hr);
- if (hr == WAIT_OBJECT_0) - { - expected_pts = 41667; - SET_EXPECT(timer_SetTimer); - SetEvent(grabber_callback_impl->done_event); + expected_pts = 41667; + SET_EXPECT(timer_SetTimer); + SetEvent(grabber_callback_impl->done_event);
- SET_EXPECT(MEStreamSinkMarker); - samples_requested = count_samples_requested(stream); - ok(samples_requested == 1, "Unexpected number of samples requested %d\n", samples_requested); - CHECK_CALLED(MEStreamSinkMarker); - CHECK_CALLED(timer_SetTimer); - } - else - { - skip("skipping MEStreamSinkMarker test\n"); - } + SET_EXPECT(MEStreamSinkMarker); + samples_requested = count_samples_requested(stream); + todo_wine + ok(samples_requested == 1, "Unexpected number of samples requested %d\n", samples_requested); + CHECK_CALLED(MEStreamSinkMarker); + CHECK_CALLED(timer_SetTimer);
hr = IMFClockStateSink_OnClockPause(clock_sink, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -4877,21 +4855,18 @@ static void test_sample_grabber_seek(void) expected_pts = sample_pts; SET_EXPECT(timer_SetTimer); supply_samples(stream, 4); - todo_wine CHECK_CALLED(timer_SetTimer);
hr = IMFClockStateSink_OnClockStart(clock_sink, 0, PRESENTATION_CURRENT_POSITION); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
samples_requested = count_samples_requested(stream); - todo_wine ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested);
/* test sample received in the stopped state */ SET_EXPECT(timer_CancelTimer); hr = IMFClockStateSink_OnClockStop(clock_sink, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine CHECK_CALLED(timer_CancelTimer);
supply_samples(stream, 4); @@ -4905,24 +4880,19 @@ static void test_sample_grabber_seek(void) /* check contents of collection */ hr = IMFCollection_GetElementCount(grabber_callback_impl->samples, &count); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(count == ARRAY_SIZE(use_clock_samples), "Unexpected total of samples delivered %ld\n", count);
for (i = 0; i < ARRAY_SIZE(use_clock_samples); i++) { hr = IMFCollection_GetElement(grabber_callback_impl->samples, i, (IUnknown**)&sample); - todo_wine_if(i) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- if (hr == S_OK) - { - hr = IMFSample_GetSampleTime(sample, &pts); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(pts == use_clock_samples[i], "%d: Unexpected pts %I64d, expected %I64d\n", i, pts, use_clock_samples[i]); + hr = IMFSample_GetSampleTime(sample, &pts); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(pts == use_clock_samples[i], "%d: Unexpected pts %I64d, expected %I64d\n", i, pts, use_clock_samples[i]);
- ref = IMFSample_Release(sample); - ok(ref == 1, "Release returned %ld\n", ref); - } + ref = IMFSample_Release(sample); + ok(ref == 1, "Release returned %ld\n", ref); }
/* required for the sink to be fully released */ @@ -4938,7 +4908,6 @@ static void test_sample_grabber_seek(void)
/* test with MF_SAMPLEGRABBERSINK_IGNORE_CLOCK */
- ignore_clock = TRUE; grabber_callback = create_test_grabber_callback(); grabber_callback_impl = impl_from_IMFSampleGrabberSinkCallback(grabber_callback); grabber_callback_impl->do_event = FALSE;