From: R��mi Bernon rbernon@codeweavers.com
--- dlls/qasf/tests/asfreader.c | 94 +++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+)
diff --git a/dlls/qasf/tests/asfreader.c b/dlls/qasf/tests/asfreader.c index 3a2e18a3054..1fbc64f8e36 100644 --- a/dlls/qasf/tests/asfreader.c +++ b/dlls/qasf/tests/asfreader.c @@ -513,6 +513,99 @@ static void test_filesourcefilter(void) ok(!ref, "Got outstanding refcount %ld.\n", ref); }
+static void test_filter_state(void) +{ + const WCHAR *filename = load_resource(L"test.wmv"); + IBaseFilter *filter = create_asf_reader(); + IFileSourceFilter *file_source; + IReferenceClock *clock; + IEnumPins *enum_pins; + IFilterGraph *graph; + FILTER_STATE state; + IPin *pins[4]; + HRESULT hr; + ULONG ref; + + hr = IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&file_source); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IFileSourceFilter_Load(file_source, filename, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + IFileSourceFilter_Release(file_source); + + hr = IBaseFilter_EnumPins(filter, &enum_pins); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IEnumPins_Next(enum_pins, 1, pins, NULL); + todo_wine + ok(hr == S_FALSE, "Got hr %#lx.\n", hr); + if (hr == S_OK) + IPin_Release(pins[0]); + IEnumPins_Release(enum_pins); + + hr = IBaseFilter_GetState(filter, INFINITE, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Stopped, "Got state %#x.\n", state); + + hr = IBaseFilter_Run(filter, GetTickCount() * 10000); + todo_wine + ok(hr == E_FAIL, "Got hr %#lx.\n", hr); + hr = IBaseFilter_GetState(filter, INFINITE, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine + ok(state == State_Stopped, "Got state %#x.\n", state); + hr = IBaseFilter_Pause(filter); + todo_wine + ok(hr == E_FAIL, "Got hr %#lx.\n", hr); + hr = IBaseFilter_GetState(filter, INFINITE, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + todo_wine + ok(state == State_Stopped, "Got state %#x.\n", state); + hr = IBaseFilter_Stop(filter); + todo_wine + ok(hr == E_FAIL, "Got hr %#lx.\n", hr); + hr = IBaseFilter_GetState(filter, INFINITE, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Stopped, "Got state %#x.\n", state); + + hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph, (void **)&graph); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IFilterGraph_AddFilter(graph, filter, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ref = IFilterGraph_Release(graph); + ok(!ref, "Got ref %ld.\n", ref); + + hr = IBaseFilter_EnumPins(filter, &enum_pins); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IEnumPins_Next(enum_pins, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + IPin_Release(pins[0]); + hr = IEnumPins_Next(enum_pins, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + IPin_Release(pins[0]); + hr = IEnumPins_Next(enum_pins, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#lx.\n", hr); + IEnumPins_Release(enum_pins); + + hr = IBaseFilter_GetSyncSource(filter, &clock); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(!clock, "Got clock %p.\n", clock); + + hr = IBaseFilter_Run(filter, GetTickCount() * 10000); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IBaseFilter_GetState(filter, INFINITE, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Running, "Got state %#x.\n", state); + + hr = IBaseFilter_Stop(filter); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IBaseFilter_GetState(filter, INFINITE, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Stopped, "Got state %#x.\n", state); + + ref = IBaseFilter_Release(filter); + ok(!ref, "Got ref %ld.\n", ref); +} + START_TEST(asfreader) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -520,6 +613,7 @@ START_TEST(asfreader) test_interfaces(); test_aggregation(); test_filesourcefilter(); + test_filter_state();
CoUninitialize(); }
From: R��mi Bernon rbernon@codeweavers.com
--- dlls/qasf/tests/asfreader.c | 458 ++++++++++++++++++++++++++++++++++++ 1 file changed, 458 insertions(+)
diff --git a/dlls/qasf/tests/asfreader.c b/dlls/qasf/tests/asfreader.c index 1fbc64f8e36..2daa9e4c955 100644 --- a/dlls/qasf/tests/asfreader.c +++ b/dlls/qasf/tests/asfreader.c @@ -95,6 +95,264 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO IUnknown_Release(unk); }
+struct test_pin +{ + IPin IPin_iface; + IMemInputPin IMemInputPin_iface; + + DWORD receive_tid; + HANDLE receive_event; + BOOL receive_can_block; + IMemAllocator *allocator; +}; + +static inline struct test_pin *impl_from_IPin(IPin *iface) +{ + return CONTAINING_RECORD(iface, struct test_pin, IPin_iface); +} + +static HRESULT WINAPI test_pin_QueryInterface(IPin *iface, REFIID iid, void **out) +{ + struct test_pin *pin = impl_from_IPin(iface); + + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IPin)) + { + *out = &pin->IPin_iface; + IPin_AddRef(*out); + return S_OK; + } + + if (IsEqualGUID(iid, &IID_IMemInputPin)) + { + *out = &pin->IMemInputPin_iface; + IMemInputPin_AddRef(*out); + return S_OK; + } + + ok(0, "%s not implemented!\n", debugstr_guid(iid)); + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test_pin_AddRef(IPin *iface) +{ + return 2; +} + +static ULONG WINAPI test_pin_Release(IPin *iface) +{ + return 1; +} + +static HRESULT WINAPI test_pin_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) +{ + return S_OK; +} + +static HRESULT WINAPI test_pin_Disconnect(IPin *iface) +{ + return S_OK; +} + +static HRESULT WINAPI test_pin_ConnectedTo(IPin *iface, IPin **peer) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *mt) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_QueryPinInfo(IPin *iface, PIN_INFO *info) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_QueryDirection(IPin *iface, PIN_DIRECTION *dir) +{ + *dir = PINDIR_INPUT; + return S_OK; +} + +static HRESULT WINAPI test_pin_QueryId(IPin *iface, WCHAR **id) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *mt) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **out) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_QueryInternalConnections(IPin *iface, IPin **out, ULONG *count) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_EndOfStream(IPin *iface) +{ + return S_OK; +} + +static HRESULT WINAPI test_pin_BeginFlush(IPin *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_EndFlush(IPin * iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_pin_NewSegment(IPin *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate) +{ + return S_OK; +} + +static const IPinVtbl test_pin_vtbl = +{ + test_pin_QueryInterface, + test_pin_AddRef, + test_pin_Release, + test_pin_Connect, + test_pin_ReceiveConnection, + test_pin_Disconnect, + test_pin_ConnectedTo, + test_pin_ConnectionMediaType, + test_pin_QueryPinInfo, + test_pin_QueryDirection, + test_pin_QueryId, + test_pin_QueryAccept, + test_pin_EnumMediaTypes, + test_pin_QueryInternalConnections, + test_pin_EndOfStream, + test_pin_BeginFlush, + test_pin_EndFlush, + test_pin_NewSegment, +}; + +static inline struct test_pin *impl_from_IMemInputPin(IMemInputPin *iface) +{ + return CONTAINING_RECORD(iface, struct test_pin, IMemInputPin_iface); +} + +static HRESULT WINAPI test_mem_input_pin_QueryInterface(IMemInputPin *iface, REFIID iid, void **out) +{ + struct test_pin *pin = impl_from_IMemInputPin(iface); + return IPin_QueryInterface(&pin->IPin_iface, iid, out); +} + +static ULONG WINAPI test_mem_input_pin_AddRef(IMemInputPin *iface) +{ + struct test_pin *pin = impl_from_IMemInputPin(iface); + return IPin_AddRef(&pin->IPin_iface); +} + +static ULONG WINAPI test_mem_input_pin_Release(IMemInputPin *iface) +{ + struct test_pin *pin = impl_from_IMemInputPin(iface); + return IPin_Release(&pin->IPin_iface); +} + +static HRESULT WINAPI test_mem_input_pin_GetAllocator(IMemInputPin *iface, + IMemAllocator **allocator) +{ + struct test_pin *impl = impl_from_IMemInputPin(iface); + if (!impl->allocator) + return VFW_E_NO_ALLOCATOR; + IMemAllocator_AddRef((*allocator = impl->allocator)); + return S_OK; +} + +static HRESULT WINAPI test_mem_input_pin_NotifyAllocator(IMemInputPin *iface, + IMemAllocator *allocator, BOOL read_only) +{ + struct test_pin *impl = impl_from_IMemInputPin(iface); + IMemAllocator_AddRef((impl->allocator = allocator)); + return S_OK; +} + +static HRESULT WINAPI test_mem_input_pin_GetAllocatorRequirements(IMemInputPin *iface, + ALLOCATOR_PROPERTIES *props) +{ + memset(props, 0, sizeof(*props)); + return S_OK; +} + +static HRESULT WINAPI test_mem_input_pin_Receive(IMemInputPin *iface, + IMediaSample *sample) +{ + struct test_pin *impl = impl_from_IMemInputPin(iface); + + impl->receive_tid = GetCurrentThreadId(); + SetEvent(impl->receive_event); + + todo_wine + ok(0, "Unexpected call.\n"); + + return S_OK; +} + +static HRESULT WINAPI test_mem_input_pin_ReceiveMultiple(IMemInputPin *iface, + IMediaSample **samples, long count, long *processed) +{ + struct test_pin *impl = impl_from_IMemInputPin(iface); + + impl->receive_tid = GetCurrentThreadId(); + SetEvent(impl->receive_event); + + *processed = count; + return S_OK; +} + +static HRESULT WINAPI test_mem_input_pin_ReceiveCanBlock(IMemInputPin *iface) +{ + struct test_pin *impl = impl_from_IMemInputPin(iface); + return impl->receive_can_block ? S_OK : S_FALSE; +} + +static const IMemInputPinVtbl test_mem_input_pin_vtbl = +{ + test_mem_input_pin_QueryInterface, + test_mem_input_pin_AddRef, + test_mem_input_pin_Release, + test_mem_input_pin_GetAllocator, + test_mem_input_pin_NotifyAllocator, + test_mem_input_pin_GetAllocatorRequirements, + test_mem_input_pin_Receive, + test_mem_input_pin_ReceiveMultiple, + test_mem_input_pin_ReceiveCanBlock, +}; + +static const struct test_pin default_test_pin = +{ + .IPin_iface.lpVtbl = &test_pin_vtbl, + .IMemInputPin_iface.lpVtbl = &test_mem_input_pin_vtbl, +}; + static void test_interfaces(void) { IBaseFilter *filter = create_asf_reader(); @@ -606,6 +864,204 @@ static void test_filter_state(void) ok(!ref, "Got ref %ld.\n", ref); }
+static void test_threading(BOOL receive_can_block) +{ + static const WAVEFORMATEX pcm_format = + { + .wFormatTag = WAVE_FORMAT_MSAUDIO1, + .nChannels = 1, + .nSamplesPerSec = 44100, + .nBlockAlign = 2, + .nAvgBytesPerSec = 88200, + .wBitsPerSample = 16, + .cbSize = 0, + }; + static const VIDEOINFOHEADER nv12_info = + { + .rcSource = {0, 0, 64, 48}, + .rcTarget = {0, 0, 64, 48}, + .bmiHeader = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 64, + .biHeight = 48, + .biPlanes = 1, + .biBitCount = 12, + .biCompression = MAKEFOURCC('N','V','1','2'), + .biSizeImage = 64 * 48 * 3 / 2, + }, + }; + static const MSAUDIO1WAVEFORMAT msaudio1_format = + { + .wfx.wFormatTag = WAVE_FORMAT_MSAUDIO1, + .wfx.nChannels = 1, + .wfx.nSamplesPerSec = 44100, + .wfx.nBlockAlign = 743, + .wfx.nAvgBytesPerSec = 16000, + .wfx.wBitsPerSample = 16, + .wfx.cbSize = sizeof(MSAUDIO1WAVEFORMAT) - sizeof(WAVEFORMATEX), + .wEncodeOptions = 1, + }; + static const VIDEOINFOHEADER2 wmv1_info2 = + { + .rcSource = {0, 0, 64, 48}, + .rcTarget = {0, 0, 64, 48}, + .dwBitRate = 189464, + .dwPictAspectRatioX = 64, + .dwPictAspectRatioY = 48, + .bmiHeader = + { + .biSize = sizeof(BITMAPINFOHEADER), + .biWidth = 64, + .biHeight = 48, + .biPlanes = 1, + .biBitCount = 24, + .biCompression = MAKEFOURCC('W','M','V','1'), + .biSizeImage = 64 * 48 * 3, + }, + }; + AM_MEDIA_TYPE audio_mt = + { + .majortype = MEDIATYPE_Audio, + .subtype = MEDIASUBTYPE_MSAUDIO1, + .bFixedSizeSamples = TRUE, + .lSampleSize = 743, + .formattype = FORMAT_WaveFormatEx, + .cbFormat = sizeof(MSAUDIO1WAVEFORMAT), + .pbFormat = (BYTE *)&msaudio1_format, + }; + AM_MEDIA_TYPE video_mt = + { + .majortype = MEDIATYPE_Video, + .subtype = WMMEDIASUBTYPE_WMV1, + .formattype = FORMAT_VideoInfo2, + .bTemporalCompression = TRUE, + .cbFormat = sizeof(VIDEOINFOHEADER2), + .pbFormat = (BYTE *)&wmv1_info2, + }; + AM_MEDIA_TYPE wine_audio_mt = + { + .majortype = MEDIATYPE_Audio, + .subtype = MEDIASUBTYPE_PCM, + .bFixedSizeSamples = TRUE, + .formattype = FORMAT_WaveFormatEx, + .cbFormat = sizeof(WAVEFORMATEX), + .pbFormat = (BYTE *)&pcm_format, + }; + AM_MEDIA_TYPE wine_video_mt = + { + .majortype = MEDIATYPE_Video, + .subtype = MEDIASUBTYPE_NV12, + .formattype = FORMAT_VideoInfo, + .bTemporalCompression = TRUE, + .cbFormat = sizeof(VIDEOINFOHEADER), + .pbFormat = (BYTE *)&nv12_info, + }; + + struct test_pin audio_pin = default_test_pin, video_pin = default_test_pin; + const WCHAR *filename = load_resource(L"test.wmv"); + IBaseFilter *filter = create_asf_reader(); + IFileSourceFilter *file_source; + IEnumPins *enum_pins; + IFilterGraph *graph; + FILTER_STATE state; + IPin *pins[4]; + HRESULT hr; + DWORD ret; + ULONG ref; + + winetest_push_context("%u", !!receive_can_block); + + video_pin.receive_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!video_pin.receive_event, "CreateEventW failed, error %lu\n", GetLastError()); + audio_pin.receive_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!audio_pin.receive_event, "CreateEventW failed, error %lu\n", GetLastError()); + + video_pin.receive_can_block = receive_can_block; + audio_pin.receive_can_block = receive_can_block; + + hr = IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&file_source); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IFileSourceFilter_Load(file_source, filename, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + IFileSourceFilter_Release(file_source); + + hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph, (void **)&graph); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IFilterGraph_AddFilter(graph, filter, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + IFilterGraph_Release(graph); + + hr = IBaseFilter_EnumPins(filter, &enum_pins); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IEnumPins_Next(enum_pins, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IPin_Connect(pins[0], &video_pin.IPin_iface, &video_mt); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (hr != S_OK) + { + hr = IPin_Connect(pins[0], &video_pin.IPin_iface, &wine_video_mt); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + IPin_Release(pins[0]); + hr = IEnumPins_Next(enum_pins, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IPin_Connect(pins[0], &audio_pin.IPin_iface, &audio_mt); + todo_wine + ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (hr != S_OK) + { + hr = IPin_Connect(pins[0], &audio_pin.IPin_iface, &wine_audio_mt); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + IPin_Release(pins[0]); + hr = IEnumPins_Next(enum_pins, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#lx.\n", hr); + IEnumPins_Release(enum_pins); + + hr = IBaseFilter_Run(filter, GetTickCount() * 10000); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IBaseFilter_GetState(filter, INFINITE, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Running, "Got state %#x.\n", state); + + ret = WaitForSingleObject(video_pin.receive_event, 500); + ok(!ret, "Wait timed out.\n"); + ret = WaitForSingleObject(audio_pin.receive_event, 500); + ok(!ret, "Wait timed out.\n"); + + ok(video_pin.receive_tid != GetCurrentThreadId(), "got wrong thread\n"); + ok(audio_pin.receive_tid != GetCurrentThreadId(), "got wrong thread\n"); + if (receive_can_block) + { + todo_wine + ok(audio_pin.receive_tid != video_pin.receive_tid, "got wrong thread\n"); + } + else + ok(audio_pin.receive_tid == video_pin.receive_tid, "got wrong thread\n"); + + hr = IBaseFilter_Stop(filter); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IBaseFilter_GetState(filter, INFINITE, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + ok(state == State_Stopped, "Got state %#x.\n", state); + + ref = IBaseFilter_Release(filter); + ok(!ref, "Got ref %ld.\n", ref); + + if (video_pin.allocator) + IMemAllocator_Release(video_pin.allocator); + if (audio_pin.allocator) + IMemAllocator_Release(audio_pin.allocator); + + CloseHandle(video_pin.receive_event); + CloseHandle(audio_pin.receive_event); + + winetest_pop_context(); +} + START_TEST(asfreader) { CoInitializeEx(NULL, COINIT_MULTITHREADED); @@ -614,6 +1070,8 @@ START_TEST(asfreader) test_aggregation(); test_filesourcefilter(); test_filter_state(); + test_threading(FALSE); + test_threading(TRUE);
CoUninitialize(); }
On 8/20/22 09:03, Rémi Bernon wrote:
+static HRESULT WINAPI test_pin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) +{
- return S_OK;
+}
+static HRESULT WINAPI test_pin_Disconnect(IPin *iface) +{
- return S_OK;
+}
Refcounting-wise this isn't exactly legal. I'd recommend using strmbase_sink for the IPin implementation, which would save a lot of code anyway.
+static HRESULT WINAPI test_mem_input_pin_ReceiveMultiple(IMemInputPin *iface,
IMediaSample **samples, long count, long *processed)
I don't think we want to use "long"; it won't do the right thing without MinGW.
+{
- struct test_pin *impl = impl_from_IMemInputPin(iface);
Please use more descriptive names than "impl". The rest of DirectShow uses "pin" here.
- winetest_push_context("%u", !!receive_can_block);
It'd be nice to be a little less terse here.
- hr = IBaseFilter_EnumPins(filter, &enum_pins);
- ok(hr == S_OK, "Got hr %#lx.\n", hr);
- hr = IEnumPins_Next(enum_pins, 1, pins, NULL);
- ok(hr == S_OK, "Got hr %#lx.\n", hr);
- hr = IPin_Connect(pins[0], &video_pin.IPin_iface, &video_mt);
- todo_wine
- ok(hr == S_OK, "Got hr %#lx.\n", hr);
- if (hr != S_OK)
- {
hr = IPin_Connect(pins[0], &video_pin.IPin_iface, &wine_video_mt);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
- }
- IPin_Release(pins[0]);
It'd be simpler just to use IBaseFilter::FindPin(), as in other DirectShow tests. Note that we already have tests for pin order anyway.
Is there any reason to pass a specific media type instead of using NULL?
- hr = IBaseFilter_GetState(filter, INFINITE, &state);
INFINITE should be avoided in tests. [And if Run() returns S_OK, it should be sufficient to pass zero here.]
On Mon Aug 22 22:03:30 2022 +0000, **** wrote:
Zebediah Figura (she/her) replied on the mailing list:
On 8/20/22 09:03, R��mi Bernon wrote: > +static HRESULT WINAPI test_pin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) > +{ > + return S_OK; > +} > + > +static HRESULT WINAPI test_pin_Disconnect(IPin *iface) > +{ > + return S_OK; > +} Refcounting-wise this isn't exactly legal. I'd recommend using strmbase_sink for the IPin implementation, which would save a lot of code anyway. > +static HRESULT WINAPI test_mem_input_pin_ReceiveMultiple(IMemInputPin *iface, > + IMediaSample **samples, long count, long *processed) I don't think we want to use "long"; it won't do the right thing without MinGW. > +{ > + struct test_pin *impl = impl_from_IMemInputPin(iface); Please use more descriptive names than "impl". The rest of DirectShow uses "pin" here. > + winetest_push_context("%u", !!receive_can_block); It'd be nice to be a little less terse here. > + hr = IBaseFilter_EnumPins(filter, &enum_pins); > + ok(hr == S_OK, "Got hr %#lx.\n", hr); > + hr = IEnumPins_Next(enum_pins, 1, pins, NULL); > + ok(hr == S_OK, "Got hr %#lx.\n", hr); > + hr = IPin_Connect(pins[0], &video_pin.IPin_iface, &video_mt); > + todo_wine > + ok(hr == S_OK, "Got hr %#lx.\n", hr); > + if (hr != S_OK) > + { > + hr = IPin_Connect(pins[0], &video_pin.IPin_iface, &wine_video_mt); > + ok(hr == S_OK, "Got hr %#lx.\n", hr); > + } > + IPin_Release(pins[0]); It'd be simpler just to use IBaseFilter::FindPin(), as in other DirectShow tests. Note that we already have tests for pin order anyway. Is there any reason to pass a specific media type instead of using NULL? > + hr = IBaseFilter_GetState(filter, INFINITE, &state); INFINITE should be avoided in tests. [And if Run() returns S_OK, it should be sufficient to pass zero here.]
Is there any reason to pass a specific media type instead of using NULL?
No real reason, just didn't know we could, but now it actually shows a difference from native, that Wine doesn't accept compressed types, which imho is worth keeping.
On 8/23/22 03:53, Rémi Bernon (@rbernon) wrote:
On Mon Aug 22 22:03:30 2022 +0000, **** wrote:
Zebediah Figura (she/her) replied on the mailing list:
On 8/20/22 09:03, Rémi Bernon wrote: > +static HRESULT WINAPI test_pin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) > +{ > + return S_OK; > +} > + > +static HRESULT WINAPI test_pin_Disconnect(IPin *iface) > +{ > + return S_OK; > +} Refcounting-wise this isn't exactly legal. I'd recommend using strmbase_sink for the IPin implementation, which would save a lot of code anyway. > +static HRESULT WINAPI test_mem_input_pin_ReceiveMultiple(IMemInputPin *iface, > + IMediaSample **samples, long count, long *processed) I don't think we want to use "long"; it won't do the right thing without MinGW. > +{ > + struct test_pin *impl = impl_from_IMemInputPin(iface); Please use more descriptive names than "impl". The rest of DirectShow uses "pin" here. > + winetest_push_context("%u", !!receive_can_block); It'd be nice to be a little less terse here. > + hr = IBaseFilter_EnumPins(filter, &enum_pins); > + ok(hr == S_OK, "Got hr %#lx.\n", hr); > + hr = IEnumPins_Next(enum_pins, 1, pins, NULL); > + ok(hr == S_OK, "Got hr %#lx.\n", hr); > + hr = IPin_Connect(pins[0], &video_pin.IPin_iface, &video_mt); > + todo_wine > + ok(hr == S_OK, "Got hr %#lx.\n", hr); > + if (hr != S_OK) > + { > + hr = IPin_Connect(pins[0], &video_pin.IPin_iface, &wine_video_mt); > + ok(hr == S_OK, "Got hr %#lx.\n", hr); > + } > + IPin_Release(pins[0]); It'd be simpler just to use IBaseFilter::FindPin(), as in other DirectShow tests. Note that we already have tests for pin order anyway. Is there any reason to pass a specific media type instead of using NULL? > + hr = IBaseFilter_GetState(filter, INFINITE, &state); INFINITE should be avoided in tests. [And if Run() returns S_OK, it should be sufficient to pass zero here.]
Is there any reason to pass a specific media type instead of using NULL?
No real reason, just didn't know we could, but now it actually shows a difference from native, that Wine doesn't accept compressed types, which imho is worth keeping.
Sure, makes sense to me.