From: Brendan McGrath <bmcgrath@codeweavers.com> --- dlls/mf/sar.c | 57 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c index ccc1ad9dccd..9b19acdff75 100644 --- a/dlls/mf/sar.c +++ b/dlls/mf/sar.c @@ -42,6 +42,7 @@ enum audio_renderer_flags SAR_SHUT_DOWN = 0x1, SAR_PREROLLED = 0x2, SAR_SAMPLE_REQUESTED = 0x4, + SAR_SEEKING = 0x8, }; enum queued_object_type @@ -113,6 +114,7 @@ struct audio_renderer DWORD sample_rate; MFCLOCK_STATE clock_state; LONGLONG pts; + LONGLONG seek_pts; UINT64 position; UINT64 audio_clock_frequency; float rate; @@ -664,6 +666,11 @@ static HRESULT WINAPI audio_renderer_clock_sink_OnClockStart(IMFClockStateSink * EnterCriticalSection(&renderer->cs); if (renderer->audio_client) { + if (offset != PRESENTATION_CURRENT_POSITION) + { + renderer->seek_pts = offset; + renderer->flags |= SAR_SEEKING; + } renderer->clock_state = MFCLOCK_STATE_RUNNING; if (renderer->state != STREAM_STATE_RUNNING) { @@ -1234,27 +1241,51 @@ static HRESULT WINAPI audio_renderer_time_source_GetClockCharacteristics(IMFPres return S_OK; } -static HRESULT WINAPI audio_renderer_time_source_GetCorrelatedTime(IMFPresentationTimeSource *iface, DWORD reserved, LONGLONG *clock_time, +static HRESULT audio_renderer_get_correlated_time(struct audio_renderer *renderer, LONGLONG *clock_time, MFTIME *system_time) { - struct audio_renderer *renderer = impl_from_IMFPresentationTimeSource(iface); UINT64 position, counter; + LONGLONG time; HRESULT hr; - TRACE("%p, %#lx, %p, %p.\n", iface, reserved, clock_time, system_time); - - if (!renderer->audio_clock) - return MF_E_NOT_INITIALIZED; - if (FAILED(hr = IAudioClock_GetPosition(renderer->audio_clock, &position, &counter))) return hr; - *clock_time = renderer->pts + (INT64)(position - renderer->position) * MFCLOCK_FREQUENCY_HNS / (INT64)renderer->audio_clock_frequency; - *system_time = counter; + time = renderer->pts + (INT64)(position - renderer->position) * MFCLOCK_FREQUENCY_HNS / (INT64)renderer->audio_clock_frequency; + if (renderer->flags & SAR_SEEKING) + { + if (time < renderer->seek_pts) + time = renderer->seek_pts; + else + renderer->flags &= ~SAR_SEEKING; + } + + if (clock_time) + *clock_time = time; + if (system_time) + *system_time = counter; return S_OK; } +static HRESULT WINAPI audio_renderer_time_source_GetCorrelatedTime(IMFPresentationTimeSource *iface, DWORD reserved, LONGLONG *clock_time, + MFTIME *system_time) +{ + struct audio_renderer *renderer = impl_from_IMFPresentationTimeSource(iface); + HRESULT hr; + + TRACE("%p, %#lx, %p, %p.\n", iface, reserved, clock_time, system_time); + + EnterCriticalSection(&renderer->cs); + if (!renderer->audio_clock) + hr = MF_E_NOT_INITIALIZED; + else + hr = audio_renderer_get_correlated_time(renderer, clock_time, system_time); + LeaveCriticalSection(&renderer->cs); + + return hr; +} + static HRESULT WINAPI audio_renderer_time_source_GetContinuityKey(IMFPresentationTimeSource *iface, DWORD *key) { TRACE("%p, %p.\n", iface, key); @@ -1525,6 +1556,11 @@ static HRESULT stream_queue_sample(struct audio_renderer *renderer, IMFSample *s sample_frames = sample_len / renderer->frame_size; + /* Discard samples that are prior to our seeking location */ + if (renderer->flags & SAR_SEEKING && start_time + + (LONGLONG)sample_frames * MFCLOCK_FREQUENCY_HNS / renderer->sample_rate < renderer->seek_pts) + return S_OK; + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY; @@ -2098,6 +2134,9 @@ static void audio_renderer_render(struct audio_renderer *renderer, IMFAsyncResul renderer->flags |= SAR_SAMPLE_REQUESTED; } + /* this is called to potentially remove the SAR_SEEKING flag */ + audio_renderer_get_correlated_time(renderer, NULL, NULL); + if (FAILED(hr = MFPutWaitingWorkItem(renderer->buffer_ready_event, 0, result, &renderer->buffer_ready_key))) WARN("Failed to submit wait item, hr %#lx.\n", hr); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10126