From 627b6b29cd083208ccf0c4f8403a450432e523ab Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Sat, 21 Nov 2020 15:25:02 -0600 Subject: [PATCH] quartz: Correct return value handling in IMediaSeeking::GetDuration(). Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/quartz/filtergraph.c | 57 +++++++++++++++++++-------------- dlls/quartz/tests/filtergraph.c | 4 +-- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index b3aebabbdad..fb0890fda1f 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -2237,36 +2237,45 @@ static HRESULT WINAPI MediaSeeking_SetTimeFormat(IMediaSeeking *iface, const GUI return S_OK; } -static HRESULT WINAPI FoundDuration(struct filter_graph *This, IMediaSeeking *seek, DWORD_PTR pduration) +static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface, LONGLONG *duration) { - HRESULT hr; - LONGLONG duration = 0, *pdur = (LONGLONG*)pduration; + struct filter_graph *graph = impl_from_IMediaSeeking(iface); + HRESULT hr = E_NOTIMPL, filter_hr; + LONGLONG filter_duration; + struct filter *filter; - hr = IMediaSeeking_GetDuration(seek, &duration); - if (FAILED(hr)) - return hr; + TRACE("graph %p, duration %p.\n", graph, duration); - if (*pdur < duration) - *pdur = duration; - return hr; -} - -static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface, LONGLONG *pDuration) -{ - struct filter_graph *This = impl_from_IMediaSeeking(iface); - HRESULT hr; - - TRACE("(%p/%p)->(%p)\n", This, iface, pDuration); - - if (!pDuration) + if (!duration) return E_POINTER; - EnterCriticalSection(&This->cs); - *pDuration = 0; - hr = all_renderers_seek(This, FoundDuration, (DWORD_PTR)pDuration); - LeaveCriticalSection(&This->cs); + *duration = 0; - TRACE("--->%08x\n", hr); + EnterCriticalSection(&graph->cs); + + LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry) + { + update_seeking(filter); + if (!filter->seeking) + continue; + + filter_hr = IMediaSeeking_GetDuration(filter->seeking, &filter_duration); + if (SUCCEEDED(filter_hr)) + { + hr = S_OK; + *duration = max(*duration, filter_duration); + } + else if (filter_hr != E_NOTIMPL) + { + LeaveCriticalSection(&graph->cs); + return filter_hr; + } + } + + LeaveCriticalSection(&graph->cs); + + TRACE("Returning hr %#x, duration %s (%s seconds).\n", hr, + wine_dbgstr_longlong(*duration), debugstr_time(*duration)); return hr; } diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 853155ab100..b6e68f3f6b9 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -4401,13 +4401,13 @@ static void test_graph_seeking(void) filter1.seek_hr = filter2.seek_hr = 0xbeef; hr = IMediaSeeking_GetDuration(seeking, &time); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); ok(time == 0x23456, "Got time %s.\n", wine_dbgstr_longlong(time)); filter1.seek_hr = E_NOTIMPL; filter2.seek_hr = S_OK; hr = IMediaSeeking_GetDuration(seeking, &time); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); ok(time == 0x12345, "Got time %s.\n", wine_dbgstr_longlong(time)); filter1.seek_hr = 0xdeadbeef;