Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 49 ++++++++++++++++---------------------- dlls/mfplat/tests/mfplat.c | 25 +++++++++++++++++++ 2 files changed, 46 insertions(+), 28 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 1992776595d..7991152f7a7 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -124,17 +124,20 @@ struct system_time_source MFCLOCK_STATE state; IMFClock *clock; LONGLONG start_offset; + LONGLONG system_time; + LONGLONG clock_time; float rate; int i_rate; CRITICAL_SECTION cs; };
-static void system_time_source_apply_rate(const struct system_time_source *source, LONGLONG *value) +static void system_time_source_update_clock_time(struct system_time_source *source, LONGLONG system_time) { - if (source->i_rate) - *value *= source->i_rate; - else - *value *= source->rate; + LONGLONG diff = system_time - source->system_time; + if (source->i_rate) diff *= source->i_rate; + else if (source->rate != 1.0f) diff *= source->rate; + source->clock_time += diff; + source->system_time = system_time; }
static struct system_time_source *impl_from_IMFPresentationTimeSource(IMFPresentationTimeSource *iface) @@ -8076,12 +8079,8 @@ static HRESULT WINAPI system_time_source_GetCorrelatedTime(IMFPresentationTimeSo if (SUCCEEDED(hr = IMFClock_GetCorrelatedTime(source->clock, 0, clock_time, system_time))) { if (source->state == MFCLOCK_STATE_RUNNING) - { - system_time_source_apply_rate(source, clock_time); - *clock_time += source->start_offset; - } - else - *clock_time = source->start_offset; + system_time_source_update_clock_time(source, *system_time); + *clock_time = source->start_offset + source->clock_time; } LeaveCriticalSection(&source->cs);
@@ -8220,25 +8219,19 @@ static HRESULT WINAPI system_time_source_sink_OnClockStart(IMFClockStateSink *if state = source->state; if (SUCCEEDED(hr = system_time_source_change_state(source, CLOCK_CMD_START))) { - system_time_source_apply_rate(source, &system_time); if (start_offset == PRESENTATION_CURRENT_POSITION) { - switch (state) + if (state != MFCLOCK_STATE_RUNNING) { - case MFCLOCK_STATE_RUNNING: - break; - case MFCLOCK_STATE_PAUSED: - source->start_offset -= system_time; - break; - default: - source->start_offset = -system_time; - break; - ; + source->start_offset -= system_time; + source->system_time = 0; } } else { - source->start_offset = -system_time + start_offset; + source->start_offset = start_offset; + source->system_time = system_time; + source->clock_time = 0; } } LeaveCriticalSection(&source->cs); @@ -8255,7 +8248,9 @@ static HRESULT WINAPI system_time_source_sink_OnClockStop(IMFClockStateSink *ifa
EnterCriticalSection(&source->cs); if (SUCCEEDED(hr = system_time_source_change_state(source, CLOCK_CMD_STOP))) - source->start_offset = 0; + { + source->start_offset = source->system_time = source->clock_time = 0; + } LeaveCriticalSection(&source->cs);
return hr; @@ -8271,8 +8266,7 @@ static HRESULT WINAPI system_time_source_sink_OnClockPause(IMFClockStateSink *if EnterCriticalSection(&source->cs); if (SUCCEEDED(hr = system_time_source_change_state(source, CLOCK_CMD_PAUSE))) { - system_time_source_apply_rate(source, &system_time); - source->start_offset += system_time; + system_time_source_update_clock_time(source, system_time); } LeaveCriticalSection(&source->cs);
@@ -8289,8 +8283,7 @@ static HRESULT WINAPI system_time_source_sink_OnClockRestart(IMFClockStateSink * EnterCriticalSection(&source->cs); if (SUCCEEDED(hr = system_time_source_change_state(source, CLOCK_CMD_RESTART))) { - system_time_source_apply_rate(source, &system_time); - source->start_offset -= system_time; + source->system_time = system_time; } LeaveCriticalSection(&source->cs);
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index c013b7b5c23..91c9d971a3b 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -3641,6 +3641,31 @@ static void test_system_time_source(void) hr = IMFClockStateSink_OnClockStart(statesink, 0, 0); ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
+ hr = IMFClockStateSink_OnClockSetRate(statesink, 5, 2.0f); + ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr); + + hr = IMFClockStateSink_OnClockPause(statesink, 6); + 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 == 12 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), + wine_dbgstr_longlong(systime)); + + hr = IMFClockStateSink_OnClockRestart(statesink, 7); + ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr); + + 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 == 14 && !!systime, "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 == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=108312
Your paranoid android.
=== w7u_adm (32 bit report) ===
mfplat: 086c:mfplat: unhandled exception c0000005 at 6ECF7D1C
=== w7u_el (32 bit report) ===
mfplat: 0860:mfplat: unhandled exception c0000005 at 6ECE7D1C