Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/qedit/tests/mediadet.c | 192 +++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 1 deletion(-)
diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c index ea10f57..067adf1 100644 --- a/dlls/qedit/tests/mediadet.c +++ b/dlls/qedit/tests/mediadet.c @@ -24,6 +24,7 @@ #include "ole2.h" #include "vfwmsgs.h" #include "uuids.h" +#include "wine/strmbase.h" #include "wine/test.h" #include "qedit.h" #include "control.h" @@ -71,6 +72,108 @@ static const IUnknownVtbl outer_vtbl =
static IUnknown test_outer = {&outer_vtbl};
+struct testfilter +{ + struct strmbase_filter filter; + struct strmbase_source source; +}; + +static inline struct testfilter *impl_from_BaseFilter(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_BaseFilter(iface); + + return index ? NULL : &filter->source.pin; +} + +static void testfilter_destroy(struct strmbase_filter *iface) +{ + struct testfilter *filter = impl_from_BaseFilter(iface); + + strmbase_source_cleanup(&filter->source); + strmbase_filter_cleanup(&filter->filter); + free(filter); +} + +static const struct strmbase_filter_ops testfilter_ops = +{ + .filter_get_pin = testfilter_get_pin, + .filter_destroy = testfilter_destroy +}; + +static inline struct testfilter *impl_from_Pin(struct strmbase_pin *iface) +{ + return CONTAINING_RECORD(iface, struct testfilter, source.pin); +} + +static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt) +{ + return S_OK; +} + +static HRESULT testsource_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt) +{ + static const VIDEOINFOHEADER source_format = + { + .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), + .bmiHeader.biWidth = 640, + .bmiHeader.biHeight = 480, + .bmiHeader.biPlanes = 1, + .bmiHeader.biBitCount = 24, + .bmiHeader.biCompression = BI_RGB, + .bmiHeader.biSizeImage = 640 * 480 * 3 + }; + + if (index) + return S_FALSE; + + mt->majortype = MEDIATYPE_Video; + mt->subtype = MEDIASUBTYPE_RGB24; + mt->bFixedSizeSamples = TRUE; + mt->bTemporalCompression = FALSE; + mt->lSampleSize = source_format.bmiHeader.biSizeImage; + mt->formattype = FORMAT_VideoInfo; + mt->pUnk = NULL; + mt->cbFormat = sizeof(source_format); + mt->pbFormat = CoTaskMemAlloc(mt->cbFormat); + memcpy(mt->pbFormat, &source_format, mt->cbFormat); + return S_OK; +} + +static HRESULT WINAPI testsource_decide_allocator(struct strmbase_source *iface, + IMemInputPin *peer, IMemAllocator **allocator) +{ + return S_OK; +} + +static const struct strmbase_source_ops testsource_ops = +{ + .base.pin_query_accept = testsource_query_accept, + .base.pin_get_media_type = testsource_get_media_type, + .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, + .pfnDecideAllocator = testsource_decide_allocator +}; + +static struct testfilter *create_testfilter(void) +{ + static const GUID clsid = {0xabacab}; + struct testfilter *filter = malloc(sizeof(*filter)); + + strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); + strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); + + return filter; +} + +static void release_testfilter(struct testfilter *filter) +{ + IBaseFilter_Release(&filter->filter.IBaseFilter_iface); +} + static void test_aggregation(void) { IMediaDet *detector, *detector2; @@ -188,12 +291,14 @@ static BOOL init_tests(void) static void test_mediadet(void) { HRESULT hr; + struct testfilter *testfilter; + IBaseFilter *filter, *filter2; FILTER_INFO filter_info; AM_MEDIA_TYPE mt, *pmt; IEnumMediaTypes *type; IMediaDet *pM = NULL; BSTR filename = NULL; - IBaseFilter *filter; + IFilterGraph *graph; IEnumPins *enumpins; LONG nstrms = 0; IUnknown *unk; @@ -270,6 +375,48 @@ static void test_mediadet(void) ok(hr == S_FALSE, "Got hr %#x.\n", hr); ok(!unk, "Got filter %p.\n", unk);
+ hr = IMediaDet_put_Filter(pM, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + testfilter = create_testfilter(); + hr = IMediaDet_put_Filter(pM, (IUnknown*)&testfilter->filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_Filter(pM, &unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!unk, "Expected a non-NULL filter.\n"); + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void**)&filter); + IUnknown_Release(unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter == &testfilter->filter.IBaseFilter_iface, "Expected the same filter.\n"); + IBaseFilter_Release(filter); + + ok(!wcscmp(testfilter->filter.name, L"Source"), "Got name %s.\n", wine_dbgstr_w(testfilter->filter.name)); + IFilterGraph_AddRef(graph = testfilter->filter.graph); + release_testfilter(testfilter); + + testfilter = create_testfilter(); + hr = IMediaDet_put_Filter(pM, (IUnknown*)&testfilter->filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_Filter(pM, &unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!unk, "Expected a non-NULL filter.\n"); + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void**)&filter); + IUnknown_Release(unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter == &testfilter->filter.IBaseFilter_iface, "Expected the same filter.\n"); + IBaseFilter_Release(filter); + + ok(graph != testfilter->filter.graph, "Expected a different filter graph.\n"); + release_testfilter(testfilter); + IFilterGraph_Release(graph); + + strm = -1; + hr = IMediaDet_get_CurrentStream(pM, &strm); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(strm == 0, "strm is %i\n", strm); + filename = SysAllocString(test_avi_filename); hr = IMediaDet_put_Filename(pM, filename); ok(hr == S_OK, "IMediaDet_put_Filename failed: %08x\n", hr); @@ -474,9 +621,52 @@ static void test_mediadet(void) hr = IBaseFilter_QueryFilterInfo(filter, &filter_info); ok(hr == S_OK, "Got hr %#x.\n", hr); ok(!wcscmp(filter_info.achName, L"Source"), "Got name %s.\n", debugstr_w(filter_info.achName)); + + testfilter = create_testfilter(); + hr = IMediaDet_put_Filter(pM, (IUnknown*)&testfilter->filter.IBaseFilter_iface); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IMediaDet_get_Filter(pM, &unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!!unk, "Expected a non-NULL filter.\n"); + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void**)&filter2); + IUnknown_Release(unk); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter != filter2, "Expected a different filter.\n"); + ok(filter2 == &testfilter->filter.IBaseFilter_iface, "Expected the same filter.\n"); + IBaseFilter_Release(filter2); + + ok(!wcscmp(testfilter->filter.name, L"Source"), "Got name %s.\n", wine_dbgstr_w(testfilter->filter.name)); + ok(filter_info.pGraph != testfilter->filter.graph, "Expected a different filter graph.\n"); IFilterGraph_Release(filter_info.pGraph); + release_testfilter(testfilter); + + filename = NULL; + hr = IMediaDet_get_Filename(pM, &filename); + todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!filename, "Got filename %s.\n", debugstr_w(filename)); + SysFreeString(filename); + + hr = IMediaDet_get_OutputStreams(pM, &nstrms); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(nstrms == 1, "nstrms is %i\n", nstrms); + + /* Now use the filter obtained from put_Filename for put_Filter. */ + hr = IMediaDet_put_Filter(pM, (IUnknown*)filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); IBaseFilter_Release(filter);
+ filename = NULL; + hr = IMediaDet_get_Filename(pM, &filename); + ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(!filename, "Got filename %s.\n", debugstr_w(filename)); + SysFreeString(filename); + + /* It still looks for a downstream source and splits it into video+audio in this case. */ + hr = IMediaDet_get_OutputStreams(pM, &nstrms); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(nstrms == 2, "nstrms is %i\n", nstrms); + hr = IMediaDet_Release(pM); ok(hr == 0, "IMediaDet_Release returned: %x\n", hr);