From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gstdemux.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 1337cd0a81c..488c9bd8a13 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -1455,6 +1455,7 @@ static HRESULT gstdemux_cleanup_stream(struct strmbase_filter *iface) { struct gstdemux *filter = impl_from_strmbase_filter(iface); GstStateChangeReturn ret; + unsigned int i;
if (!filter->container) return S_OK; @@ -1468,6 +1469,12 @@ static HRESULT gstdemux_cleanup_stream(struct strmbase_filter *iface) gst_element_get_state(filter->container, NULL, NULL, GST_CLOCK_TIME_NONE); filter->ignore_flush = FALSE;
+ for (i = 0; i < filter->source_count; ++i) + { + if (filter->sources[i]->pin.pin.peer) + IMemAllocator_Decommit(filter->sources[i]->pin.pAllocator); + } + return S_OK; }
From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/strmbase/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 1f2154393d9..6b5a5e80e3e 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -88,7 +88,7 @@ static HRESULT renderer_init_stream(struct strmbase_filter *iface) if (filter->pFuncsTable->renderer_init_stream) filter->pFuncsTable->renderer_init_stream(filter);
- return S_OK; + return filter->sink.pin.peer ? S_FALSE : S_OK; }
static HRESULT renderer_start_stream(struct strmbase_filter *iface, REFERENCE_TIME start)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/filtergraph.c | 62 +++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 7 deletions(-)
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index b36605f3963..fd73a9ad837 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -2286,6 +2286,7 @@ todo_wine IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface); IFilterGraph2_Disconnect(graph, sink_pin.peer); IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface); + parser1_pins[1].QueryInternalConnections_hr = E_NOTIMPL;
/* A pin whose name (not ID) begins with a tilde is not connected. */
@@ -2316,6 +2317,14 @@ todo_wine IFilterGraph2_Disconnect(graph, sink_pin.peer); IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
+ hr = IFilterGraph2_Connect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface); + todo_wine ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr); + + parser1_pins[0].QueryInternalConnections_hr = S_OK; + hr = IFilterGraph2_Connect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + parser1_pins[0].QueryInternalConnections_hr = E_NOTIMPL; + ref = IFilterGraph2_Release(graph); ok(!ref, "Got outstanding refcount %d.\n", ref);
@@ -2763,25 +2772,28 @@ static const IPinVtbl test_connect_direct_vtbl =
static void test_connect_direct_init(struct testpin *pin, PIN_DIRECTION dir) { - memset(pin, 0, sizeof(*pin)); - pin->IPin_iface.lpVtbl = &test_connect_direct_vtbl; - pin->ref = 1; - pin->dir = dir; + testpin_init(pin, &test_connect_direct_vtbl, dir); }
static void test_connect_direct(void) { - struct testpin source_pin, sink_pin; - struct testfilter source, sink; + struct testpin source_pin, sink_pin, parser1_pins[2], parser2_pins[2]; + struct testfilter source, sink, parser1, parser2;
IFilterGraph2 *graph = create_graph(); AM_MEDIA_TYPE mt; HRESULT hr;
test_connect_direct_init(&source_pin, PINDIR_OUTPUT); - test_connect_direct_init(&sink_pin, PINDIR_INPUT); testfilter_init(&source, &source_pin, 1); + test_connect_direct_init(&sink_pin, PINDIR_INPUT); testfilter_init(&sink, &sink_pin, 1); + test_connect_direct_init(&parser1_pins[0], PINDIR_INPUT); + test_connect_direct_init(&parser1_pins[1], PINDIR_OUTPUT); + testfilter_init(&parser1, parser1_pins, 2); + test_connect_direct_init(&parser2_pins[0], PINDIR_INPUT); + test_connect_direct_init(&parser2_pins[1], PINDIR_OUTPUT); + testfilter_init(&parser2, parser2_pins, 2);
hr = IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -2935,6 +2947,42 @@ todo_wine hr = IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface); ok(hr == S_OK, "Got hr %#x.\n", hr);
+ /* ConnectDirect() protects against cyclical connections. */ + hr = IFilterGraph2_AddFilter(graph, &parser1.IBaseFilter_iface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_AddFilter(graph, &parser2.IBaseFilter_iface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IFilterGraph2_ConnectDirect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface, NULL); + ok(hr == VFW_E_CIRCULAR_GRAPH, "Got hr %#x.\n", hr); + + hr = IFilterGraph2_ConnectDirect(graph, &parser1_pins[1].IPin_iface, &parser2_pins[0].IPin_iface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_ConnectDirect(graph, &parser2_pins[1].IPin_iface, &parser1_pins[0].IPin_iface, NULL); + todo_wine ok(hr == VFW_E_CIRCULAR_GRAPH, "Got hr %#x.\n", hr); + IFilterGraph2_Disconnect(graph, &parser1_pins[1].IPin_iface); + IFilterGraph2_Disconnect(graph, &parser2_pins[0].IPin_iface); + + parser1_pins[0].QueryInternalConnections_hr = S_OK; + hr = IFilterGraph2_ConnectDirect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface, NULL); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!parser1_pins[0].peer, "Got peer %p.\n", parser1_pins[0].peer); + todo_wine ok(parser1_pins[1].peer == &parser1_pins[0].IPin_iface, "Got peer %p.\n", parser1_pins[1].peer); + IFilterGraph2_Disconnect(graph, &parser1_pins[0].IPin_iface); + IFilterGraph2_Disconnect(graph, &parser1_pins[1].IPin_iface); + + hr = IFilterGraph2_ConnectDirect(graph, &parser1_pins[1].IPin_iface, &parser2_pins[0].IPin_iface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_ConnectDirect(graph, &parser2_pins[1].IPin_iface, &parser1_pins[0].IPin_iface, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IFilterGraph2_Disconnect(graph, &parser1_pins[1].IPin_iface); + IFilterGraph2_Disconnect(graph, &parser2_pins[0].IPin_iface); + + hr = IFilterGraph2_RemoveFilter(graph, &parser1.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_RemoveFilter(graph, &parser2.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + /* Both pins are disconnected when a filter is removed. */ hr = IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, &mt); ok(hr == S_OK, "Got hr %#x.\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=65527
Your paranoid android.
=== debian10 (32 bit Chinese:China report) ===
quartz: filtergraph.c:4046: Test failed: Expected about 1334ms, got ef1af0. filtergraph.c:4051: Test failed: Expected about 1334ms, got ef1af0.
It will need to do some bookkeeping.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/filtergraph.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 60bea5542ff..46ae113a4bd 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -1123,7 +1123,7 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, goto out;
/* Try direct connection first */ - hr = IPin_Connect(ppinOut, ppinIn, NULL); + hr = IFilterGraph2_ConnectDirect(iface, ppinOut, ppinIn, NULL);
/* If direct connection succeeded, we should propagate that return value. * If it returned VFW_E_NOT_CONNECTED or VFW_E_NO_AUDIO_HARDWARE, then don't @@ -1279,7 +1279,7 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, goto error; }
- hr = IPin_Connect(ppinOut, ppinfilter, NULL); + hr = IFilterGraph2_ConnectDirect(iface, ppinOut, ppinfilter, NULL); if (FAILED(hr)) { TRACE("Cannot connect to filter (%x), trying next one\n", hr); goto error; @@ -1591,7 +1591,7 @@ static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut) }
/* Connect the pin to the "Renderer" */ - hr = IPin_Connect(ppinOut, ppinfilter, NULL); + hr = IFilterGraph2_ConnectDirect(iface, ppinOut, ppinfilter, NULL); IPin_Release(ppinfilter);
if (FAILED(hr)) {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/filtergraph.c | 87 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 46ae113a4bd..9e568224807 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include <assert.h> #include <stdarg.h>
#define COBJMACROS @@ -150,9 +151,10 @@ typedef struct _ITF_CACHE_ENTRY {
struct filter { - struct list entry; + struct list entry, sorted_entry; IBaseFilter *filter; WCHAR *name; + BOOL sorting; };
typedef struct _IFilterGraphImpl { @@ -183,8 +185,18 @@ typedef struct _IFilterGraphImpl { IUnknown *outer_unk; LONG ref; IUnknown *punkFilterMapper2; - struct list filters;
+ /* We keep two lists of filters, one unsorted and one topologically sorted. + * The former is necessary for functions like IGraphBuilder::Connect() and + * IGraphBuilder::Render() that iterate through the filter list but may + * add to it while doing so; the latter is for functions like + * IMediaControl::Run() that should propagate messages to all filters + * (including unconnected ones) but must do so in topological order from + * sinks to sources. We can easily guarantee that the loop in Connect() will + * touch each filter exactly once so long as we aren't reordering it, but + * using the sorted filters list there would be hard. This seems to be the + * easiest and clearest solution. */ + struct list filters, sorted_filters; unsigned int name_index;
IReferenceClock *refClock; @@ -617,6 +629,8 @@ static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface,
IBaseFilter_AddRef(entry->filter = filter); list_add_head(&graph->filters, &entry->entry); + list_add_head(&graph->sorted_filters, &entry->sorted_entry); + entry->sorting = FALSE; ++graph->version;
return duplicate_name ? VFW_S_DUPLICATE_NAME : hr; @@ -694,6 +708,7 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte IBaseFilter_SetSyncSource(pFilter, NULL); IBaseFilter_Release(pFilter); list_remove(&entry->entry); + list_remove(&entry->sorted_entry); CoTaskMemFree(entry->name); heap_free(entry); This->version++; @@ -818,6 +833,70 @@ out: #endif }
+static struct filter *find_sorted_filter(IFilterGraphImpl *graph, IBaseFilter *iface) +{ + struct filter *filter; + + LIST_FOR_EACH_ENTRY(filter, &graph->sorted_filters, struct filter, sorted_entry) + { + if (filter->filter == iface) + return filter; + } + + return NULL; +} + +static void sort_filter_recurse(IFilterGraphImpl *graph, struct filter *filter, struct list *sorted) +{ + struct filter *peer_filter; + IEnumPins *enumpins; + PIN_DIRECTION dir; + IPin *pin, *peer; + PIN_INFO info; + + TRACE("Sorting filter %p.\n", filter->filter); + + /* Cyclic connections should be caught by CheckCircularConnection(). */ + assert(!filter->sorting); + + filter->sorting = TRUE; + + IBaseFilter_EnumPins(filter->filter, &enumpins); + while (IEnumPins_Next(enumpins, 1, &pin, NULL) == S_OK) + { + IPin_QueryDirection(pin, &dir); + + if (dir == PINDIR_INPUT && IPin_ConnectedTo(pin, &peer) == S_OK) + { + IPin_QueryPinInfo(peer, &info); + /* Note that the filter may have already been sorted. */ + if ((peer_filter = find_sorted_filter(graph, info.pFilter))) + sort_filter_recurse(graph, peer_filter, sorted); + IBaseFilter_Release(info.pFilter); + IPin_Release(peer); + } + IPin_Release(pin); + } + IEnumPins_Release(enumpins); + + filter->sorting = FALSE; + + list_remove(&filter->sorted_entry); + list_add_head(sorted, &filter->sorted_entry); +} + +static void sort_filters(IFilterGraphImpl *graph) +{ + struct list sorted = LIST_INIT(sorted), *cursor; + + while ((cursor = list_head(&graph->sorted_filters))) + { + struct filter *filter = LIST_ENTRY(cursor, struct filter, sorted_entry); + sort_filter_recurse(graph, filter, &sorted); + } + + list_move_tail(&graph->sorted_filters, &sorted); +}
/* NOTE: despite the implication, it doesn't matter which * way round you put in the input and output pins */ @@ -869,6 +948,9 @@ static HRESULT WINAPI FilterGraph2_ConnectDirect(IFilterGraph2 *iface, IPin *ppi } }
+ if (SUCCEEDED(hr)) + sort_filters(This); + return hr; }
@@ -5702,6 +5784,7 @@ static HRESULT filter_graph_common_create(IUnknown *outer, void **out, BOOL thre fimpl->IGraphVersion_iface.lpVtbl = &IGraphVersion_VTable; fimpl->ref = 1; list_init(&fimpl->filters); + list_init(&fimpl->sorted_filters); fimpl->name_index = 1; fimpl->refClock = NULL; fimpl->hEventCompletion = CreateEventW(0, TRUE, FALSE, 0);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/filtergraph.c | 4 ---- dlls/quartz/tests/filtergraph.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 9e568224807..1e87f818588 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -1200,10 +1200,6 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut, ppinOut = temp; }
- hr = CheckCircularConnection(This, ppinOut, ppinIn); - if (FAILED(hr)) - goto out; - /* Try direct connection first */ hr = IFilterGraph2_ConnectDirect(iface, ppinOut, ppinIn, NULL);
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index fd73a9ad837..65fa4dac3b4 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -2318,7 +2318,7 @@ todo_wine IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
hr = IFilterGraph2_Connect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface); - todo_wine ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr); + ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr);
parser1_pins[0].QueryInternalConnections_hr = S_OK; hr = IFilterGraph2_Connect(graph, &parser1_pins[1].IPin_iface, &parser1_pins[0].IPin_iface);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qasf/tests/dmowrapper.c | 12 +- dlls/quartz/filtergraph.c | 310 +++++++++++------------------- dlls/quartz/tests/avisplit.c | 8 +- dlls/quartz/tests/filtergraph.c | 42 ++-- dlls/quartz/tests/videorenderer.c | 32 +-- dlls/quartz/tests/vmr7.c | 20 +- dlls/quartz/tests/vmr9.c | 20 +- 7 files changed, 178 insertions(+), 266 deletions(-)
diff --git a/dlls/qasf/tests/dmowrapper.c b/dlls/qasf/tests/dmowrapper.c index fe00536364c..42d3a4f0e0e 100644 --- a/dlls/qasf/tests/dmowrapper.c +++ b/dlls/qasf/tests/dmowrapper.c @@ -1227,21 +1227,21 @@ static void test_filter_state(IMediaControl *control) ok(state == State_Stopped, "Got state %u.\n", state);
hr = IMediaControl_Pause(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); ok(state == State_Paused, "Got state %u.\n", state);
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); ok(state == State_Running, "Got state %u.\n", state);
hr = IMediaControl_Pause(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -1250,7 +1250,7 @@ static void test_filter_state(IMediaControl *control) ok(!got_Flush, "Unexpected IMediaObject::Flush().\n"); hr = IMediaControl_Stop(control); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(got_Flush, "Expected IMediaObject::Flush().\n"); + ok(got_Flush, "Expected IMediaObject::Flush().\n"); got_Flush = 0;
hr = IMediaControl_GetState(control, 0, &state); @@ -1258,7 +1258,7 @@ static void test_filter_state(IMediaControl *control) ok(state == State_Stopped, "Got state %u.\n", state);
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -1267,7 +1267,7 @@ static void test_filter_state(IMediaControl *control) ok(!got_Flush, "Unexpected IMediaObject::Flush().\n"); hr = IMediaControl_Stop(control); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(got_Flush, "Expected IMediaObject::Flush().\n"); + ok(got_Flush, "Expected IMediaObject::Flush().\n"); got_Flush = 0;
hr = IMediaControl_GetState(control, 0, &state); diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 1e87f818588..5acd0729527 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -567,6 +567,51 @@ static IBaseFilter *find_filter_by_name(IFilterGraphImpl *graph, const WCHAR *na return NULL; }
+static BOOL has_output_pins(IBaseFilter *filter) +{ + IEnumPins *enumpins; + PIN_DIRECTION dir; + IPin *pin; + + if (FAILED(IBaseFilter_EnumPins(filter, &enumpins))) + return FALSE; + + while (IEnumPins_Next(enumpins, 1, &pin, NULL) == S_OK) + { + IPin_QueryDirection(pin, &dir); + IPin_Release(pin); + if (dir == PINDIR_OUTPUT) + { + IEnumPins_Release(enumpins); + return TRUE; + } + } + + IEnumPins_Release(enumpins); + return FALSE; +} + +static BOOL is_renderer(IBaseFilter *filter) +{ + IAMFilterMiscFlags *flags; + IMediaSeeking *seeking; + BOOL ret = FALSE; + + if (SUCCEEDED(IBaseFilter_QueryInterface(filter, &IID_IAMFilterMiscFlags, (void **)&flags))) + { + if (IAMFilterMiscFlags_GetMiscFlags(flags) & AM_FILTER_MISC_FLAGS_IS_RENDERER) + ret = TRUE; + IAMFilterMiscFlags_Release(flags); + } + else if (SUCCEEDED(IBaseFilter_QueryInterface(filter, &IID_IMediaSeeking, (void **)&seeking))) + { + IMediaSeeking_Release(seeking); + if (!has_output_pins(filter)) + ret = TRUE; + } + return ret; +} + /*** IFilterGraph methods ***/ static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, IBaseFilter *filter, const WCHAR *name) @@ -633,6 +678,9 @@ static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, entry->sorting = FALSE; ++graph->version;
+ if (is_renderer(filter)) + ++graph->nRenderers; + return duplicate_name ? VFW_S_DUPLICATE_NAME : hr; }
@@ -705,6 +753,9 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, NULL); if (SUCCEEDED(hr)) { + if (is_renderer(pFilter)) + --This->nRenderers; + IBaseFilter_SetSyncSource(pFilter, NULL); IBaseFilter_Release(pFilter); list_remove(&entry->entry); @@ -2025,184 +2076,6 @@ static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface, DISPID dispIdMem return S_OK; }
-typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *, DWORD_PTR data); - -static BOOL has_output_pins(IBaseFilter *filter) -{ - IEnumPins *enumpins; - PIN_DIRECTION dir; - IPin *pin; - - if (FAILED(IBaseFilter_EnumPins(filter, &enumpins))) - return FALSE; - - while (IEnumPins_Next(enumpins, 1, &pin, NULL) == S_OK) - { - IPin_QueryDirection(pin, &dir); - IPin_Release(pin); - if (dir == PINDIR_OUTPUT) - { - IEnumPins_Release(enumpins); - return TRUE; - } - } - - IEnumPins_Release(enumpins); - return FALSE; -} - -static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter, DWORD_PTR data) -{ - IAMFilterMiscFlags *flags; - IMediaSeeking *seeking; - IEnumPins *enumpins; - PIN_DIRECTION dir; - HRESULT hr; - IPin* pInputPin; - PIN_INFO PinInfo; - IPin *pin; - - TRACE("%p %p\n", pGraph, pOutputPin); - PinInfo.pFilter = NULL; - - hr = IPin_ConnectedTo(pOutputPin, &pInputPin); - - if (SUCCEEDED(hr)) - { - hr = IPin_QueryPinInfo(pInputPin, &PinInfo); - IPin_Release(pInputPin); - } - - if (SUCCEEDED(hr)) - hr = IBaseFilter_EnumPins(PinInfo.pFilter, &enumpins); - - if (SUCCEEDED(hr)) - { - while (IEnumPins_Next(enumpins, 1, &pin, NULL) == S_OK) - { - IPin_QueryDirection(pin, &dir); - if (dir == PINDIR_OUTPUT) - ExploreGraph(pGraph, pin, FoundFilter, data); - IPin_Release(pin); - } - - IEnumPins_Release(enumpins); - TRACE("Doing stuff with filter %p\n", PinInfo.pFilter); - - if (SUCCEEDED(IBaseFilter_QueryInterface(PinInfo.pFilter, - &IID_IAMFilterMiscFlags, (void **)&flags))) - { - if (IAMFilterMiscFlags_GetMiscFlags(flags) & AM_FILTER_MISC_FLAGS_IS_RENDERER) - pGraph->nRenderers++; - IAMFilterMiscFlags_Release(flags); - } - else if (SUCCEEDED(IBaseFilter_QueryInterface(PinInfo.pFilter, - &IID_IMediaSeeking, (void **)&seeking))) - { - if (!has_output_pins(PinInfo.pFilter)) - pGraph->nRenderers++; - IMediaSeeking_Release(seeking); - } - - FoundFilter(PinInfo.pFilter, data); - } - - if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter); - return hr; -} - -static HRESULT WINAPI SendRun(IBaseFilter *pFilter, DWORD_PTR data) -{ - REFERENCE_TIME time = *(REFERENCE_TIME*)data; - return IBaseFilter_Run(pFilter, time); -} - -static HRESULT WINAPI SendPause(IBaseFilter *pFilter, DWORD_PTR data) -{ - return IBaseFilter_Pause(pFilter); -} - -static HRESULT WINAPI SendStop(IBaseFilter *pFilter, DWORD_PTR data) -{ - return IBaseFilter_Stop(pFilter); -} - -static HRESULT WINAPI SendGetState(IBaseFilter *pFilter, DWORD_PTR data) -{ - FILTER_STATE state; - DWORD time_end = data; - DWORD time_now = GetTickCount(); - LONG wait; - - if (time_end == INFINITE) - { - wait = INFINITE; - } - else if (time_end > time_now) - { - wait = time_end - time_now; - } - else - wait = 0; - - return IBaseFilter_GetState(pFilter, wait, &state); -} - - -static HRESULT SendFilterMessage(IFilterGraphImpl *This, fnFoundFilter FoundFilter, DWORD_PTR data) -{ - struct filter *filter; - IEnumPins* pEnum; - HRESULT hr; - IPin* pPin; - DWORD dummy; - PIN_DIRECTION dir; - - TRACE("(%p)->()\n", This); - - /* Explorer the graph from source filters to renderers, determine renderers - * number and run filters from renderers to source filters */ - This->nRenderers = 0; - ResetEvent(This->hEventCompletion); - - LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry) - { - BOOL source = TRUE; - hr = IBaseFilter_EnumPins(filter->filter, &pEnum); - if (hr != S_OK) - { - WARN("Enum pins failed %x\n", hr); - continue; - } - /* Check if it is a source filter */ - while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK) - { - IPin_QueryDirection(pPin, &dir); - IPin_Release(pPin); - if (dir == PINDIR_INPUT) - { - source = FALSE; - break; - } - } - if (source) - { - TRACE("Found source filter %p.\n", filter->filter); - IEnumPins_Reset(pEnum); - while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK) - { - /* Explore the graph downstream from this pin */ - ExploreGraph(This, pPin, FoundFilter, data); - IPin_Release(pPin); - } - FoundFilter(filter->filter, data); - } - IEnumPins_Release(pEnum); - } - - return S_FALSE; -} - static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) { IFilterGraphImpl *graph = impl_from_IMediaControl(iface); @@ -5268,6 +5141,8 @@ static HRESULT WINAPI MediaFilter_GetClassID(IMediaFilter *iface, CLSID * pClass static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface) { IFilterGraphImpl *graph = impl_from_IMediaFilter(iface); + HRESULT hr = S_OK, filter_hr; + struct filter *filter;
TRACE("graph %p.\n", graph);
@@ -5280,8 +5155,22 @@ static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface) }
if (graph->state == State_Running) - SendFilterMessage(graph, SendPause, 0); - SendFilterMessage(graph, SendStop, 0); + { + LIST_FOR_EACH_ENTRY(filter, &graph->sorted_filters, struct filter, sorted_entry) + { + filter_hr = IBaseFilter_Pause(filter->filter); + if (hr == S_OK) + hr = filter_hr; + } + } + + LIST_FOR_EACH_ENTRY(filter, &graph->sorted_filters, struct filter, sorted_entry) + { + filter_hr = IBaseFilter_Stop(filter->filter); + if (hr == S_OK) + hr = filter_hr; + } + graph->state = State_Stopped;
/* Update the current position, probably to synchronize multiple streams. */ @@ -5289,12 +5178,14 @@ static HRESULT WINAPI MediaFilter_Stop(IMediaFilter *iface) AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
LeaveCriticalSection(&graph->cs); - return S_OK; + return hr; }
static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) { IFilterGraphImpl *graph = impl_from_IMediaFilter(iface); + HRESULT hr = S_OK, filter_hr; + struct filter *filter;
TRACE("graph %p.\n", graph);
@@ -5317,17 +5208,25 @@ static HRESULT WINAPI MediaFilter_Pause(IMediaFilter *iface) graph->current_pos += graph->stream_elapsed; }
- SendFilterMessage(graph, SendPause, 0); + LIST_FOR_EACH_ENTRY(filter, &graph->sorted_filters, struct filter, sorted_entry) + { + filter_hr = IBaseFilter_Pause(filter->filter); + if (hr == S_OK) + hr = filter_hr; + } + graph->state = State_Paused;
LeaveCriticalSection(&graph->cs); - return S_FALSE; + return hr; }
static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME start) { IFilterGraphImpl *graph = impl_from_IMediaFilter(iface); REFERENCE_TIME stream_start = start; + HRESULT hr = S_OK, filter_hr; + struct filter *filter;
TRACE("graph %p, start %s.\n", graph, debugstr_time(start));
@@ -5351,17 +5250,25 @@ static HRESULT WINAPI MediaFilter_Run(IMediaFilter *iface, REFERENCE_TIME start) stream_start += 500000; }
- SendFilterMessage(graph, SendRun, (DWORD_PTR)&stream_start); + LIST_FOR_EACH_ENTRY(filter, &graph->sorted_filters, struct filter, sorted_entry) + { + filter_hr = IBaseFilter_Run(filter->filter, stream_start); + if (hr == S_OK) + hr = filter_hr; + } + graph->state = State_Running;
LeaveCriticalSection(&graph->cs); - return S_FALSE; + return hr; }
static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD timeout, FILTER_STATE *state) { IFilterGraphImpl *graph = impl_from_IMediaFilter(iface); - DWORD end; + DWORD end = GetTickCount() + timeout; + HRESULT hr = S_OK, filter_hr; + struct filter *filter;
TRACE("graph %p, timeout %u, state %p.\n", graph, timeout, state);
@@ -5371,17 +5278,30 @@ static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD timeout, F EnterCriticalSection(&graph->cs);
*state = graph->state; - if (timeout > 0) - end = GetTickCount() + timeout; - else if (timeout == INFINITE) - end = INFINITE; - else - end = 0; - if (end) - SendFilterMessage(graph, SendGetState, end); + + LIST_FOR_EACH_ENTRY(filter, &graph->sorted_filters, struct filter, sorted_entry) + { + FILTER_STATE filter_state; + int wait; + + if (timeout == INFINITE) + wait = INFINITE; + else if (!timeout) + wait = 0; + else + wait = max(end - GetTickCount(), 0); + + filter_hr = IBaseFilter_GetState(filter->filter, wait, &filter_state); + if (hr == S_OK && filter_hr == VFW_S_STATE_INTERMEDIATE) + hr = VFW_S_STATE_INTERMEDIATE; + else if (filter_hr != S_OK && filter_hr != VFW_S_STATE_INTERMEDIATE) + hr = filter_hr; + if (filter_state != graph->state) + WARN("Filter %p reported incorrect state %u.\n", filter->filter, filter_state); + }
LeaveCriticalSection(&graph->cs); - return S_OK; + return hr; }
static HRESULT WINAPI MediaFilter_SetSyncSource(IMediaFilter *iface, IReferenceClock *pClock) diff --git a/dlls/quartz/tests/avisplit.c b/dlls/quartz/tests/avisplit.c index 002966d276c..ae621e43126 100644 --- a/dlls/quartz/tests/avisplit.c +++ b/dlls/quartz/tests/avisplit.c @@ -1025,21 +1025,21 @@ static void test_filter_state(IMediaControl *control) ok(state == State_Stopped, "Got state %u.\n", state);
hr = IMediaControl_Pause(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); ok(state == State_Paused, "Got state %u.\n", state);
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); ok(state == State_Running, "Got state %u.\n", state);
hr = IMediaControl_Pause(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -1053,7 +1053,7 @@ static void test_filter_state(IMediaControl *control) ok(state == State_Stopped, "Got state %u.\n", state);
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 65fa4dac3b4..01152c214a3 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -3104,8 +3104,8 @@ static void check_filter_state_(unsigned int line, IFilterGraph2 *graph, FILTER_
static void test_filter_state(void) { + struct testfilter source, sink, dummy; struct testpin source_pin, sink_pin; - struct testfilter source, sink;
IFilterGraph2 *graph = create_graph(); REFERENCE_TIME start_time; @@ -3120,6 +3120,7 @@ static void test_filter_state(void) testsink_init(&sink_pin); testfilter_init(&source, &source_pin, 1); testfilter_init(&sink, &sink_pin, 1); + testfilter_init(&dummy, NULL, 0);
IFilterGraph2_QueryInterface(graph, &IID_IMediaFilter, (void **)&filter); IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control); @@ -3129,12 +3130,12 @@ static void test_filter_state(void)
IFilterGraph2_AddFilter(graph, &source.IBaseFilter_iface, NULL); IFilterGraph2_AddFilter(graph, &sink.IBaseFilter_iface, NULL); + IFilterGraph2_AddFilter(graph, &dummy.IBaseFilter_iface, NULL); IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, NULL);
check_filter_state(graph, State_Stopped);
hr = IMediaControl_Pause(control); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Paused);
@@ -3149,7 +3150,6 @@ todo_wine hr = IReferenceClock_GetTime(clock, &start_time); ok(SUCCEEDED(hr), "Got hr %#x.\n", hr); hr = IMediaControl_Run(control); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Running); ok(source.start_time >= start_time && source.start_time < start_time + 500 * 10000, @@ -3159,7 +3159,6 @@ todo_wine wine_dbgstr_longlong(source.start_time), wine_dbgstr_longlong(sink.start_time));
hr = IMediaControl_Pause(control); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Paused);
@@ -3168,7 +3167,6 @@ todo_wine check_filter_state(graph, State_Stopped);
hr = IMediaControl_Run(control); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Running);
@@ -3192,7 +3190,6 @@ todo_wine IFilterGraph2_ConnectDirect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface, NULL);
hr = IMediaFilter_Pause(filter); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Paused);
@@ -3203,25 +3200,23 @@ todo_wine ok(sink.clock == clock, "Expected %p, got %p.\n", clock, sink.clock);
hr = IMediaFilter_Run(filter, 0xdeadbeef); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Running); ok(source.start_time == 0xdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(source.start_time)); ok(sink.start_time == 0xdeadbeef, "Got time %s.\n", wine_dbgstr_longlong(sink.start_time));
hr = IMediaFilter_Pause(filter); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Paused);
hr = IMediaFilter_Run(filter, 0xdeadf00d); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Running); ok(source.start_time == 0xdeadf00d, "Got time %s.\n", wine_dbgstr_longlong(source.start_time)); ok(sink.start_time == 0xdeadf00d, "Got time %s.\n", wine_dbgstr_longlong(sink.start_time));
hr = IMediaFilter_Pause(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Paused);
hr = IMediaFilter_Stop(filter); @@ -3231,7 +3226,6 @@ todo_wine hr = IReferenceClock_GetTime(clock, &start_time); ok(SUCCEEDED(hr), "Got hr %#x.\n", hr); hr = IMediaFilter_Run(filter, 0); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Running); ok(source.start_time >= start_time && source.start_time < start_time + 500 * 10000, @@ -3242,11 +3236,11 @@ todo_wine
Sleep(600); hr = IMediaFilter_Pause(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Paused);
hr = IMediaFilter_Run(filter, 0); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Running); ok(source.start_time >= start_time && source.start_time < start_time + 500 * 10000, "Expected time near %s, got %s.\n", @@ -3255,13 +3249,13 @@ todo_wine wine_dbgstr_longlong(source.start_time), wine_dbgstr_longlong(sink.start_time));
hr = IMediaFilter_Pause(filter); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Paused); Sleep(600);
start_time += 550 * 10000; hr = IMediaFilter_Run(filter, 0); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Running); ok(source.start_time >= start_time && source.start_time < start_time + 500 * 10000, "Expected time near %s, got %s.\n", @@ -3279,7 +3273,6 @@ todo_wine IMediaFilter_SetSyncSource(filter, NULL);
hr = IMediaControl_Run(control); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Running); todo_wine @@ -3298,24 +3291,24 @@ todo_wine
sink.state_hr = VFW_S_STATE_INTERMEDIATE; hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); ok(state == State_Paused, "Got state %u.\n", state);
sink.state_hr = VFW_S_CANT_CUE; hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_CANT_CUE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_CANT_CUE, "Got hr %#x.\n", hr); ok(state == State_Paused, "Got state %u.\n", state);
sink.state_hr = VFW_S_STATE_INTERMEDIATE; source.state_hr = VFW_S_CANT_CUE; hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_CANT_CUE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_CANT_CUE, "Got hr %#x.\n", hr); ok(state == State_Paused, "Got state %u.\n", state);
sink.state_hr = VFW_S_CANT_CUE; source.state_hr = VFW_S_STATE_INTERMEDIATE; hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_CANT_CUE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_CANT_CUE, "Got hr %#x.\n", hr); ok(state == State_Paused, "Got state %u.\n", state);
sink.state_hr = source.state_hr = S_OK; @@ -3323,7 +3316,6 @@ todo_wine /* Destroying the graph while it's running stops all filters. */
hr = IMediaFilter_Run(filter, 0); -todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); check_filter_state(graph, State_Running); todo_wine @@ -3993,7 +3985,7 @@ static void test_graph_seeking(void) * SetPositions() and then adds the clock offset to the stream start. */
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
/* Note that if the graph is running, it is paused while seeking. */ current = 0; @@ -4035,11 +4027,11 @@ static void test_graph_seeking(void) ok(stop == 8000 * 10000, "Got time %s.\n", wine_dbgstr_longlong(stop));
hr = IMediaControl_Pause(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
Sleep(100); hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaSeeking_GetCurrentPosition(seeking, &time); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -4062,7 +4054,7 @@ static void test_graph_seeking(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
Sleep(100); hr = IMediaSeeking_GetCurrentPosition(seeking, &time); diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c index fcb5f3d2277..356cfe96e4c 100644 --- a/dlls/quartz/tests/videorenderer.c +++ b/dlls/quartz/tests/videorenderer.c @@ -679,7 +679,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
thread = send_frame(input);
@@ -712,7 +712,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
thread = send_frame(input);
@@ -722,7 +722,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -735,7 +735,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_Pause(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); @@ -748,7 +748,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -757,7 +757,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_Pause(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); @@ -772,10 +772,10 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
hr = IMediaControl_Run(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); @@ -837,7 +837,7 @@ static void test_flushing(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = join_thread(thread); ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -872,7 +872,7 @@ static void test_sample_time(IPin *pin, IMemInputPin *input, IFilterGraph2 *grap ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
thread = send_frame_time(input, 1, 0x11); /* dark blue */
@@ -882,7 +882,7 @@ static void test_sample_time(IPin *pin, IMemInputPin *input, IFilterGraph2 *grap ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(WaitForSingleObject(thread, 500) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
@@ -984,7 +984,7 @@ static void test_eos(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) todo_wine ok(hr == E_UNEXPECTED, "Got hr %#x.\n", hr);
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); ret = check_ec_complete(eventsrc, 0); todo_wine ok(ret == 1, "Expected EC_COMPLETE.\n");
@@ -997,7 +997,7 @@ static void test_eos(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) * done rendering. */
hr = IMediaControl_Run(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); hr = join_thread(send_frame(input)); ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMediaControl_GetState(control, 1000, &state); @@ -1020,7 +1020,7 @@ static void test_eos(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) /* Test sending EOS while flushing. */
hr = IMediaControl_Run(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); hr = join_thread(send_frame(input)); ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -1039,7 +1039,7 @@ static void test_eos(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) /* Test sending EOS and then flushing or stopping. */
hr = IMediaControl_Run(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); hr = join_thread(send_frame(input)); ok(hr == S_OK, "Got hr %#x.\n", hr); hr = IMediaControl_GetState(control, 1000, &state); @@ -1133,7 +1133,7 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input, }
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); join_thread(thread);
hr = IBasicVideo_GetCurrentImage(video, &size, buffer); diff --git a/dlls/quartz/tests/vmr7.c b/dlls/quartz/tests/vmr7.c index 3357a3b6577..19a89de5737 100644 --- a/dlls/quartz/tests/vmr7.c +++ b/dlls/quartz/tests/vmr7.c @@ -1031,7 +1031,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
thread = send_frame(input);
@@ -1064,7 +1064,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
thread = send_frame(input);
@@ -1074,7 +1074,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -1087,7 +1087,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_Pause(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); @@ -1100,7 +1100,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -1109,7 +1109,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_Pause(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); @@ -1127,10 +1127,10 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
hr = IMediaControl_Run(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); @@ -1199,7 +1199,7 @@ static void test_flushing(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = join_thread(thread); ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -1304,7 +1304,7 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input, }
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); join_thread(thread);
size = sizeof(buffer); diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c index 85304fce41c..387f4f0a93e 100644 --- a/dlls/quartz/tests/vmr9.c +++ b/dlls/quartz/tests/vmr9.c @@ -1035,7 +1035,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
thread = send_frame(input);
@@ -1068,7 +1068,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
thread = send_frame(input);
@@ -1078,7 +1078,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -1091,7 +1091,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_Pause(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); @@ -1104,7 +1104,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -1113,7 +1113,7 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IMediaControl_Pause(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); @@ -1131,10 +1131,10 @@ static void test_filter_state(IMemInputPin *input, IFilterGraph2 *graph) ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); - todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); + ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr);
hr = IMediaControl_Run(control); - ok(hr == S_FALSE, "Got hr %#x.\n", hr); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IMediaControl_GetState(control, 0, &state); todo_wine ok(hr == VFW_S_STATE_INTERMEDIATE, "Got hr %#x.\n", hr); @@ -1203,7 +1203,7 @@ static void test_flushing(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "Thread should block in Receive().\n");
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); hr = join_thread(thread); ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -1305,7 +1305,7 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input, }
hr = IMediaControl_Run(control); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); join_thread(thread);
size = sizeof(buffer);