Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 22 +++++++- dlls/mfplat/tests/mfplat.c | 109 ++++++++++++++++++++++++++++++++++++- 2 files changed, 129 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 889961b8d1..37ea744313 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -8058,15 +8058,35 @@ static HRESULT WINAPI system_time_source_sink_OnClockStart(IMFClockStateSink *if LONGLONG start_offset) { struct system_time_source *source = impl_from_IMFClockStateSink(iface); + MFCLOCK_STATE state; HRESULT hr;
TRACE("%p, %s, %s.\n", iface, debugstr_time(system_time), debugstr_time(start_offset));
EnterCriticalSection(&source->cs); + state = source->state; if (SUCCEEDED(hr = system_time_source_change_state(source, CLOCK_CMD_START))) { system_time_source_apply_rate(source, &system_time); - source->start_offset = -system_time + start_offset; + if (start_offset == PRESENTATION_CURRENT_POSITION) + { + switch (state) + { + case MFCLOCK_STATE_RUNNING: + break; + case MFCLOCK_STATE_PAUSED: + source->start_offset -= system_time; + break; + default: + source->start_offset = -system_time; + break; + ; + } + } + else + { + source->start_offset = -system_time + start_offset; + } } LeaveCriticalSection(&source->cs);
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 497c451f72..185bacdebe 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -3127,7 +3127,6 @@ static void test_system_time_source(void) hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); ok(hr == S_OK, "Failed to get time %#x.\n", hr); ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime)); - IMFClockStateSink_Release(statesink);
hr = IMFClockStateSink_OnClockStart(statesink, 10, 0); ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr); @@ -3172,6 +3171,114 @@ static void test_system_time_source(void) ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
+ IMFClockStateSink_Release(statesink); + IMFPresentationTimeSource_Release(time_source); + + /* PRESENTATION_CURRENT_POSITION */ + hr = MFCreateSystemTimeSource(&time_source); + ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink); + ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + /* INVALID -> RUNNING */ + hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION); + ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + /* RUNNING -> RUNNING */ + hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION); + ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION); + ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + hr = IMFClockStateSink_OnClockStart(statesink, 0, 0); + ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION); + ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + /* STOPPED -> RUNNING */ + hr = IMFClockStateSink_OnClockStop(statesink, 567); + ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION); + ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + /* PAUSED -> RUNNING */ + hr = IMFClockStateSink_OnClockPause(statesink, 8); + ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION); + ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + hr = IMFClockStateSink_OnClockPause(statesink, 7); + ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + hr = IMFClockStateSink_OnClockStart(statesink, 50, 7); + ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr); + + hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime); + ok(hr == S_OK, "Failed to get time %#x.\n", hr); + ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + IMFClockStateSink_Release(statesink); IMFPresentationTimeSource_Release(time_source); }