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.
-- v2: quartz: Update sync source when running or pausing a filter graph.
From: Shaun Ren sren@codeweavers.com
--- dlls/quartz/filtergraph.c | 22 ++++++++++++++----- dlls/quartz/tests/filtergraph.c | 39 ++++++++++++++++++++++++++++++--- 2 files changed, 52 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..2459416ef51 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,34 @@ 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. */ + + IBaseFilter_SetSyncSource(&dummy.IBaseFilter_iface, NULL); + + 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=130525
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 01776DE4.
=== w7u_adm (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 01730A6C.
=== w7u_el (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00AB0A6C.
=== w8 (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 0A613194.
=== w8adm (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 02224264.
=== w864 (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00A999E4.
=== w1064v1507 (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 009DB454.
=== w1064v1809 (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00D454B4.
=== w1064_tsign (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 031C4684.
=== w10pro64 (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 032043F4.
=== w11pro64 (32 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00B05F6C.
=== w7pro64 (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00000000003AA4E8.
=== w864 (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00000000028C6E18.
=== w1064v1507 (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00000000027E7758.
=== w1064v1809 (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 0000000002A99A28.
=== w1064_2qxl (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00000000030B16B8.
=== w1064_adm (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 000000000304E038.
=== w1064_tsign (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00000000001F6E98.
=== w10pro64 (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 0000000000B9E318.
=== w10pro64_en_AE_u8 (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 0000000002A2D7F8.
=== w10pro64_ar (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 0000000002A297E8.
=== w10pro64_ja (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 0000000002AD6DA8.
=== w10pro64_zh_CN (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 0000000002C0F3C8.
=== w11pro64_amd (64 bit report) ===
quartz: filtergraph.c:3657: Test failed: Got filter_clock 00000000001004C8.
This merge request was closed by Shaun Ren.