Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/dsoundrender.c | 138 +++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+)
diff --git a/dlls/quartz/tests/dsoundrender.c b/dlls/quartz/tests/dsoundrender.c index 0b45d712dc0..22d5bf62824 100644 --- a/dlls/quartz/tests/dsoundrender.c +++ b/dlls/quartz/tests/dsoundrender.c @@ -25,6 +25,7 @@ #include "dsound.h" #include "amaudio.h" #include "mmreg.h" +#include "wine/strmbase.h" #include "wine/test.h"
static const WCHAR sink_id[] = L"Audio Input pin (rendered)"; @@ -38,6 +39,12 @@ static IBaseFilter *create_dsound_render(void) return filter; }
+static inline BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b) +{ + return !memcmp(a, b, offsetof(AM_MEDIA_TYPE, pbFormat)) + && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat); +} + static ULONG get_refcount(void *iface) { IUnknown *unknown = iface; @@ -573,6 +580,136 @@ static void test_enum_media_types(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+struct testfilter +{ + struct strmbase_filter filter; + struct strmbase_source source; +}; + +static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, filter); +} + +static struct strmbase_pin *testfilter_get_pin(struct strmbase_filter *iface, unsigned int index) +{ + struct testfilter *filter = impl_from_strmbase_filter(iface); + if (!index) + return &filter->source.pin; + return NULL; +} + +static void testfilter_destroy(struct strmbase_filter *iface) +{ + struct testfilter *filter = impl_from_strmbase_filter(iface); + strmbase_source_cleanup(&filter->source); + strmbase_filter_cleanup(&filter->filter); +} + +static const struct strmbase_filter_ops testfilter_ops = +{ + .filter_get_pin = testfilter_get_pin, + .filter_destroy = testfilter_destroy, +}; + +static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, + IMemInputPin *peer, IMemAllocator **allocator) +{ + return S_OK; +} + +static const struct strmbase_source_ops testsource_ops = +{ + .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, + .pfnDecideAllocator = testsource_DecideAllocator, +}; + +static void testfilter_init(struct testfilter *filter) +{ + static const GUID clsid = {0xabacab}; + strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); + strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); +} + +static void test_connect_pin(void) +{ + WAVEFORMATEX wfx = + { + .wFormatTag = WAVE_FORMAT_PCM, + .nChannels = 2, + .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 44100 * 4, + .nBlockAlign = 4, + .wBitsPerSample = 16, + }; + AM_MEDIA_TYPE req_mt = + { + .majortype = MEDIATYPE_Audio, + .subtype = MEDIASUBTYPE_PCM, + .formattype = FORMAT_WaveFormatEx, + .cbFormat = sizeof(wfx), + .pbFormat = (BYTE *)&wfx, + }; + IBaseFilter *filter = create_dsound_render(); + struct testfilter source; + IFilterGraph2 *graph; + AM_MEDIA_TYPE mt; + IPin *pin, *peer; + HRESULT hr; + ULONG ref; + + testfilter_init(&source); + + CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph2, (void **)&graph); + IFilterGraph2_AddFilter(graph, &source.filter.IBaseFilter_iface, L"source"); + IFilterGraph2_AddFilter(graph, filter, L"sink"); + + IBaseFilter_FindPin(filter, sink_id, &pin); + + peer = (IPin *)0xdeadbeef; + hr = IPin_ConnectedTo(pin, &peer); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + ok(!peer, "Got peer %p.\n", peer); + + hr = IPin_ConnectionMediaType(pin, &mt); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + + hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IPin_ConnectedTo(pin, &peer); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(peer == &source.source.pin.IPin_iface, "Got peer %p.\n", peer); + IPin_Release(peer); + + hr = IPin_ConnectionMediaType(pin, &mt); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(compare_media_types(&mt, &req_mt), "Media types didn't match.\n"); + + hr = IFilterGraph2_Disconnect(graph, pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IFilterGraph2_Disconnect(graph, pin); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(source.source.pin.peer == pin, "Got peer %p.\n", source.source.pin.peer); + IFilterGraph2_Disconnect(graph, &source.source.pin.IPin_iface); + + peer = (IPin *)0xdeadbeef; + hr = IPin_ConnectedTo(pin, &peer); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + ok(!peer, "Got peer %p.\n", peer); + + hr = IPin_ConnectionMediaType(pin, &mt); + ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + + IPin_Release(pin); + ref = IFilterGraph2_Release(graph); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); + ref = IBaseFilter_Release(&source.filter.IBaseFilter_iface); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + static void test_pin(IPin *pin) { IMemInputPin *mpin = NULL; @@ -829,6 +966,7 @@ START_TEST(dsoundrender) test_enum_media_types(); test_unconnected_filter_state(); test_media_types(); + test_connect_pin(); test_basefilter();
CoUninitialize();