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);