Some filters (e.g. MediaStreamFilter) can become renderers when they are already in the graph.
Signed-off-by: Anton Baskanov baskanov@gmail.com --- 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 a77a9165f5..c0014010d8 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -688,9 +688,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; }
@@ -763,9 +760,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) @@ -5168,6 +5162,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); @@ -5184,6 +5191,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);
@@ -5226,6 +5235,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 98b24c68d6..34d2722213 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -3462,10 +3462,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); @@ -3480,8 +3476,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");