From e92c851d95497fbb36000be17f78b70ee3b2bf09 Mon Sep 17 00:00:00 2001 From: Anton Baskanov Date: Wed, 10 Jun 2020 23:09:07 +0700 Subject: [PATCH] quartz/filtergraph: Count renderers in IMediaControl::Pause and ::Run. Some filters (e.g. MediaStreamFilter) can become renderers when they are already in the graph. Signed-off-by: Anton Baskanov Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/quartz/filtergraph.c | 23 +++++++++++++++++------ dlls/quartz/tests/filtergraph.c | 11 +++++++---- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index b1968069b86..0d0ccc2b624 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -691,9 +691,6 @@ static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, entry->seeking = NULL; ++graph->version; - if (is_renderer(entry)) - ++graph->nRenderers; - return duplicate_name ? VFW_S_DUPLICATE_NAME : hr; } @@ -766,9 +763,6 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, NULL); if (SUCCEEDED(hr)) { - if (is_renderer(entry)) - --This->nRenderers; - IBaseFilter_SetSyncSource(pFilter, NULL); IBaseFilter_Release(pFilter); if (entry->seeking) @@ -5171,6 +5165,19 @@ static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface) return hr; } +static void update_render_count(IFilterGraphImpl *graph) +{ + /* Some filters (e.g. MediaStreamFilter) can become renderers when they are + * already in the graph. */ + struct filter *filter; + graph->nRenderers = 0; + LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry) + { + if (is_renderer(filter)) + ++graph->nRenderers; + } +} + static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) { IFilterGraphImpl *graph = impl_from_IMediaFilter(iface); @@ -5187,6 +5194,8 @@ static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) return S_OK; } + update_render_count(graph); + if (graph->defaultclock && !graph->refClock) IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface); @@ -5229,6 +5238,8 @@ static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME start) } graph->EcCompleteCount = 0; + update_render_count(graph); + if (graph->defaultclock && !graph->refClock) IFilterGraph2_SetDefaultSyncSource(&graph->IFilterGraph2_iface); diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index d1c081681a3..50c2402c326 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -3463,10 +3463,6 @@ static void test_ec_complete(void) testsource_init(&source_pins[2], NULL, 0); testfilter_init(&source, source_pins, 3); - filter1.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl; - filter2.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl; - filter1.misc_flags = filter2.misc_flags = AM_FILTER_MISC_FLAGS_IS_RENDERER; - IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control); IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc); IFilterGraph2_QueryInterface(graph, &IID_IMediaEventSink, (void **)&eventsink); @@ -3481,8 +3477,15 @@ static void test_ec_complete(void) /* EC_COMPLETE is only delivered to the user after all renderers deliver it. */ + filter1.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl; + filter2.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl; + filter3.IAMFilterMiscFlags_iface.lpVtbl = &testmiscflags_vtbl; + filter1.misc_flags = filter2.misc_flags = AM_FILTER_MISC_FLAGS_IS_RENDERER; + IMediaControl_Run(control); + filter3.misc_flags = AM_FILTER_MISC_FLAGS_IS_RENDERER; + while ((hr = IMediaEvent_GetEvent(eventsrc, &code, ¶m1, ¶m2, 0)) == S_OK) { ok(code != EC_COMPLETE, "Got unexpected EC_COMPLETE.\n");