Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/videorenderer.c | 139 ++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+)
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c index 3919b419e14..112b4bd309d 100644 --- a/dlls/quartz/tests/videorenderer.c +++ b/dlls/quartz/tests/videorenderer.c @@ -991,6 +991,144 @@ static void test_sample_time(IPin *pin, IMemInputPin *input, IFilterGraph2 *grap IMediaControl_Release(control); }
+static unsigned int check_ec_complete(IMediaEvent *eventsrc) +{ + unsigned int ret = FALSE; + LONG_PTR param1, param2; + HRESULT hr; + LONG code; + + while ((hr = IMediaEvent_GetEvent(eventsrc, &code, ¶m1, ¶m2, 50)) == S_OK) + { + if (code == EC_COMPLETE) + { + ok(param1 == S_OK, "Got param1 %#lx.\n", param1); + ok(!param2, "Got param2 %#lx.\n", param2); + ret++; + } + IMediaEvent_FreeEventParams(eventsrc, code, param1, param2); + } + ok(hr == E_ABORT, "Got hr %#x.\n", hr); + + return ret; +} + +static void test_eos(IPin *pin, IMemInputPin *input, IFilterGraph2 *graph) +{ + IMediaControl *control; + IMediaEvent *eventsrc; + OAFilterState state; + HRESULT hr; + BOOL ret; + + IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control); + IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc); + + hr = IMediaControl_Pause(control); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + ok(!ret, "Got unexpected EC_COMPLETE.\n"); + + hr = IPin_EndOfStream(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_GetState(control, 1000, &state); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n"); + + hr = join_thread(send_frame(input)); + 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); + ret = check_ec_complete(eventsrc); + todo_wine ok(ret == 1, "Expected EC_COMPLETE.\n"); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + ok(!ret, "Got unexpected EC_COMPLETE.\n"); + + /* We do not receive an EC_COMPLETE notification until the last sample is + * done rendering. */ + + hr = IMediaControl_Run(control); + 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); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + ok(!ret, "Got unexpected EC_COMPLETE.\n"); + + hr = IPin_EndOfStream(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n"); + Sleep(1000); + ret = check_ec_complete(eventsrc); + todo_wine ok(ret == 1, "Expected EC_COMPLETE.\n"); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + ok(!ret, "Got unexpected EC_COMPLETE.\n"); + + /* Test sending EOS while flushing. */ + + hr = IMediaControl_Run(control); + 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 = IPin_BeginFlush(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_EndOfStream(pin); + todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + hr = IPin_EndFlush(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n"); + + /* Test sending EOS and then flushing or stopping. */ + + hr = IMediaControl_Run(control); + 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); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_EndOfStream(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + todo_wine ok(!ret, "Got unexpected EC_COMPLETE.\n"); + + hr = IPin_BeginFlush(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_EndFlush(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = join_thread(send_frame(input)); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IPin_EndOfStream(pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + ok(!ret, "Got unexpected EC_COMPLETE.\n"); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = check_ec_complete(eventsrc); + ok(!ret, "Got unexpected EC_COMPLETE.\n"); + + IMediaEvent_Release(eventsrc); + IMediaControl_Release(control); +} + static void test_connect_pin(void) { VIDEOINFOHEADER vih = @@ -1097,6 +1235,7 @@ static void test_connect_pin(void) test_filter_state(input, graph); test_flushing(pin, input, graph); test_sample_time(pin, input, graph); + test_eos(pin, input, graph);
hr = IFilterGraph2_Disconnect(graph, pin); ok(hr == S_OK, "Got hr %#x.\n", hr);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/renderer.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-)
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 038cb48b57b..1de974a9093 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -420,7 +420,6 @@ HRESULT WINAPI BaseRendererImpl_Stop(IBaseFilter * iface)
HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart) { - HRESULT hr = S_OK; BaseRenderer *This = impl_from_IBaseFilter(iface); TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart));
@@ -435,30 +434,18 @@ HRESULT WINAPI BaseRendererImpl_Run(IBaseFilter * iface, REFERENCE_TIME tStart) { This->sink.end_of_stream = FALSE; } - else if (This->filter.filterInfo.pGraph) - { - IMediaEventSink *pEventSink; - hr = IFilterGraph_QueryInterface(This->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink); - if (SUCCEEDED(hr)) - { - hr = IMediaEventSink_Notify(pEventSink, EC_COMPLETE, S_OK, (LONG_PTR)This); - IMediaEventSink_Release(pEventSink); - } - hr = S_OK; - } - if (SUCCEEDED(hr)) - { - QualityControlRender_Start(This->qcimpl, This->filter.rtStreamStart); - if (This->sink.pin.peer && This->pFuncsTable->renderer_start_stream) - This->pFuncsTable->renderer_start_stream(This); - if (This->filter.state == State_Stopped) - BaseRendererImpl_ClearPendingSample(This); - This->filter.state = State_Running; - } + + QualityControlRender_Start(This->qcimpl, This->filter.rtStreamStart); + if (This->sink.pin.peer && This->pFuncsTable->renderer_start_stream) + This->pFuncsTable->renderer_start_stream(This); + if (This->filter.state == State_Stopped) + BaseRendererImpl_ClearPendingSample(This); + This->filter.state = State_Running; + out: LeaveCriticalSection(&This->csRenderLock);
- return hr; + return S_OK; }
HRESULT WINAPI BaseRendererImpl_Pause(IBaseFilter * iface)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/renderer.c | 5 +++++ include/wine/strmbase.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 1de974a9093..25534154e95 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -220,6 +220,11 @@ static HRESULT sink_query_accept(struct strmbase_pin *pin, const AM_MEDIA_TYPE * static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out) { BaseRenderer *filter = impl_from_IPin(&iface->IPin_iface); + HRESULT hr; + + if (filter->pFuncsTable->renderer_pin_query_interface + && SUCCEEDED(hr = filter->pFuncsTable->renderer_pin_query_interface(filter, iid, out))) + return hr;
if (IsEqualGUID(iid, &IID_IMemInputPin)) *out = &filter->sink.IMemInputPin_iface; diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 6a358decfc7..5eaf204f471 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -574,6 +574,7 @@ typedef struct BaseRendererFuncTable { BaseRenderer_EndFlush pfnEndFlush; void (*renderer_destroy)(BaseRenderer *iface); HRESULT (*renderer_query_interface)(BaseRenderer *iface, REFIID iid, void **out); + HRESULT (*renderer_pin_query_interface)(BaseRenderer *iface, REFIID iid, void **out); } BaseRendererFuncTable;
HRESULT WINAPI BaseRendererImpl_Receive(BaseRenderer *This, IMediaSample * pSample);
This is not used by any application I know of, but is useful for testing.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/videorenderer.c | 2 +- dlls/quartz/videorenderer.c | 118 ++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 1 deletion(-)
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c index 112b4bd309d..1343f85e5e6 100644 --- a/dlls/quartz/tests/videorenderer.c +++ b/dlls/quartz/tests/videorenderer.c @@ -102,7 +102,7 @@ static void test_interfaces(void) IBaseFilter_FindPin(filter, sink_id, &pin);
check_interface(pin, &IID_IMemInputPin, TRUE); - todo_wine check_interface(pin, &IID_IOverlay, TRUE); + check_interface(pin, &IID_IOverlay, TRUE); check_interface(pin, &IID_IPin, TRUE); todo_wine check_interface(pin, &IID_IPinConnection, TRUE); todo_wine check_interface(pin, &IID_IQualityControl, TRUE); diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c index a7b3159ebcc..e2d80642d2e 100644 --- a/dlls/quartz/videorenderer.c +++ b/dlls/quartz/videorenderer.c @@ -42,6 +42,8 @@ typedef struct VideoRendererImpl BaseControlWindow baseControlWindow; BaseControlVideo baseControlVideo;
+ IOverlay IOverlay_iface; + BOOL init; HANDLE hThread;
@@ -401,6 +403,19 @@ static HRESULT video_renderer_query_interface(BaseRenderer *iface, REFIID iid, v return S_OK; }
+static HRESULT video_renderer_pin_query_interface(BaseRenderer *iface, REFIID iid, void **out) +{ + VideoRendererImpl *filter = impl_from_BaseRenderer(iface); + + if (IsEqualGUID(iid, &IID_IOverlay)) + *out = &filter->IOverlay_iface; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + static void video_renderer_stop_stream(BaseRenderer *iface) { VideoRendererImpl *This = impl_from_BaseRenderer(iface); @@ -475,6 +490,7 @@ static const BaseRendererFuncTable BaseFuncTable = .pfnEndFlush = VideoRenderer_EndFlush, .renderer_destroy = video_renderer_destroy, .renderer_query_interface = video_renderer_query_interface, + .renderer_pin_query_interface = video_renderer_pin_query_interface, };
static const BaseWindowFuncTable renderer_BaseWindowFuncTable = { @@ -783,6 +799,106 @@ static const IVideoWindowVtbl IVideoWindow_VTable = BaseControlWindowImpl_IsCursorHidden };
+static inline VideoRendererImpl *impl_from_IOverlay(IOverlay *iface) +{ + return CONTAINING_RECORD(iface, VideoRendererImpl, IOverlay_iface); +} + +static HRESULT WINAPI overlay_QueryInterface(IOverlay *iface, REFIID iid, void **out) +{ + VideoRendererImpl *filter = impl_from_IOverlay(iface); + return IPin_QueryInterface(&filter->renderer.sink.pin.IPin_iface, iid, out); +} + +static ULONG WINAPI overlay_AddRef(IOverlay *iface) +{ + VideoRendererImpl *filter = impl_from_IOverlay(iface); + return IPin_AddRef(&filter->renderer.sink.pin.IPin_iface); +} + +static ULONG WINAPI overlay_Release(IOverlay *iface) +{ + VideoRendererImpl *filter = impl_from_IOverlay(iface); + return IPin_Release(&filter->renderer.sink.pin.IPin_iface); +} + +static HRESULT WINAPI overlay_GetPalette(IOverlay *iface, DWORD *count, PALETTEENTRY **palette) +{ + FIXME("iface %p, count %p, palette %p, stub!\n", iface, count, palette); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_SetPalette(IOverlay *iface, DWORD count, PALETTEENTRY *palette) +{ + FIXME("iface %p, count %u, palette %p, stub!\n", iface, count, palette); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_GetDefaultColorKey(IOverlay *iface, COLORKEY *key) +{ + FIXME("iface %p, key %p, stub!\n", iface, key); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_GetColorKey(IOverlay *iface, COLORKEY *key) +{ + FIXME("iface %p, key %p, stub!\n", iface, key); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_SetColorKey(IOverlay *iface, COLORKEY *key) +{ + FIXME("iface %p, key %p, stub!\n", iface, key); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_GetWindowHandle(IOverlay *iface, HWND *window) +{ + FIXME("iface %p, window %p, stub!\n", iface, window); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_GetClipList(IOverlay *iface, RECT *source, RECT *dest, RGNDATA **region) +{ + FIXME("iface %p, source %p, dest %p, region %p, stub!\n", iface, source, dest, region); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_GetVideoPosition(IOverlay *iface, RECT *source, RECT *dest) +{ + FIXME("iface %p, source %p, dest %p, stub!\n", iface, source, dest); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_Advise(IOverlay *iface, IOverlayNotify *sink, DWORD flags) +{ + FIXME("iface %p, sink %p, flags %#x, stub!\n", iface, sink, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI overlay_Unadvise(IOverlay *iface) +{ + FIXME("iface %p, stub!\n", iface); + return E_NOTIMPL; +} + +static const IOverlayVtbl overlay_vtbl = +{ + overlay_QueryInterface, + overlay_AddRef, + overlay_Release, + overlay_GetPalette, + overlay_SetPalette, + overlay_GetDefaultColorKey, + overlay_GetColorKey, + overlay_SetColorKey, + overlay_GetWindowHandle, + overlay_GetClipList, + overlay_GetVideoPosition, + overlay_Advise, + overlay_Unadvise, +}; + HRESULT VideoRenderer_create(IUnknown *outer, void **out) { static const WCHAR sink_name[] = {'I','n',0}; @@ -799,6 +915,8 @@ HRESULT VideoRenderer_create(IUnknown *outer, void **out) ZeroMemory(&pVideoRenderer->WindowPos, sizeof(RECT)); pVideoRenderer->FullScreenMode = OAFALSE;
+ pVideoRenderer->IOverlay_iface.lpVtbl = &overlay_vtbl; + hr = strmbase_renderer_init(&pVideoRenderer->renderer, &VideoRenderer_Vtbl, outer, &CLSID_VideoRenderer, sink_name, &BaseFuncTable);
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=57207
Your paranoid android.
=== wvistau64_zh_CN (32 bit report) ===
quartz: videorenderer.c:1071: Test failed: Expected EC_COMPLETE. videorenderer.c:1076: Test failed: Got unexpected EC_COMPLETE.
=== wvistau64_he (32 bit report) ===
quartz: videorenderer.c:1071: Test failed: Expected EC_COMPLETE. videorenderer.c:1076: Test failed: Got unexpected EC_COMPLETE.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/videorenderer.c | 26 ++++++++++++++++++++++++++ dlls/quartz/videorenderer.c | 8 ++++++-- 2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c index 1343f85e5e6..3bee2a500c8 100644 --- a/dlls/quartz/tests/videorenderer.c +++ b/dlls/quartz/tests/videorenderer.c @@ -1321,6 +1321,31 @@ static void test_unconnected_filter_state(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void test_overlay(void) +{ + IBaseFilter *filter = create_video_renderer(); + IOverlay *overlay; + HRESULT hr; + ULONG ref; + IPin *pin; + HWND hwnd; + + IBaseFilter_FindPin(filter, sink_id, &pin); + + hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hwnd = (HWND)0xdeadbeef; + hr = IOverlay_GetWindowHandle(overlay, &hwnd); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hwnd && hwnd != (HWND)0xdeadbeef, "Got invalid window %p.\n", hwnd); + + IOverlay_Release(overlay); + IPin_Release(pin); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + START_TEST(videorenderer) { CoInitialize(NULL); @@ -1334,6 +1359,7 @@ START_TEST(videorenderer) test_enum_media_types(); test_unconnected_filter_state(); test_connect_pin(); + test_overlay();
CoUninitialize(); } diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c index e2d80642d2e..429b59bfe33 100644 --- a/dlls/quartz/videorenderer.c +++ b/dlls/quartz/videorenderer.c @@ -854,8 +854,12 @@ static HRESULT WINAPI overlay_SetColorKey(IOverlay *iface, COLORKEY *key)
static HRESULT WINAPI overlay_GetWindowHandle(IOverlay *iface, HWND *window) { - FIXME("iface %p, window %p, stub!\n", iface, window); - return E_NOTIMPL; + VideoRendererImpl *filter = impl_from_IOverlay(iface); + + TRACE("filter %p, window %p.\n", filter, window); + + *window = filter->baseControlWindow.baseWindow.hWnd; + return S_OK; }
static HRESULT WINAPI overlay_GetClipList(IOverlay *iface, RECT *source, RECT *dest, RGNDATA **region)
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=57208
Your paranoid android.
=== wvistau64_zh_CN (32 bit report) ===
quartz: videorenderer.c:1071: Test failed: Expected EC_COMPLETE. videorenderer.c:1076: Test failed: Got unexpected EC_COMPLETE.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/filtergraph.c | 105 ++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+)
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index f279950ebe1..8cfa1e2adb3 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -4037,6 +4037,110 @@ static void test_add_source_filter(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static HWND get_renderer_hwnd(IFilterGraph2 *graph) +{ + static const WCHAR sink_id[] = {'I','n',0}; + IEnumFilters *enum_filters; + IBaseFilter *filter; + IOverlay *overlay; + CLSID clsid; + HRESULT hr; + IPin *pin; + HWND hwnd; + + hr = IFilterGraph2_EnumFilters(graph, &enum_filters); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + while (IEnumFilters_Next(enum_filters, 1, &filter, NULL) == S_OK) + { + hr = IBaseFilter_GetClassID(filter, &clsid); + if (hr == S_OK && IsEqualGUID(&clsid, &CLSID_VideoRenderer)) + { + hr = IBaseFilter_FindPin(filter, sink_id, &pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_QueryInterface(pin, &IID_IOverlay, (void **)&overlay); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IOverlay_GetWindowHandle(overlay, &hwnd); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + IOverlay_Release(overlay); + IPin_Release(pin); + } + IBaseFilter_Release(filter); + } + + IEnumFilters_Release(enum_filters); + + return hwnd; +} + +static void test_window_threading(void) +{ + WCHAR *filename = load_resource(avifile); + IFilterGraph2 *graph; + HRESULT hr; + DWORD tid; + ULONG ref; + HWND hwnd; + BOOL ret; + + graph = create_graph(); + hr = IFilterGraph2_RenderFile(graph, filename, NULL); + if (FAILED(hr)) + { + skip("Cannot render test file, hr %#x.\n", hr); + IFilterGraph2_Release(graph); + DeleteFileW(filename); + return; + } + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hwnd = get_renderer_hwnd(graph); + if (hwnd) + { + tid = GetWindowThreadProcessId(hwnd, NULL); + ok(tid != GetCurrentThreadId(), "Window should have been created on a separate thread.\n"); + + /* The thread should be processing messages, or this will hang. */ + SendMessageA(hwnd, WM_NULL, 0, 0); + } + else + skip("Could not find renderer window.\n"); + + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + hr = CoCreateInstance(&CLSID_FilterGraphNoThread, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph2, (void **)&graph); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IFilterGraph2_RenderFile(graph, filename, NULL); + if (FAILED(hr)) + { + skip("Cannot render test file, hr %#x.\n", hr); + IFilterGraph2_Release(graph); + DeleteFileW(filename); + return; + } + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hwnd = get_renderer_hwnd(graph); + if (hwnd) + { + tid = GetWindowThreadProcessId(hwnd, NULL); + todo_wine ok(tid == GetCurrentThreadId(), "Window should be created on main thread.\n"); + } + else + skip("Could not find renderer window.\n"); + + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ret = DeleteFileW(filename); + ok(ret, "Failed to delete file, error %u.\n", GetLastError()); +} + START_TEST(filtergraph) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -4059,6 +4163,7 @@ START_TEST(filtergraph) test_graph_seeking(); test_default_sync_source(); test_add_source_filter(); + test_window_threading();
CoUninitialize(); test_render_with_multithread();
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=57209
Your paranoid android.
=== wxppro (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w2003std (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== wvistau64 (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== wvistau64_zh_CN (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread. filtergraph.c:782: Test failed: wait failed
=== wvistau64_fr (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread. filtergraph.c:782: Test failed: wait failed
=== wvistau64_he (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread. filtergraph.c:782: Test failed: wait failed
=== w2008s64 (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w7u (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w7pro64 (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread. filtergraph.c:782: Test failed: wait failed
=== w8 (32 bit report) ===
quartz: filtergraph.c:527: Test failed: didn't get EOS filtergraph.c:532: Test failed: expected 2ccdba, got 0 filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w8adm (32 bit report) ===
quartz: filtergraph.c:527: Test failed: didn't get EOS filtergraph.c:532: Test failed: expected 2ccdba, got 0 filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w864 (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w1064v1507 (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w1064v1809 (32 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w864 (64 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w1064v1507 (64 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
=== w1064v1809 (64 bit report) ===
quartz: filtergraph.c:4111: Test failed: Window should be created on main thread.
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=57204
Your paranoid android.
=== wvistau64_zh_CN (32 bit report) ===
quartz: videorenderer.c:1071: Test failed: Expected EC_COMPLETE. videorenderer.c:1076: Test failed: Got unexpected EC_COMPLETE.
On 10/01/2019 12:18 AM, Marvin wrote:
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=57204
Your paranoid android.
=== wvistau64_zh_CN (32 bit report) ===
quartz: videorenderer.c:1071: Test failed: Expected EC_COMPLETE. videorenderer.c:1076: Test failed: Got unexpected EC_COMPLETE.
As these test failures show, this series does need some improvement, so please ignore for now.