From: Zebediah Figura Subject: [PATCH v2 3/5] quartz/filtergraph: Correctly implement IMediaSeeking::GetStopPosition(). Message-Id: <20191019154825.8314-3-z.figura12@gmail.com> Date: Sat, 19 Oct 2019 10:48:23 -0500 In-Reply-To: <20191019154825.8314-1-z.figura12@gmail.com> References: <20191019154825.8314-1-z.figura12@gmail.com> Signed-off-by: Zebediah Figura --- dlls/quartz/filtergraph.c | 43 ++++++++++++++++++++++++--------- dlls/quartz/tests/filtergraph.c | 14 +++++------ 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 9d60d4332b..024f0bd1a5 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -2466,24 +2466,43 @@ static HRESULT WINAPI MediaSeeking_GetDuration(IMediaSeeking *iface, LONGLONG *p return hr; } -static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface, LONGLONG *pStop) +static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop) { - IFilterGraphImpl *This = impl_from_IMediaSeeking(iface); - HRESULT hr = S_OK; + IFilterGraphImpl *graph = impl_from_IMediaSeeking(iface); + HRESULT hr = E_NOTIMPL, filter_hr; + IMediaSeeking *seeking; + struct filter *filter; + LONGLONG filter_stop; - TRACE("(%p/%p)->(%p)\n", This, iface, pStop); + TRACE("graph %p, stop %p.\n", graph, stop); - if (!pStop) + if (!stop) return E_POINTER; - EnterCriticalSection(&This->cs); - if (This->stop_position < 0) - /* Stop position not set, use duration instead */ - hr = IMediaSeeking_GetDuration(iface, pStop); - else - *pStop = This->stop_position; - LeaveCriticalSection(&This->cs); + *stop = 0; + EnterCriticalSection(&graph->cs); + + LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry) + { + if (FAILED(IBaseFilter_QueryInterface(filter->filter, &IID_IMediaSeeking, (void **)&seeking))) + continue; + + filter_hr = IMediaSeeking_GetStopPosition(seeking, &filter_stop); + IMediaSeeking_Release(seeking); + if (SUCCEEDED(filter_hr)) + { + hr = S_OK; + *stop = max(*stop, filter_stop); + } + else if (filter_hr != E_NOTIMPL) + { + LeaveCriticalSection(&graph->cs); + return filter_hr; + } + } + + LeaveCriticalSection(&graph->cs); return hr; } diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 386e87086a..2ec9c52e47 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -3788,31 +3788,31 @@ static void test_graph_seeking(void) filter2.seek_stop = 0x65432; hr = IMediaSeeking_GetStopPosition(seeking, &time); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(time == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(time)); + ok(time == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(time)); filter2.seek_stop = 0x54321; filter1.seek_stop = 0x65432; hr = IMediaSeeking_GetStopPosition(seeking, &time); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(time == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(time)); + ok(time == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(time)); filter1.seek_hr = filter2.seek_hr = 0xbeef; hr = IMediaSeeking_GetStopPosition(seeking, &time); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(time == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(time)); + ok(time == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(time)); filter1.seek_hr = E_NOTIMPL; hr = IMediaSeeking_GetStopPosition(seeking, &time); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(time == 0x54321, "Got time %s.\n", wine_dbgstr_longlong(time)); + ok(time == 0x54321, "Got time %s.\n", wine_dbgstr_longlong(time)); filter1.seek_hr = 0xdeadbeef; hr = IMediaSeeking_GetStopPosition(seeking, &time); - todo_wine ok(hr == 0xdeadbeef, "Got hr %#x.\n", hr); + ok(hr == 0xdeadbeef, "Got hr %#x.\n", hr); filter1.seek_hr = filter2.seek_hr = E_NOTIMPL; hr = IMediaSeeking_GetStopPosition(seeking, &time); - todo_wine ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr); filter1.seek_hr = filter2.seek_hr = S_OK; hr = IMediaSeeking_GetCurrentPosition(seeking, &time); @@ -3823,7 +3823,7 @@ static void test_graph_seeking(void) hr = IMediaSeeking_GetPositions(seeking, ¤t, &stop); ok(hr == S_OK, "Got hr %#x.\n", hr); ok(!current, "Got time %s.\n", wine_dbgstr_longlong(current)); - todo_wine ok(stop == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(stop)); + ok(stop == 0x65432, "Got time %s.\n", wine_dbgstr_longlong(stop)); current = 0x123; stop = 0x321; -- 2.20.1