This fixes seeking within sample grabber by matching Windows functionality.
From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/mf/tests/mf.c | 191 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 0c0590ed195..56cef1c9b10 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -4189,6 +4189,196 @@ static void test_sample_grabber(void) IMFSampleGrabberSinkCallback_Release(grabber_callback); }
+static void supply_samples(IMFStreamSink *stream, int num_samples) +{ + IMFMediaBuffer *buffer; + IMFSample *sample; + HRESULT hr; + int i; + + for (i = 0; i < num_samples; i++) + { + hr = MFCreateMemoryBuffer(360, &buffer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateSample(&sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFSample_AddBuffer(sample, buffer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFSample_SetSampleTime(sample, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFSample_SetSampleDuration(sample, 41667); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFStreamSink_ProcessSample(stream, sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFMediaBuffer_Release(buffer); + IMFSample_Release(sample); + } +} + +static int count_samples_requested(IMFStreamSink *stream) +{ + int samples_requested; + IMFMediaEvent *event; + MediaEventType met; + HRESULT hr; + + samples_requested = 0; + while (IMFStreamSink_GetEvent(stream, 0, &event) == S_OK) + { + hr = IMFMediaEvent_GetType(event, &met); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFMediaEvent_Release(event); + if (met == MEStreamSinkRequestSample) + samples_requested++; + else if (met == MEStreamSinkStarted) + break; + } + + return samples_requested; +} + +static void test_sample_grabber_seek(void) +{ + IMFSampleGrabberSinkCallback *grabber_callback = create_test_grabber_callback(); + IMFPresentationTimeSource *time_source; + IMFPresentationClock *clock; + IMFMediaType *media_type; + IMFStreamSink *stream; + IMFActivate *activate; + int samples_requested; + IMFMediaSink *sink; + HRESULT hr; + ULONG ref; + + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr); + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr); + + EXPECT_REF(media_type, 1); + hr = MFCreateSampleGrabberSinkActivate(media_type, grabber_callback, &activate); + ok(hr == S_OK, "Failed to create grabber activate, hr %#lx.\n", hr); + EXPECT_REF(media_type, 2); + + ref = IMFMediaType_Release(media_type); + ok(ref == 1, "Release returned %ld\n", ref); + + hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink); + ok(hr == S_OK, "Failed to activate object, hr %#lx.\n", hr); + + ref = IMFActivate_Release(activate); + ok(ref == 0, "Release returned %ld\n", ref); + + hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream); + ok(hr == S_OK, "Failed to get sink stream, hr %#lx.\n", hr); + + + /* Set clock. */ + hr = MFCreatePresentationClock(&clock); + ok(hr == S_OK, "Failed to create clock object, hr %#lx.\n", hr); + + hr = IMFMediaSink_SetPresentationClock(sink, clock); + ok(hr == S_OK, "Failed to set presentation clock, hr %#lx.\n", hr); + + hr = MFCreateSystemTimeSource(&time_source); + ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr); + + hr = IMFPresentationClock_SetTimeSource(clock, time_source); + ok(hr == S_OK, "Failed to set time source, hr %#lx.\n", hr); + IMFPresentationTimeSource_Release(time_source); + + + /* test number of new sample requests on clock start */ + hr = IMFPresentationClock_Start(clock, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + 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 4 samples have been provided */ + supply_samples(stream, 4); + hr = IMFPresentationClock_Start(clock, 1234); + 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 number of new sample requests on seek when in running state and 3 samples have been provided */ + supply_samples(stream, 3); + hr = IMFPresentationClock_Start(clock, 1234); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + 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 */ + hr = IMFPresentationClock_Stop(clock); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFPresentationClock_Start(clock, 0); + 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 number of new sample requests on seek whilst paused and 3 samples provided */ + supply_samples(stream, 3); + + hr = IMFPresentationClock_Pause(clock); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFPresentationClock_Start(clock, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + 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 paused and no samples provided */ + hr = IMFPresentationClock_Pause(clock); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFPresentationClock_Start(clock, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + todo_wine + ok(samples_requested == 0, "Unexpected number of samples requested %d\n", samples_requested); + + ref = IMFPresentationClock_Release(clock); + ok(ref == 2, "Release returned %ld\n", ref); + + /* required for the sink to be fully released */ + hr = IMFMediaSink_Shutdown(sink); + ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); + + ref = IMFMediaSink_Release(sink); + todo_wine + ok(ref == 0, "Release returned %ld\n", ref); + + hr = MFShutdown(); + ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); + + IMFSampleGrabberSinkCallback_Release(grabber_callback); +} + static void test_sample_grabber_is_mediatype_supported(void) { IMFSampleGrabberSinkCallback *grabber_callback = create_test_grabber_callback(); @@ -8454,6 +8644,7 @@ START_TEST(mf) test_MFShutdownObject(); test_presentation_clock(); test_sample_grabber(); + test_sample_grabber_seek(); test_sample_grabber_is_mediatype_supported(); test_sample_grabber_orientation(MFVideoFormat_RGB32); test_sample_grabber_orientation(MFVideoFormat_NV12);
From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/mf/tests/mf.c | 419 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 393 insertions(+), 26 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 56cef1c9b10..4c68f3d7e78 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -4189,8 +4189,325 @@ static void test_sample_grabber(void) IMFSampleGrabberSinkCallback_Release(grabber_callback); }
+struct timer_cancel +{ + IUnknown IUnknown_iface; + LONG refcount; + ULONG id; +}; + +static struct timer_cancel* impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct timer_cancel, IUnknown_iface); +} + +static WINAPI HRESULT unknown_QueryInterface(IUnknown *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + } + else + { + *obj = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef(iface); + return S_OK; +} + +static WINAPI ULONG unknown_AddRef(IUnknown *iface) +{ + struct timer_cancel *tc = impl_from_IUnknown(iface); + return InterlockedIncrement(&tc->refcount); +} + +static WINAPI ULONG unknown_Release(IUnknown *iface) +{ + struct timer_cancel *tc = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&tc->refcount); + + if (!tc->refcount) + free(tc); + + return refcount; +} + +static IUnknownVtbl UnknownVtbl = +{ + unknown_QueryInterface, + unknown_AddRef, + unknown_Release, +}; + +static struct timer_cancel* create_timer_cancel(void) +{ + static ULONG id = 1; + + struct timer_cancel *tc = calloc(1, sizeof(*tc)); + tc->IUnknown_iface.lpVtbl = &UnknownVtbl; + tc->refcount = 1; + tc->id = id++; + + return tc; +} + +DEFINE_EXPECT(timer_SetTimer); +DEFINE_EXPECT(timer_CancelTimer); + +struct presentation_clock +{ + IMFPresentationClock IMFPresentationClock_iface; + IMFTimer IMFTimer_iface; + LONG refcount; + IMFClockStateSink *sample_grabber_clock_state_sink; + IMFAsyncResult *callback_result; + IUnknown *cancel_key; +}; + +static struct presentation_clock* impl_from_IMFTimer(IMFTimer *iface) +{ + return CONTAINING_RECORD(iface, struct presentation_clock, IMFTimer_iface); +} + +static WINAPI HRESULT timer_QueryInterface(IMFTimer *iface, REFIID riid, void **obj) +{ + struct presentation_clock* pc = impl_from_IMFTimer(iface); + return IMFPresentationClock_QueryInterface(&pc->IMFPresentationClock_iface, riid, obj); +} + +static WINAPI ULONG timer_AddRef(IMFTimer *iface) +{ + struct presentation_clock* pc = impl_from_IMFTimer(iface); + return IMFPresentationClock_AddRef(&pc->IMFPresentationClock_iface); +} + +static WINAPI ULONG timer_Release(IMFTimer *iface) +{ + struct presentation_clock* pc = impl_from_IMFTimer(iface); + return IMFPresentationClock_Release(&pc->IMFPresentationClock_iface); +} + +static HRESULT WINAPI timer_SetTimer(IMFTimer *iface, DWORD flags, LONGLONG time, + IMFAsyncCallback *callback, IUnknown *state, IUnknown **cancel_key) +{ + struct presentation_clock* pc = impl_from_IMFTimer(iface); + struct timer_cancel *tc; + HRESULT hr; + + CHECK_EXPECT(timer_SetTimer); + + ok(flags == 0, "Unexpected flags value %#lx\n", flags); + ok(time == 0, "Unexpected time value %I64d\n", time); + ok(pc->callback_result == NULL, "Unexpected callback value %p\n", pc->callback_result); + ok(pc->cancel_key == NULL, "Unexpected cancel key %p\n", pc->cancel_key); + + hr = MFCreateAsyncResult(NULL, callback, state, &pc->callback_result); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + tc = create_timer_cancel(); + pc->cancel_key = *cancel_key = &tc->IUnknown_iface; + + return S_OK; +} + +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); + + IMFAsyncResult_Release(pc->callback_result); + pc->callback_result = NULL; + pc->cancel_key = NULL; + + return S_OK; +} + +static IMFTimerVtbl MFTimerVtbl = +{ + timer_QueryInterface, + timer_AddRef, + timer_Release, + timer_SetTimer, + timer_CancelTimer, +}; + +static struct presentation_clock* impl_from_IMFPresentationClock(IMFPresentationClock *iface) +{ + return CONTAINING_RECORD(iface, struct presentation_clock, IMFPresentationClock_iface); +} + +static WINAPI HRESULT presentation_clock_QueryInterface(IMFPresentationClock *iface, REFIID riid, void **obj) +{ + struct presentation_clock *pc = impl_from_IMFPresentationClock(iface); + + if (IsEqualIID(riid, &IID_IMFPresentationClock) || + IsEqualIID(riid, &IID_IMFClock) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + } + else if (IsEqualIID(riid, &IID_IMFTimer)) + { + *obj = &pc->IMFTimer_iface; + } + else + { + *obj = NULL; + return E_NOINTERFACE; + } + + IMFPresentationClock_AddRef(iface); + return S_OK; +} + +static WINAPI ULONG presentation_clock_AddRef(IMFPresentationClock *iface) +{ + struct presentation_clock *pc = impl_from_IMFPresentationClock(iface); + return InterlockedIncrement(&pc->refcount); +} + +static WINAPI ULONG presentation_clock_Release(IMFPresentationClock *iface) +{ + struct presentation_clock *pc = impl_from_IMFPresentationClock(iface); + ULONG refcount = InterlockedDecrement(&pc->refcount); + + if (!pc->refcount) + { + if (pc->sample_grabber_clock_state_sink) + IMFClockStateSink_Release(pc->sample_grabber_clock_state_sink); + if (pc->callback_result) + IMFAsyncResult_Release(pc->callback_result); + free(pc); + } + + return refcount; +} + +static WINAPI HRESULT presentation_clock_GetClockCharacteristics(IMFPresentationClock *iface, DWORD *flags) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_GetCorrelatedTime(IMFPresentationClock *iface, DWORD reserved, + LONGLONG *clock_time, MFTIME *system_time) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_GetContinuityKey(IMFPresentationClock *iface, DWORD *key) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_GetState(IMFPresentationClock *iface, DWORD reserved, MFCLOCK_STATE *state) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_GetProperties(IMFPresentationClock *iface, MFCLOCK_PROPERTIES *props) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_SetTimeSource(IMFPresentationClock *iface, + IMFPresentationTimeSource *time_source) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_GetTimeSource(IMFPresentationClock *iface, + IMFPresentationTimeSource **time_source) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_GetTime(IMFPresentationClock *iface, MFTIME *time) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_AddClockStateSink(IMFPresentationClock *iface, IMFClockStateSink *state_sink) +{ + struct presentation_clock *pc = impl_from_IMFPresentationClock(iface); + + if (pc->sample_grabber_clock_state_sink) + IMFClockStateSink_Release(pc->sample_grabber_clock_state_sink); + + IMFClockStateSink_AddRef(pc->sample_grabber_clock_state_sink = state_sink); + + return S_OK; +} + +static WINAPI HRESULT presentation_clock_RemoveClockStateSink(IMFPresentationClock *iface, + IMFClockStateSink *state_sink) +{ + struct presentation_clock *pc = impl_from_IMFPresentationClock(iface); + + if (pc->sample_grabber_clock_state_sink == state_sink) + { + IMFClockStateSink_Release(state_sink); + pc->sample_grabber_clock_state_sink = NULL; + } + + return S_OK; +} + +static WINAPI HRESULT presentation_clock_Start(IMFPresentationClock *iface, LONGLONG start_offset) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_Stop(IMFPresentationClock *iface) +{ + return E_NOTIMPL; +} + +static WINAPI HRESULT presentation_clock_Pause(IMFPresentationClock *iface) +{ + return E_NOTIMPL; +} + +static IMFPresentationClockVtbl MFPresentationClockVtbl = +{ + presentation_clock_QueryInterface, + presentation_clock_AddRef, + presentation_clock_Release, + presentation_clock_GetClockCharacteristics, + presentation_clock_GetCorrelatedTime, + presentation_clock_GetContinuityKey, + presentation_clock_GetState, + presentation_clock_GetProperties, + presentation_clock_SetTimeSource, + presentation_clock_GetTimeSource, + presentation_clock_GetTime, + presentation_clock_AddClockStateSink, + presentation_clock_RemoveClockStateSink, + presentation_clock_Start, + presentation_clock_Stop, + presentation_clock_Pause, +}; + +static struct presentation_clock* create_presentation_clock(void) +{ + struct presentation_clock* pc = calloc(1, sizeof(*pc)); + + pc->IMFPresentationClock_iface.lpVtbl = &MFPresentationClockVtbl; + pc->IMFTimer_iface.lpVtbl = &MFTimerVtbl; + pc->refcount = 1; + + return pc; +} + +static MFTIME sample_pts = 0; + static void supply_samples(IMFStreamSink *stream, int num_samples) { + IMFMediaBuffer *buffer; IMFSample *sample; HRESULT hr; @@ -4207,9 +4524,11 @@ static void supply_samples(IMFStreamSink *stream, int num_samples) hr = IMFSample_AddBuffer(sample, buffer); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFSample_SetSampleTime(sample, 0); + hr = IMFSample_SetSampleTime(sample, sample_pts); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ sample_pts += 41667; + hr = IMFSample_SetSampleDuration(sample, 41667); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
@@ -4247,7 +4566,8 @@ static int count_samples_requested(IMFStreamSink *stream) static void test_sample_grabber_seek(void) { IMFSampleGrabberSinkCallback *grabber_callback = create_test_grabber_callback(); - IMFPresentationTimeSource *time_source; + struct presentation_clock *mock_clock; + IMFClockStateSink *clock_sink; IMFPresentationClock *clock; IMFMediaType *media_type; IMFStreamSink *stream; @@ -4257,7 +4577,6 @@ static void test_sample_grabber_seek(void) HRESULT hr; ULONG ref;
- hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
@@ -4288,84 +4607,132 @@ static void test_sample_grabber_seek(void)
/* Set clock. */ - hr = MFCreatePresentationClock(&clock); - ok(hr == S_OK, "Failed to create clock object, hr %#lx.\n", hr); + mock_clock = create_presentation_clock(); + clock = &mock_clock->IMFPresentationClock_iface;
hr = IMFMediaSink_SetPresentationClock(sink, clock); ok(hr == S_OK, "Failed to set presentation clock, hr %#lx.\n", hr); - - hr = MFCreateSystemTimeSource(&time_source); - ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr); - - hr = IMFPresentationClock_SetTimeSource(clock, time_source); - ok(hr == S_OK, "Failed to set time source, hr %#lx.\n", hr); - IMFPresentationTimeSource_Release(time_source); + ok(!!mock_clock->sample_grabber_clock_state_sink, "AddClockStateSink not called\n"); + clock_sink = mock_clock->sample_grabber_clock_state_sink;
/* test number of new sample requests on clock start */ - hr = IMFPresentationClock_Start(clock, 0); + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
samples_requested = count_samples_requested(stream); 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 4 samples have been provided */ + sample_pts = 0; + SET_EXPECT(timer_SetTimer); supply_samples(stream, 4); - hr = IMFPresentationClock_Start(clock, 1234); + CHECK_CALLED(timer_SetTimer); + + 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, 3); - hr = IMFPresentationClock_Start(clock, 1234); + todo_wine + CHECK_CALLED(timer_SetTimer); + + 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 */ - hr = IMFPresentationClock_Stop(clock); + hr = IMFClockStateSink_OnClockStop(clock_sink, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFPresentationClock_Start(clock, 0); + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 0); 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 number of new sample requests on seek whilst paused and 3 samples provided */ + sample_pts = 0; + SET_EXPECT(timer_SetTimer); supply_samples(stream, 3); + todo_wine + CHECK_CALLED(timer_SetTimer);
- hr = IMFPresentationClock_Pause(clock); + hr = IMFClockStateSink_OnClockPause(clock_sink, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFPresentationClock_Start(clock, 0); + /* test over supply */ + supply_samples(stream, 6); + + SET_EXPECT(timer_CancelTimer); + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + 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); + ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested);
/* test number of new sample requests on seek whilst paused and no samples provided */ - hr = IMFPresentationClock_Pause(clock); + hr = IMFClockStateSink_OnClockPause(clock_sink, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFPresentationClock_Start(clock, 0); + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
samples_requested = count_samples_requested(stream); - todo_wine ok(samples_requested == 0, "Unexpected number of samples requested %d\n", samples_requested);
+ /* test sample received in the paused state with no samples queued */ + hr = IMFClockStateSink_OnClockPause(clock_sink, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + sample_pts = 0; + 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); + + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, PRESENTATION_CURRENT_POSITION); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested); + + /* required for the sink to be fully released */ ref = IMFPresentationClock_Release(clock); ok(ref == 2, "Release returned %ld\n", ref);
- /* required for the sink to be fully released */ hr = IMFMediaSink_Shutdown(sink); ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/mf/tests/mf.c | 111 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 10 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 4c68f3d7e78..d0a1d235c9e 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -4255,6 +4255,9 @@ static struct timer_cancel* create_timer_cancel(void)
DEFINE_EXPECT(timer_SetTimer); DEFINE_EXPECT(timer_CancelTimer); +DEFINE_EXPECT(MEStreamSinkMarker); + +static MFTIME sample_pts = 0, expected_pts = 0;
struct presentation_clock { @@ -4299,8 +4302,8 @@ static HRESULT WINAPI timer_SetTimer(IMFTimer *iface, DWORD flags, LONGLONG time CHECK_EXPECT(timer_SetTimer);
ok(flags == 0, "Unexpected flags value %#lx\n", flags); - ok(time == 0, "Unexpected time value %I64d\n", time); - ok(pc->callback_result == NULL, "Unexpected callback value %p\n", pc->callback_result); + ok(time == expected_pts, "Unexpected time value %I64d\n", time); + ok(pc->callback_result == NULL, "Unexpected callback result value %p\n", pc->callback_result); ok(pc->cancel_key == NULL, "Unexpected cancel key %p\n", pc->cancel_key);
hr = MFCreateAsyncResult(NULL, callback, state, &pc->callback_result); @@ -4321,6 +4324,7 @@ static HRESULT WINAPI timer_CancelTimer(IMFTimer *iface, IUnknown *cancel_key) ok(cancel_key == pc->cancel_key, "Unexpected cancel key %p\n", cancel_key);
IMFAsyncResult_Release(pc->callback_result); + pc->callback_result = NULL; pc->cancel_key = NULL;
@@ -4503,8 +4507,6 @@ static struct presentation_clock* create_presentation_clock(void) return pc; }
-static MFTIME sample_pts = 0; - static void supply_samples(IMFStreamSink *stream, int num_samples) {
@@ -4558,25 +4560,64 @@ static int count_samples_requested(IMFStreamSink *stream) samples_requested++; else if (met == MEStreamSinkStarted) break; + else if (met == MEStreamSinkMarker) + { + CHECK_EXPECT(MEStreamSinkMarker); + break; + } }
return samples_requested; }
+#define trigger_timer(mock_clock) _trigger_timer(__LINE__, mock_clock) + +static HRESULT _trigger_timer(int line, struct presentation_clock *mock_clock) +{ + HRESULT hr = E_FAIL; + + mock_clock->cancel_key = NULL; + + ok_(__FILE__, line)(!!mock_clock->callback_result, "Expected callback result to be set\n"); + + if (mock_clock->callback_result) + { + hr = MFInvokeCallback(mock_clock->callback_result); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFAsyncResult_Release(mock_clock->callback_result); + mock_clock->callback_result = NULL; + } + + return hr; +} + static void test_sample_grabber_seek(void) { - IMFSampleGrabberSinkCallback *grabber_callback = create_test_grabber_callback(); + struct test_grabber_callback *grabber_callback_impl; + IMFSampleGrabberSinkCallback *grabber_callback; struct presentation_clock *mock_clock; IMFClockStateSink *clock_sink; IMFPresentationClock *clock; + IMFAsyncCallback *callback; IMFMediaType *media_type; IMFStreamSink *stream; IMFActivate *activate; int samples_requested; + PROPVARIANT propvar; IMFMediaSink *sink; HRESULT hr; ULONG ref;
+ PropVariantInit(&propvar); + callback = create_test_callback(TRUE); + + grabber_callback = create_test_grabber_callback(); + grabber_callback_impl = impl_from_IMFSampleGrabberSinkCallback(grabber_callback); + grabber_callback_impl->ready_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!grabber_callback_impl->ready_event, "CreateEventW failed, error %lu\n", GetLastError()); + grabber_callback_impl->done_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!grabber_callback_impl->done_event, "CreateEventW failed, error %lu\n", GetLastError()); + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
@@ -4642,9 +4683,27 @@ static void test_sample_grabber_seek(void) /* 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, 3); + 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); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + supply_samples(stream, 1); + + ok(!!mock_clock->callback_result, "Expected callback result to be set\n"); + hr = trigger_timer(mock_clock); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = WaitForSingleObject(grabber_callback_impl->ready_event, 1000); + ok(hr == WAIT_OBJECT_0, "Unexpected hr %#lx.\n", hr); + + expected_pts = 41667; + SET_EXPECT(timer_SetTimer); + SetEvent(grabber_callback_impl->done_event); + hr = gen_wait_media_event((IMFMediaEventGenerator*)stream, callback, MEStreamSinkRequestSample, 1000, &propvar); + PropVariantClear(&propvar); + CHECK_CALLED(timer_SetTimer);
SET_EXPECT(timer_CancelTimer); hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 1234); @@ -4654,7 +4713,7 @@ static void test_sample_grabber_seek(void)
samples_requested = count_samples_requested(stream); todo_wine - ok(samples_requested == 3, "Unexpected number of samples requested %d\n", samples_requested); + ok(samples_requested == 2, "Unexpected number of samples requested %d\n", samples_requested);
/* test number of new sample requests on seek whilst stopped */ hr = IMFClockStateSink_OnClockStop(clock_sink, 0); @@ -4667,11 +4726,40 @@ static void test_sample_grabber_seek(void) ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested);
/* test number of new sample requests on seek whilst paused and 3 samples provided */ - sample_pts = 0; + sample_pts = expected_pts = 0; SET_EXPECT(timer_SetTimer); - supply_samples(stream, 3); + 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); + + 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"); + }
hr = IMFClockStateSink_OnClockPause(clock_sink, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -4701,7 +4789,7 @@ static void test_sample_grabber_seek(void) hr = IMFClockStateSink_OnClockPause(clock_sink, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- sample_pts = 0; + expected_pts = sample_pts; SET_EXPECT(timer_SetTimer); supply_samples(stream, 4); todo_wine @@ -4740,6 +4828,9 @@ static void test_sample_grabber_seek(void) todo_wine ok(ref == 0, "Release returned %ld\n", ref);
+ ref = IMFAsyncCallback_Release(callback); + ok(ref == 0, "Release returned %ld\n", ref); + hr = MFShutdown(); ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/mf/tests/mf.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index d0a1d235c9e..c5153d12d39 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -4299,11 +4299,15 @@ static HRESULT WINAPI timer_SetTimer(IMFTimer *iface, DWORD flags, LONGLONG time struct timer_cancel *tc; HRESULT hr;
+ todo_wine_if(time == 83334) CHECK_EXPECT(timer_SetTimer);
ok(flags == 0, "Unexpected flags value %#lx\n", flags); + todo_wine_if(time == 83334) ok(time == expected_pts, "Unexpected time value %I64d\n", time); + todo_wine_if(time == 83334) ok(pc->callback_result == NULL, "Unexpected callback result value %p\n", pc->callback_result); + todo_wine_if(time == 83334) ok(pc->cancel_key == NULL, "Unexpected cancel key %p\n", pc->cancel_key);
hr = MFCreateAsyncResult(NULL, callback, state, &pc->callback_result); @@ -4562,6 +4566,7 @@ static int count_samples_requested(IMFStreamSink *stream) break; else if (met == MEStreamSinkMarker) { + todo_wine CHECK_EXPECT(MEStreamSinkMarker); break; } @@ -4715,6 +4720,30 @@ static void test_sample_grabber_seek(void) 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 */ + hr = IMFStreamSink_Flush(stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + supply_samples(stream, 1); + + /* only on seek */ + 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 */ hr = IMFClockStateSink_OnClockStop(clock_sink, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -4723,13 +4752,13 @@ static void test_sample_grabber_seek(void) 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 number of new sample requests on seek whilst paused and 3 samples provided */ 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); @@ -4783,6 +4812,7 @@ static void test_sample_grabber_seek(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
samples_requested = count_samples_requested(stream); + todo_wine ok(samples_requested == 0, "Unexpected number of samples requested %d\n", samples_requested);
/* test sample received in the paused state with no samples queued */ @@ -4815,6 +4845,7 @@ static void test_sample_grabber_seek(void) 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);
/* required for the sink to be fully released */
From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/mf/tests/mf.c | 241 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 234 insertions(+), 7 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index c5153d12d39..f3409635824 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -3105,6 +3105,8 @@ static void test_media_session_rate_control(void) ok(hr == S_OK, "Shutdown failure, hr %#lx.\n", hr); }
+DEFINE_EXPECT(OnProcessSample); + struct test_grabber_callback { IMFSampleGrabberSinkCallback IMFSampleGrabberSinkCallback_iface; @@ -3113,6 +3115,8 @@ struct test_grabber_callback IMFCollection *samples; HANDLE ready_event; HANDLE done_event; + + BOOL do_event; };
static struct test_grabber_callback *impl_from_IMFSampleGrabberSinkCallback(IMFSampleGrabberSinkCallback *iface) @@ -3204,7 +3208,7 @@ static HRESULT WINAPI test_grabber_callback_OnProcessSample(IMFSampleGrabberSink return S_OK; }
- if (!grabber->ready_event) + if (!grabber->ready_event && grabber->do_event) return E_NOTIMPL;
sample = create_sample(buffer, sample_size); @@ -3218,9 +3222,16 @@ static HRESULT WINAPI test_grabber_callback_OnProcessSample(IMFSampleGrabberSink IMFCollection_AddElement(grabber->samples, (IUnknown *)sample); IMFSample_Release(sample);
- SetEvent(grabber->ready_event); - res = WaitForSingleObject(grabber->done_event, 1000); - ok(!res, "WaitForSingleObject returned %#lx\n", res); + if (grabber->do_event) + { + SetEvent(grabber->ready_event); + res = WaitForSingleObject(grabber->done_event, 1000); + ok(!res, "WaitForSingleObject returned %#lx\n", res); + } + else + { + CHECK_EXPECT2(OnProcessSample); + }
return S_OK; } @@ -3257,6 +3268,7 @@ static IMFSampleGrabberSinkCallback *create_test_grabber_callback(void) grabber->refcount = 1; hr = MFCreateCollection(&grabber->samples); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + grabber->do_event = TRUE;
return &grabber->IMFSampleGrabberSinkCallback_iface; } @@ -4546,7 +4558,10 @@ static void supply_samples(IMFStreamSink *stream, int num_samples) } }
-static int count_samples_requested(IMFStreamSink *stream) +static BOOL ignore_clock = FALSE; + +#define count_samples_requested(stream) _count_samples_requested(__LINE__, stream) +static int _count_samples_requested(int line, IMFStreamSink *stream) { int samples_requested; IMFMediaEvent *event; @@ -4557,16 +4572,19 @@ static int count_samples_requested(IMFStreamSink *stream) while (IMFStreamSink_GetEvent(stream, 0, &event) == S_OK) { hr = IMFMediaEvent_GetType(event, &met); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
IMFMediaEvent_Release(event); if (met == MEStreamSinkRequestSample) samples_requested++; else if (met == MEStreamSinkStarted) + { + ok_(__FILE__, line)(!expect_MEStreamSinkMarker, "Expected MEStreamSinkMarker, got MEStreamSinkStarted\n"); break; + } else if (met == MEStreamSinkMarker) { - todo_wine + todo_wine_if(!ignore_clock) CHECK_EXPECT(MEStreamSinkMarker); break; } @@ -4859,6 +4877,215 @@ static void test_sample_grabber_seek(void) todo_wine ok(ref == 0, "Release returned %ld\n", ref);
+ /* 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; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr); + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr); + + EXPECT_REF(media_type, 1); + hr = MFCreateSampleGrabberSinkActivate(media_type, grabber_callback, &activate); + ok(hr == S_OK, "Failed to create grabber activate, hr %#lx.\n", hr); + EXPECT_REF(media_type, 2); + + hr = IMFActivate_SetUINT32(activate, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ref = IMFMediaType_Release(media_type); + ok(ref == 1, "Release returned %ld\n", ref); + + hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink); + ok(hr == S_OK, "Failed to activate object, hr %#lx.\n", hr); + + ref = IMFActivate_Release(activate); + ok(ref == 0, "Release returned %ld\n", ref); + + hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream); + ok(hr == S_OK, "Failed to get sink stream, hr %#lx.\n", hr); + + + /* Set clock. */ + mock_clock = create_presentation_clock(); + clock = &mock_clock->IMFPresentationClock_iface; + + hr = IMFMediaSink_SetPresentationClock(sink, clock); + ok(hr == S_OK, "Failed to set presentation clock, hr %#lx.\n", hr); + ok(!!mock_clock->sample_grabber_clock_state_sink, "AddClockStateSink not called\n"); + clock_sink = mock_clock->sample_grabber_clock_state_sink; + + + /* test number of new sample requests on clock start */ + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + 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 4 samples have been provided */ + sample_pts = 0; + SET_EXPECT(OnProcessSample); + supply_samples(stream, 4); + CHECK_CALLED(OnProcessSample); + CLEAR_CALLED(OnProcessSample); + + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 1234); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + 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(OnProcessSample); + supply_samples(stream, 2); + CHECK_CALLED(OnProcessSample); + CLEAR_CALLED(OnProcessSample); + hr = IMFStreamSink_PlaceMarker(stream, MFSTREAMSINK_MARKER_DEFAULT, NULL, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SET_EXPECT(OnProcessSample); + supply_samples(stream, 1); + CHECK_CALLED(OnProcessSample); + CLEAR_CALLED(OnProcessSample); + + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 1234); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + SET_EXPECT(MEStreamSinkMarker); + samples_requested = count_samples_requested(stream); + ok(samples_requested == 2, "Unexpected number of samples requested %d\n", samples_requested); + CHECK_CALLED(MEStreamSinkMarker); + CLEAR_CALLED(OnProcessSample); + + samples_requested = count_samples_requested(stream); + ok(samples_requested == 1, "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(OnProcessSample); + supply_samples(stream, 2); + CHECK_CALLED(OnProcessSample); + CLEAR_CALLED(OnProcessSample); + + /* there is no cancel timer, or sample requests during a flush */ + hr = IMFStreamSink_Flush(stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + SET_EXPECT(OnProcessSample); + supply_samples(stream, 1); + CHECK_CALLED(OnProcessSample); + CLEAR_CALLED(OnProcessSample); + + /* only on seek */ + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 1234); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + ok(samples_requested == 3, "Unexpected number of samples requested %d\n", samples_requested); + + /* test number of new sample requests on seek whilst stopped */ + hr = IMFClockStateSink_OnClockStop(clock_sink, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested); + + /* test number of new sample requests on seek whilst paused and 3 samples provided */ + sample_pts = expected_pts = 0; + SET_EXPECT(OnProcessSample); + supply_samples(stream, 3); + CHECK_CALLED(OnProcessSample); + CLEAR_CALLED(OnProcessSample); + hr = IMFStreamSink_PlaceMarker(stream, MFSTREAMSINK_MARKER_DEFAULT, NULL, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + SET_EXPECT(OnProcessSample); + supply_samples(stream, 2); + CHECK_CALLED(OnProcessSample); + CLEAR_CALLED(OnProcessSample); + + SET_EXPECT(MEStreamSinkMarker); + samples_requested = count_samples_requested(stream); + ok(samples_requested == 3, "Unexpected number of samples requested %d\n", samples_requested); + CHECK_CALLED(MEStreamSinkMarker); + + hr = IMFClockStateSink_OnClockPause(clock_sink, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* test over supply */ + SET_EXPECT(OnProcessSample); + supply_samples(stream, 6); + CHECK_CALLED(OnProcessSample); + CLEAR_CALLED(OnProcessSample); + + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + ok(samples_requested == 8, "Unexpected number of samples requested %d\n", samples_requested); + + /* test number of new sample requests on seek whilst paused and no samples provided */ + hr = IMFClockStateSink_OnClockPause(clock_sink, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + ok(samples_requested == 0, "Unexpected number of samples requested %d\n", samples_requested); + + /* test sample received in the paused state with no samples queued */ + hr = IMFClockStateSink_OnClockPause(clock_sink, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + expected_pts = sample_pts; + SET_EXPECT(OnProcessSample); + supply_samples(stream, 4); + CHECK_CALLED(OnProcessSample); + CLEAR_CALLED(OnProcessSample); + + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, PRESENTATION_CURRENT_POSITION); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested); + + /* test sample received in the stopped state */ + hr = IMFClockStateSink_OnClockStop(clock_sink, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + supply_samples(stream, 4); + + hr = IMFClockStateSink_OnClockStart(clock_sink, 0, PRESENTATION_CURRENT_POSITION); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + samples_requested = count_samples_requested(stream); + ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested); + + ref = IMFPresentationClock_Release(clock); + ok(ref == 2, "Release returned %ld\n", ref); + + /* required for the sink to be fully released */ + hr = IMFMediaSink_Shutdown(sink); + ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); + + ref = IMFMediaSink_Release(sink); + todo_wine + ok(ref == 0, "Release returned %ld\n", ref); + ref = IMFAsyncCallback_Release(callback); ok(ref == 0, "Release returned %ld\n", ref);
From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/mf/tests/mf.c | 87 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index f3409635824..5cbb7ddf485 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -3117,6 +3117,7 @@ struct test_grabber_callback HANDLE done_event;
BOOL do_event; + BOOL need_sample_time; };
static struct test_grabber_callback *impl_from_IMFSampleGrabberSinkCallback(IMFSampleGrabberSinkCallback *iface) @@ -3215,7 +3216,7 @@ static HRESULT WINAPI test_grabber_callback_OnProcessSample(IMFSampleGrabberSink hr = IMFSample_SetSampleFlags(sample, sample_flags); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); /* FIXME: sample time is inconsistent across windows versions, ignore it */ - hr = IMFSample_SetSampleTime(sample, 0); + hr = IMFSample_SetSampleTime(sample, grabber->need_sample_time ? sample_time : 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFSample_SetSampleDuration(sample, sample_duration); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -4628,8 +4629,47 @@ static void test_sample_grabber_seek(void) int samples_requested; PROPVARIANT propvar; IMFMediaSink *sink; + IMFSample *sample; + LONGLONG pts; + DWORD count; HRESULT hr; ULONG ref; + int i; + + static const LONGLONG use_clock_samples[] = + { + 0, + 0 + }; + + static const LONGLONG ignore_clock_samples[] = + { + 0, + 41667, + 83334, + 125001, + 0, + 41667, + 83334, + 0, + 41667, + 83334, + 0, + 41667, + 83334, + 125001, + 166668, + 208335, + 250002, + 291669, + 333336, + 375003, + 416670, + 458337, + 500004, + 541671, + 583338, + };
PropVariantInit(&propvar); callback = create_test_callback(TRUE); @@ -4640,6 +4680,7 @@ static void test_sample_grabber_seek(void) ok(!!grabber_callback_impl->ready_event, "CreateEventW failed, error %lu\n", GetLastError()); grabber_callback_impl->done_event = CreateEventW(NULL, FALSE, FALSE, NULL); ok(!!grabber_callback_impl->done_event, "CreateEventW failed, error %lu\n", GetLastError()); + grabber_callback_impl->need_sample_time = TRUE;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr); @@ -4866,6 +4907,29 @@ static void test_sample_grabber_seek(void) todo_wine ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested);
+ /* 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]); + + ref = IMFSample_Release(sample); + ok(ref == 1, "Release returned %ld\n", ref); + } + } + /* required for the sink to be fully released */ ref = IMFPresentationClock_Release(clock); ok(ref == 2, "Release returned %ld\n", ref); @@ -4883,6 +4947,7 @@ static void test_sample_grabber_seek(void) grabber_callback = create_test_grabber_callback(); grabber_callback_impl = impl_from_IMFSampleGrabberSinkCallback(grabber_callback); grabber_callback_impl->do_event = FALSE; + grabber_callback_impl->need_sample_time = TRUE;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr); @@ -5075,10 +5140,28 @@ static void test_sample_grabber_seek(void) samples_requested = count_samples_requested(stream); ok(samples_requested == 4, "Unexpected number of samples requested %d\n", samples_requested);
+ /* check contents of collection */ + hr = IMFCollection_GetElementCount(grabber_callback_impl->samples, &count); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(count == ARRAY_SIZE(ignore_clock_samples), "Unexpected total of samples delivered %ld\n", count); + + for (i = 0; i < ARRAY_SIZE(ignore_clock_samples); i++) + { + hr = IMFCollection_GetElement(grabber_callback_impl->samples, i, (IUnknown**)&sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFSample_GetSampleTime(sample, &pts); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(pts == ignore_clock_samples[i], "%d: Unexpected pts %I64d, expected %I64d\n", i, pts, ignore_clock_samples[i]); + + ref = IMFSample_Release(sample); + ok(ref == 1, "Release returned %ld\n", ref); + } + + /* required for the sink to be fully released */ ref = IMFPresentationClock_Release(clock); ok(ref == 2, "Release returned %ld\n", ref);
- /* required for the sink to be fully released */ hr = IMFMediaSink_Shutdown(sink); ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
From: Brendan McGrath bmcgrath@codeweavers.com
--- dlls/mf/samplegrabber.c | 93 ++++++++++++----------------------------- dlls/mf/tests/mf.c | 64 ++++++---------------------- 2 files changed, 39 insertions(+), 118 deletions(-)
diff --git a/dlls/mf/samplegrabber.c b/dlls/mf/samplegrabber.c index a8c797f25ed..fe884cadff3 100644 --- a/dlls/mf/samplegrabber.c +++ b/dlls/mf/samplegrabber.c @@ -89,8 +89,7 @@ struct sample_grabber float rate; enum sink_state state; CRITICAL_SECTION cs; - UINT32 sample_count; - IMFSample *samples[MAX_SAMPLE_QUEUE_LENGTH]; + byte samples_queued; };
static IMFSampleGrabberSinkCallback *sample_grabber_get_callback(const struct sample_grabber *sink) @@ -187,13 +186,14 @@ static ULONG WINAPI sample_grabber_stream_AddRef(IMFStreamSink *iface) return IMFMediaSink_AddRef(&grabber->IMFMediaSink_iface); }
-static void stream_release_pending_item(struct scheduled_item *item) +static void stream_release_pending_item(struct sample_grabber *grabber, struct scheduled_item *item) { list_remove(&item->entry); switch (item->type) { case ITEM_TYPE_SAMPLE: IMFSample_Release(item->u.sample); + grabber->samples_queued--; break; case ITEM_TYPE_MARKER: PropVariantClear(&item->u.marker.context); @@ -398,13 +398,13 @@ static HRESULT stream_queue_sample(struct sample_grabber *grabber, IMFSample *sa item->u.sample = sample; IMFSample_AddRef(item->u.sample); list_init(&item->entry); - if (list_empty(&grabber->items)) + if (!grabber->samples_queued++) hr = stream_schedule_sample(grabber, item);
if (SUCCEEDED(hr)) list_add_tail(&grabber->items, &item->entry); else - stream_release_pending_item(item); + stream_release_pending_item(grabber, item);
return hr; } @@ -430,7 +430,7 @@ static HRESULT WINAPI sample_grabber_stream_ProcessSample(IMFStreamSink *iface,
if (grabber->is_shut_down) hr = MF_E_STREAMSINK_REMOVED; - else if (grabber->state == SINK_STATE_RUNNING || (grabber->state == SINK_STATE_PAUSED && grabber->ignore_clock)) + else if (grabber->state != SINK_STATE_STOPPED) { hr = IMFSample_GetSampleTime(sample, &sampletime);
@@ -448,14 +448,6 @@ static HRESULT WINAPI sample_grabber_stream_ProcessSample(IMFStreamSink *iface, hr = stream_queue_sample(grabber, sample); } } - else if (grabber->state == SINK_STATE_PAUSED) - { - if (grabber->sample_count < MAX_SAMPLE_QUEUE_LENGTH) - { - IMFSample_AddRef(sample); - grabber->samples[grabber->sample_count++] = sample; - } - }
LeaveCriticalSection(&grabber->cs);
@@ -492,7 +484,7 @@ static HRESULT stream_place_marker(struct sample_grabber *grabber, MFSTREAMSINK_ if (SUCCEEDED(hr)) list_add_tail(&grabber->items, &item->entry); else - stream_release_pending_item(item); + stream_release_pending_item(grabber, item);
return hr; } @@ -520,7 +512,6 @@ static HRESULT WINAPI sample_grabber_stream_PlaceMarker(IMFStreamSink *iface, MF static HRESULT WINAPI sample_grabber_stream_Flush(IMFStreamSink *iface) { struct sample_grabber *grabber = impl_from_IMFStreamSink(iface); - struct scheduled_item *item, *next_item; HRESULT hr = S_OK;
TRACE("%p.\n", iface); @@ -529,17 +520,6 @@ static HRESULT WINAPI sample_grabber_stream_Flush(IMFStreamSink *iface)
if (grabber->is_shut_down) hr = MF_E_STREAMSINK_REMOVED; - else - { - LIST_FOR_EACH_ENTRY_SAFE(item, next_item, &grabber->items, struct scheduled_item, entry) - { - /* Samples are discarded, markers are processed immediately. */ - if (item->type == ITEM_TYPE_MARKER) - sample_grabber_stream_report_marker(grabber, &item->u.marker.context, E_ABORT); - - stream_release_pending_item(item); - } - }
LeaveCriticalSection(&grabber->cs);
@@ -761,7 +741,7 @@ static HRESULT WINAPI sample_grabber_stream_timer_callback_Invoke(IMFAsyncCallba if (item->type == ITEM_TYPE_MARKER) { sample_grabber_stream_report_marker(grabber, &item->u.marker.context, S_OK); - stream_release_pending_item(item); + stream_release_pending_item(grabber, item); } else if (item->type == ITEM_TYPE_SAMPLE) { @@ -769,8 +749,10 @@ static HRESULT WINAPI sample_grabber_stream_timer_callback_Invoke(IMFAsyncCallba { if (FAILED(hr = sample_grabber_report_sample(grabber, item->u.sample, &sample_delivered))) WARN("Failed to report a sample, hr %#lx.\n", hr); - stream_release_pending_item(item); + stream_release_pending_item(grabber, item); sample_reported = TRUE; + if (sample_delivered) + sample_grabber_stream_request_sample(grabber); } else { @@ -780,8 +762,6 @@ static HRESULT WINAPI sample_grabber_stream_timer_callback_Invoke(IMFAsyncCallba } } } - if (sample_delivered) - sample_grabber_stream_request_sample(grabber);
LeaveCriticalSection(&grabber->cs);
@@ -852,21 +832,7 @@ static void sample_grabber_release_pending_items(struct sample_grabber *grabber)
LIST_FOR_EACH_ENTRY_SAFE(item, next_item, &grabber->items, struct scheduled_item, entry) { - stream_release_pending_item(item); - } -} - -static void release_samples(struct sample_grabber *grabber) -{ - unsigned int i; - - for (i = 0; i < MAX_SAMPLE_QUEUE_LENGTH; ++i) - { - if (grabber->samples[i]) - { - IMFSample_Release(grabber->samples[i]); - grabber->samples[i] = NULL; - } + stream_release_pending_item(grabber, item); } }
@@ -902,7 +868,6 @@ static ULONG WINAPI sample_grabber_sink_Release(IMFMediaSink *iface) if (grabber->sample_attributes) IMFAttributes_Release(grabber->sample_attributes); sample_grabber_release_pending_items(grabber); - release_samples(grabber); DeleteCriticalSection(&grabber->cs); free(grabber); } @@ -1175,6 +1140,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;
@@ -1189,27 +1155,21 @@ static HRESULT sample_grabber_set_state(struct sample_grabber *grabber, enum sin if (state == SINK_STATE_STOPPED) { 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; @@ -1517,7 +1477,6 @@ static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *use object->IMFStreamSink_iface.lpVtbl = &sample_grabber_stream_vtbl; object->IMFMediaTypeHandler_iface.lpVtbl = &sample_grabber_stream_type_handler_vtbl; object->timer_callback.lpVtbl = &sample_grabber_stream_timer_callback_vtbl; - object->sample_count = MAX_SAMPLE_QUEUE_LENGTH; object->refcount = 1; object->rate = 1.0f; if (FAILED(IMFSampleGrabberSinkCallback_QueryInterface(context->callback, &IID_IMFSampleGrabberSinkCallback2, diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 5cbb7ddf485..79acccd7cd9 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -4312,15 +4312,11 @@ static HRESULT WINAPI timer_SetTimer(IMFTimer *iface, DWORD flags, LONGLONG time struct timer_cancel *tc; HRESULT hr;
- todo_wine_if(time == 83334) CHECK_EXPECT(timer_SetTimer);
ok(flags == 0, "Unexpected flags value %#lx\n", flags); - todo_wine_if(time == 83334) ok(time == expected_pts, "Unexpected time value %I64d\n", time); - todo_wine_if(time == 83334) ok(pc->callback_result == NULL, "Unexpected callback result value %p\n", pc->callback_result); - todo_wine_if(time == 83334) ok(pc->cancel_key == NULL, "Unexpected cancel key %p\n", pc->cancel_key);
hr = MFCreateAsyncResult(NULL, callback, state, &pc->callback_result); @@ -4336,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);
@@ -4559,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) { @@ -4585,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; } @@ -4737,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); @@ -4772,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 */ @@ -4796,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 */ @@ -4811,7 +4795,6 @@ static void test_sample_grabber_seek(void) 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 number of new sample requests on seek whilst paused and 3 samples provided */ @@ -4823,31 +4806,21 @@ static void test_sample_grabber_seek(void) 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); + 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); @@ -4871,7 +4844,6 @@ static void test_sample_grabber_seek(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
samples_requested = count_samples_requested(stream); - todo_wine ok(samples_requested == 0, "Unexpected number of samples requested %d\n", samples_requested);
/* test sample received in the paused state with no samples queued */ @@ -4881,21 +4853,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); @@ -4904,30 +4873,24 @@ static void test_sample_grabber_seek(void) 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);
/* 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 */ @@ -4943,7 +4906,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;