This fixes a bug where after a sync source is assigned to a filter graph, subsequent filters added to the graph are not given the assigned sync source. This behaviour is expected by the game "Nioh: The Complete Edition", where multiple videos are rendered using the same filter graph.
From: Shaun Ren sren@codeweavers.com
--- dlls/quartz/filtergraph.c | 22 ++++++++++++++------ dlls/quartz/tests/filtergraph.c | 37 ++++++++++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 9 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 437691b5553..21986e47f33 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -1708,6 +1708,19 @@ static void update_render_count(struct filter_graph *graph) } }
+static void update_sync_source(struct filter_graph *graph) +{ + struct filter *filter; + + if (graph->defaultclock && !graph->refClock) + IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface); + else + { + LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry) + IBaseFilter_SetSyncSource(filter->filter, graph->refClock); + } +} + /* Perform the paused -> running transition. The caller must hold graph->cs. */ static HRESULT graph_start(struct filter_graph *graph, REFERENCE_TIME stream_start) { @@ -1732,8 +1745,7 @@ static HRESULT graph_start(struct filter_graph *graph, REFERENCE_TIME stream_sta if (list_empty(&graph->media_events)) ResetEvent(graph->media_event_handle);
- if (graph->defaultclock && !graph->refClock) - IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface); + update_sync_source(graph);
if (!stream_start && graph->refClock) { @@ -1843,8 +1855,7 @@ static HRESULT WINAPI MediaControl_Run(IMediaControl *iface)
if (graph->state == State_Stopped) { - if (graph->defaultclock && !graph->refClock) - IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface); + update_sync_source(graph);
LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry) { @@ -5068,8 +5079,7 @@ static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) update_render_count(graph); LeaveCriticalSection(&graph->event_cs);
- if (graph->defaultclock && !graph->refClock) - IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface); + update_sync_source(graph);
if (graph->state == State_Running && !graph->needs_async_run && graph->refClock) { diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index d6ce9d31ce2..228b2e826bc 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -1458,8 +1458,13 @@ static HRESULT WINAPI testfilter_SetSyncSource(IBaseFilter *iface, IReferenceClo
static HRESULT WINAPI testfilter_GetSyncSource(IBaseFilter *iface, IReferenceClock **clock) { - ok(0, "Unexpected call.\n"); - return E_NOTIMPL; + struct testfilter *filter = impl_from_IBaseFilter(iface); + if (winetest_debug > 1) trace("%p->GetSyncSource(%p)\n", filter, clock); + + if (filter->clock) + IReferenceClock_AddRef(filter->clock); + *clock = filter->clock; + return S_OK; }
static HRESULT WINAPI testfilter_EnumPins(IBaseFilter *iface, IEnumPins **out) @@ -3405,7 +3410,7 @@ static void test_filter_state(void)
IFilterGraph2 *graph = create_graph(); REFERENCE_TIME start_time, time; - IReferenceClock *clock; + IReferenceClock *clock, *filter_clock; IMediaControl *control; IMediaSeeking *seeking; FILTER_STATE mf_state; @@ -3640,6 +3645,32 @@ static void test_filter_state(void) ok(hr == S_OK, "Got hr %#lx.\n", hr); check_filter_state(graph, State_Stopped);
+ /* Sync source should be set on all filters when the graph runs. */ + + hr = IFilterGraph2_AddFilter(graph, &dummy.IBaseFilter_iface, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + hr = IBaseFilter_GetSyncSource(&dummy.IBaseFilter_iface, &filter_clock); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(filter_clock == NULL, "Got filter_clock %p.\n", filter_clock); + + hr = IMediaControl_Run(control); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + check_filter_state(graph, State_Running); + + hr = IBaseFilter_GetSyncSource(&dummy.IBaseFilter_iface, &filter_clock); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(filter_clock == clock, "Expected fliter_clock %p, got %p.\n", clock, filter_clock); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + check_filter_state(graph, State_Stopped); + + hr = IFilterGraph2_RemoveFilter(graph, &dummy.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + IReferenceClock_Release(filter_clock); + /* Test removing the sync source. */
IReferenceClock_Release(clock);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=130507
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 00ADFFD4.
=== w7u_adm (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 009CFF04.
=== w7u_el (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 00AA6DE4.
=== w8 (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 021B42D4.
=== w8adm (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 01E542D4.
=== w864 (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 00B799E4.
=== w1064v1507 (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 00C6A5A4.
=== w1064v1809 (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 02E5588C.
=== w1064_tsign (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0327F264.
=== w10pro64 (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 02BD12CC.
=== w11pro64 (32 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 00C64E04.
=== w7pro64 (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000000C4FD98.
=== w864 (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000002827F68.
=== w1064v1507 (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000002807758.
=== w1064v1809 (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000002A61CF8.
=== w1064_2qxl (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000000B56E98.
=== w1064_adm (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000003141A58.
=== w1064_tsign (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000002AC9AE8.
=== w10pro64 (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000002CF8A28.
=== w10pro64_en_AE_u8 (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 00000000001DBE88.
=== w10pro64_ar (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000003A78988.
=== w10pro64_ja (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000002A45F58.
=== w10pro64_zh_CN (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 0000000000BEDF38.
=== w11pro64_amd (64 bit report) ===
quartz: filtergraph.c:3655: Test failed: Got filter_clock 000000000C2E50D8.