[PATCH v3 08/13] qedit/tests: Add tests for put_Filter with a custom filter.

Gabriel Ivăncescu gabrielopcode at gmail.com
Fri Apr 17 11:09:08 CDT 2020


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
 dlls/qedit/tests/mediadet.c | 681 +++++++++++++++++++++++++++++++++++-
 1 file changed, 680 insertions(+), 1 deletion(-)

diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c
index 0a7f1cc..1fa2bb6 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 "dshow.h"
 #include "wine/test.h"
 #include "qedit.h"
 #include "control.h"
@@ -71,6 +72,588 @@ static const IUnknownVtbl outer_vtbl =
 
 static IUnknown test_outer = {&outer_vtbl};
 
+struct testfilter
+{
+    IBaseFilter IBaseFilter_iface;
+    LONG ref;
+    WCHAR *name;
+    IFilterGraph *graph;
+    FILTER_STATE state;
+
+    IEnumPins IEnumPins_iface;
+    UINT enum_idx;
+
+    IPin IPin_iface;
+    IPin *peer;
+
+    IEnumMediaTypes IEnumMediaTypes_iface;
+    UINT mt_enum_idx;
+};
+
+static inline struct testfilter *impl_from_IEnumMediaTypes(IEnumMediaTypes *iface)
+{
+    return CONTAINING_RECORD(iface, struct testfilter, IEnumMediaTypes_iface);
+}
+
+static HRESULT WINAPI testenummt_QueryInterface(IEnumMediaTypes *iface, REFIID iid, void **out)
+{
+    *out = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI testenummt_AddRef(IEnumMediaTypes *iface)
+{
+    struct testfilter *filter = impl_from_IEnumMediaTypes(iface);
+    return IBaseFilter_AddRef(&filter->IBaseFilter_iface);
+}
+
+static ULONG WINAPI testenummt_Release(IEnumMediaTypes *iface)
+{
+    struct testfilter *filter = impl_from_IEnumMediaTypes(iface);
+    return IBaseFilter_Release(&filter->IBaseFilter_iface);
+}
+
+static HRESULT WINAPI testenummt_Next(IEnumMediaTypes *iface, ULONG count, AM_MEDIA_TYPE **out, ULONG *fetched)
+{
+    struct testfilter *filter = impl_from_IEnumMediaTypes(iface);
+    ULONG i = 0;
+
+    if (winetest_debug > 1) trace("IEnumMediaTypes_Next(%u)\n", count);
+
+    if (count && !filter->mt_enum_idx)
+    {
+        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
+        };
+        AM_MEDIA_TYPE source_type =
+        {
+            .majortype = MEDIATYPE_Video,
+            .subtype = MEDIASUBTYPE_RGB24,
+            .bFixedSizeSamples = TRUE,
+            .lSampleSize = source_format.bmiHeader.biSizeImage,
+            .formattype = FORMAT_VideoInfo,
+            .cbFormat = sizeof(source_format)
+        };
+
+        source_type.pbFormat = CoTaskMemAlloc(sizeof(source_format));
+        memcpy(source_type.pbFormat, &source_format, sizeof(source_format));
+
+        out[i] = CoTaskMemAlloc(sizeof(*out[i]));
+        *out[i++] = source_type;
+    }
+
+    if (fetched) *fetched = i;
+    filter->mt_enum_idx += i;
+
+    return (i == count) ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI testenummt_Skip(IEnumMediaTypes *iface, ULONG count)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testenummt_Reset(IEnumMediaTypes *iface)
+{
+    struct testfilter *filter = impl_from_IEnumMediaTypes(iface);
+
+    filter->mt_enum_idx = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI testenummt_Clone(IEnumMediaTypes *iface, IEnumMediaTypes **out)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static const IEnumMediaTypesVtbl testenummt_vtbl =
+{
+    testenummt_QueryInterface,
+    testenummt_AddRef,
+    testenummt_Release,
+    testenummt_Next,
+    testenummt_Skip,
+    testenummt_Reset,
+    testenummt_Clone
+};
+
+static inline struct testfilter *impl_from_IPin(IPin *iface)
+{
+    return CONTAINING_RECORD(iface, struct testfilter, IPin_iface);
+}
+
+static HRESULT WINAPI testpin_QueryInterface(IPin *iface, REFIID iid, void **out)
+{
+    struct testfilter *filter = impl_from_IPin(iface);
+    if (winetest_debug > 1) trace("IPin_QueryInterface(%s)\n", wine_dbgstr_guid(iid));
+
+    if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IPin))
+        *out = &filter->IPin_iface;
+    else
+    {
+        *out = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown *)*out);
+    return S_OK;
+}
+
+static ULONG WINAPI testpin_AddRef(IPin *iface)
+{
+    struct testfilter *filter = impl_from_IPin(iface);
+    return IBaseFilter_AddRef(&filter->IBaseFilter_iface);
+}
+
+static ULONG WINAPI testpin_Release(IPin *iface)
+{
+    struct testfilter *filter = impl_from_IPin(iface);
+    return IBaseFilter_Release(&filter->IBaseFilter_iface);
+}
+
+static HRESULT WINAPI testpin_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
+{
+    struct testfilter *filter = impl_from_IPin(iface);
+    IEnumMediaTypes *enummt;
+    AM_MEDIA_TYPE *pmt;
+    HRESULT hr;
+
+    if (winetest_debug > 1) trace("IPin_Connect(%p)\n", peer);
+
+    ok(!mt, "Got media type %p\n", mt);
+
+    IPin_EnumMediaTypes(iface, &enummt);
+    IEnumMediaTypes_Next(enummt, 1, &pmt, NULL);
+    IEnumMediaTypes_Reset(enummt);
+    IEnumMediaTypes_Release(enummt);
+
+    hr = IPin_ReceiveConnection(peer, &filter->IPin_iface, pmt);
+    CoTaskMemFree(pmt->pbFormat);
+    CoTaskMemFree(pmt);
+    if (FAILED(hr))
+        return hr;
+
+    filter->peer = peer;
+    IPin_AddRef(peer);
+    return S_OK;
+}
+
+static HRESULT WINAPI testpin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpin_Disconnect(IPin *iface)
+{
+    struct testfilter *filter = impl_from_IPin(iface);
+    if (winetest_debug > 1) trace("IPin_Disconnect()\n");
+
+    if (filter->peer)
+    {
+        IPin_Release(filter->peer);
+        filter->peer = NULL;
+    }
+    return S_OK;
+}
+
+static HRESULT WINAPI testpin_ConnectedTo(IPin *iface, IPin **peer)
+{
+    struct testfilter *filter = impl_from_IPin(iface);
+    if (winetest_debug > 1) trace("IPin_ConnectedTo()\n");
+
+    if (!filter->peer)
+        return VFW_E_NOT_CONNECTED;
+
+    *peer = filter->peer;
+    IPin_AddRef(*peer);
+    return S_OK;
+}
+
+static HRESULT WINAPI testpin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *mt)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpin_QueryPinInfo(IPin *iface, PIN_INFO *info)
+{
+    struct testfilter *filter = impl_from_IPin(iface);
+    if (winetest_debug > 1) trace("IPin_QueryPinInfo()\n");
+
+    info->pFilter = &filter->IBaseFilter_iface;
+    IBaseFilter_AddRef(&filter->IBaseFilter_iface);
+    info->dir = PINDIR_OUTPUT;
+    wcscpy(info->achName, L"testpin");
+    return S_OK;
+}
+
+static HRESULT WINAPI testpin_QueryDirection(IPin *iface, PIN_DIRECTION *dir)
+{
+    if (winetest_debug > 1) trace("IPin_QueryDirection()\n");
+
+    *dir = PINDIR_OUTPUT;
+    return S_OK;
+}
+
+static HRESULT WINAPI testpin_QueryId(IPin *iface, WCHAR **id)
+{
+    if (winetest_debug > 1) trace("IPin_QueryId()\n");
+
+    if (!(*id = CoTaskMemAlloc(sizeof(L"deadbeef"))))
+        return E_OUTOFMEMORY;
+
+    wcscpy(*id, L"deadbeef");
+    return S_OK;
+}
+
+static HRESULT WINAPI testpin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *mt)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **out)
+{
+    struct testfilter *filter = impl_from_IPin(iface);
+    if (winetest_debug > 1) trace("IPin_EnumMediaTypes()\n");
+
+    *out = &filter->IEnumMediaTypes_iface;
+    IEnumMediaTypes_AddRef(*out);
+    filter->mt_enum_idx = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI testpin_QueryInternalConnections(IPin *iface, IPin **out, ULONG *count)
+{
+    if (winetest_debug > 1) trace("IPin_QueryInternalConnections()\n");
+
+    *count = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI testpin_EndOfStream(IPin *iface)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpin_BeginFlush(IPin *iface)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpin_EndFlush(IPin *iface)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpin_NewSegment(IPin *iface, REFERENCE_TIME start, REFERENCE_TIME stop, double rate)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static const IPinVtbl testpin_vtbl =
+{
+    testpin_QueryInterface,
+    testpin_AddRef,
+    testpin_Release,
+    testpin_Connect,
+    testpin_ReceiveConnection,
+    testpin_Disconnect,
+    testpin_ConnectedTo,
+    testpin_ConnectionMediaType,
+    testpin_QueryPinInfo,
+    testpin_QueryDirection,
+    testpin_QueryId,
+    testpin_QueryAccept,
+    testpin_EnumMediaTypes,
+    testpin_QueryInternalConnections,
+    testpin_EndOfStream,
+    testpin_BeginFlush,
+    testpin_EndFlush,
+    testpin_NewSegment
+};
+
+static inline struct testfilter *impl_from_IEnumPins(IEnumPins *iface)
+{
+    return CONTAINING_RECORD(iface, struct testfilter, IEnumPins_iface);
+}
+
+static HRESULT WINAPI testenumpins_QueryInterface(IEnumPins *iface, REFIID iid, void **out)
+{
+    ok(0, "Unexpected call with iid %s.\n", wine_dbgstr_guid(iid));
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI testenumpins_AddRef(IEnumPins *iface)
+{
+    struct testfilter *filter = impl_from_IEnumPins(iface);
+    return IBaseFilter_AddRef(&filter->IBaseFilter_iface);
+}
+
+static ULONG WINAPI testenumpins_Release(IEnumPins *iface)
+{
+    struct testfilter *filter = impl_from_IEnumPins(iface);
+    return IBaseFilter_Release(&filter->IBaseFilter_iface);
+}
+
+static HRESULT WINAPI testenumpins_Next(IEnumPins *iface, ULONG count, IPin **out, ULONG *fetched)
+{
+    struct testfilter *filter = impl_from_IEnumPins(iface);
+    ULONG i = 0;
+
+    if (winetest_debug > 1) trace("IEnumPins_Next(%u)\n", count);
+
+    /* Only report one pin */
+    if (count && !filter->enum_idx)
+    {
+        out[i] = &filter->IPin_iface;
+        IPin_AddRef(out[i++]);
+    }
+
+    if (fetched) *fetched = i;
+    filter->enum_idx += i;
+
+    return (i == count) ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI testenumpins_Skip(IEnumPins *iface, ULONG count)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testenumpins_Reset(IEnumPins *iface)
+{
+    struct testfilter *filter = impl_from_IEnumPins(iface);
+
+    filter->enum_idx = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI testenumpins_Clone(IEnumPins *iface, IEnumPins **out)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static const IEnumPinsVtbl testenumpins_vtbl =
+{
+    testenumpins_QueryInterface,
+    testenumpins_AddRef,
+    testenumpins_Release,
+    testenumpins_Next,
+    testenumpins_Skip,
+    testenumpins_Reset,
+    testenumpins_Clone
+};
+
+static inline struct testfilter *impl_from_IBaseFilter(IBaseFilter *iface)
+{
+    return CONTAINING_RECORD(iface, struct testfilter, IBaseFilter_iface);
+}
+
+static HRESULT WINAPI testfilter_QueryInterface(IBaseFilter *iface, REFIID iid, void **out)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+
+    if (winetest_debug > 1) trace("QueryInterface(%s)\n", wine_dbgstr_guid(iid));
+
+    if (IsEqualGUID(iid, &IID_IUnknown)
+            || IsEqualGUID(iid, &IID_IPersist)
+            || IsEqualGUID(iid, &IID_IMediaFilter)
+            || IsEqualGUID(iid, &IID_IBaseFilter))
+    {
+        *out = &filter->IBaseFilter_iface;
+    }
+    else
+    {
+        if (IsEqualGUID(iid, &IID_IFileSourceFilter)) todo_wine ok(0, "Filter queried for IFileSourceFilter\n");
+
+        *out = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown *)*out);
+    return S_OK;
+}
+
+static ULONG WINAPI testfilter_AddRef(IBaseFilter *iface)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+    return InterlockedIncrement(&filter->ref);
+}
+
+static ULONG WINAPI testfilter_Release(IBaseFilter *iface)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+    LONG ref = InterlockedDecrement(&filter->ref);
+
+    if (!ref)
+    {
+        free(filter->name);
+        free(filter);
+    }
+    return ref;
+}
+
+static HRESULT WINAPI testfilter_GetClassID(IBaseFilter *iface, CLSID *clsid)
+{
+    if (winetest_debug > 1) trace("IBaseFilter_GetClassID()\n");
+
+    memset(clsid, 0xde, sizeof(*clsid));
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilter_Stop(IBaseFilter *iface)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+    if (winetest_debug > 1) trace("IBaseFilter_Stop()\n");
+
+    filter->state = State_Stopped;
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilter_Pause(IBaseFilter *iface)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+    if (winetest_debug > 1) trace("IBaseFilter_Pause()\n");
+
+    filter->state = State_Paused;
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilter_Run(IBaseFilter *iface, REFERENCE_TIME start)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+    if (winetest_debug > 1) trace("IBaseFilter_Run()\n");
+
+    filter->state = State_Running;
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilter_GetState(IBaseFilter *iface, DWORD timeout, FILTER_STATE *state)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+    if (winetest_debug > 1) trace("IBaseFilter_GetState()\n");
+
+    *state = filter->state;
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilter_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock)
+{
+    if (winetest_debug > 1) trace("IBaseFilter_SetSyncSource()\n");
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilter_GetSyncSource(IBaseFilter *iface, IReferenceClock **clock)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testfilter_EnumPins(IBaseFilter *iface, IEnumPins **out)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+    if (winetest_debug > 1) trace("IBaseFilter_EnumPins()\n");
+
+    *out = &filter->IEnumPins_iface;
+    IEnumPins_AddRef(*out);
+    filter->enum_idx = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilter_FindPin(IBaseFilter *iface, const WCHAR *id, IPin **pin)
+{
+    ok(0, "Unexpected call.\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testfilter_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *info)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+    if (winetest_debug > 1) trace("IBaseFilter_QueryFilterInfo()\n");
+
+    info->pGraph = filter->graph;
+    if (filter->graph)
+        IFilterGraph_AddRef(filter->graph);
+    if (filter->name)
+        wcscpy(info->achName, filter->name);
+    else
+        info->achName[0] = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *graph, const WCHAR *name)
+{
+    struct testfilter *filter = impl_from_IBaseFilter(iface);
+    if (winetest_debug > 1) trace("IBaseFilter_JoinFilterGraph()\n");
+
+    filter->graph = graph;
+    free(filter->name);
+    if (name)
+    {
+        filter->name = malloc((wcslen(name) + 1) * sizeof(WCHAR));
+        wcscpy(filter->name, name);
+    }
+    else
+        filter->name = NULL;
+    return S_OK;
+}
+
+static HRESULT WINAPI testfilter_QueryVendorInfo(IBaseFilter *iface, WCHAR **info)
+{
+    return E_NOTIMPL;
+}
+
+static const IBaseFilterVtbl testfilter_vtbl =
+{
+    testfilter_QueryInterface,
+    testfilter_AddRef,
+    testfilter_Release,
+    testfilter_GetClassID,
+    testfilter_Stop,
+    testfilter_Pause,
+    testfilter_Run,
+    testfilter_GetState,
+    testfilter_SetSyncSource,
+    testfilter_GetSyncSource,
+    testfilter_EnumPins,
+    testfilter_FindPin,
+    testfilter_QueryFilterInfo,
+    testfilter_JoinFilterGraph,
+    testfilter_QueryVendorInfo
+};
+
+static IBaseFilter *create_testfilter(void)
+{
+    struct testfilter *filter = malloc(sizeof(*filter));
+
+    memset(filter, 0, sizeof(*filter));
+    filter->IBaseFilter_iface.lpVtbl = &testfilter_vtbl;
+    filter->IEnumPins_iface.lpVtbl = &testenumpins_vtbl;
+    filter->IPin_iface.lpVtbl = &testpin_vtbl;
+    filter->IEnumMediaTypes_iface.lpVtbl = &testenummt_vtbl;
+    filter->ref = 1;
+    filter->state = State_Stopped;
+
+    return &filter->IBaseFilter_iface;
+}
+
 static void test_aggregation(void)
 {
     IMediaDet *detector, *detector2;
@@ -188,11 +771,12 @@ static BOOL init_tests(void)
 static void test_mediadet(void)
 {
     HRESULT hr;
+    IBaseFilter *filter, *filter2;
     FILTER_INFO filter_info;
     IEnumMediaTypes *type;
     IMediaDet *pM = NULL;
     BSTR filename = NULL;
-    IBaseFilter *filter;
+    IFilterGraph *graph;
     IEnumPins *pins;
     LONG nstrms = 0;
     LONG strm;
@@ -270,6 +854,53 @@ static void test_mediadet(void)
     ok(hr == S_FALSE, "IMediaDet_get_Filter failed: %08x\n", hr);
     ok(unk == NULL, "Wrong filter %p\n", unk);
 
+    hr = IMediaDet_put_Filter(pM, NULL);
+    ok(hr == E_POINTER, "IMediaDet_put_Filter failed: %08x\n", hr);
+
+    filter = create_testfilter();
+    hr = IMediaDet_put_Filter(pM, (IUnknown*)filter);
+    ok(hr == S_OK, "IMediaDet_put_Filter failed: %08x\n", hr);
+
+    hr = IMediaDet_get_Filter(pM, &unk);
+    ok(hr == S_OK, "IMediaDet_get_Filter failed: %08x\n", hr);
+    ok(unk != NULL, "NULL filter\n");
+    hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void**)&filter2);
+    IUnknown_Release(unk);
+    ok(hr == S_OK, "Could not get IBaseFilter interface: %08x\n", hr);
+    ok(filter == filter2, "Wrong filter\n");
+    IBaseFilter_Release(filter2);
+
+    hr = IBaseFilter_QueryFilterInfo(filter, &filter_info);
+    ok(hr == S_OK, "IBaseFilter_QueryFilterInfo failed: %08x\n", hr);
+    ok(!wcscmp(filter_info.achName, L"Source"), "Wrong filter name: %s\n", wine_dbgstr_w(filter_info.achName));
+    IBaseFilter_Release(filter);
+    graph = filter_info.pGraph;
+
+    filter = create_testfilter();
+    hr = IMediaDet_put_Filter(pM, (IUnknown*)filter);
+    ok(hr == S_OK, "IMediaDet_put_Filter failed: %08x\n", hr);
+    IBaseFilter_Release(filter);
+
+    hr = IMediaDet_get_Filter(pM, &unk);
+    ok(hr == S_OK, "IMediaDet_get_Filter failed: %08x\n", hr);
+    ok(unk != NULL, "NULL filter\n");
+    hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void**)&filter);
+    IUnknown_Release(unk);
+    ok(hr == S_OK, "Could not get IBaseFilter interface: %08x\n", hr);
+
+    hr = IBaseFilter_QueryFilterInfo(filter, &filter_info);
+    ok(hr == S_OK, "IBaseFilter_QueryFilterInfo failed: %08x\n", hr);
+    ok(!wcscmp(filter_info.achName, L"Source"), "Wrong filter name: %s\n", wine_dbgstr_w(filter_info.achName));
+    ok(graph != filter_info.pGraph, "Same filter graph was used\n");
+    IFilterGraph_Release(filter_info.pGraph);
+    IFilterGraph_Release(graph);
+    IBaseFilter_Release(filter);
+
+    strm = -1;
+    hr = IMediaDet_get_CurrentStream(pM, &strm);
+    ok(hr == S_OK, "IMediaDet_get_CurrentStream failed: %08x\n", hr);
+    ok(strm == 0, "IMediaDet_get_CurrentStream: 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);
@@ -469,9 +1100,57 @@ static void test_mediadet(void)
     hr = IBaseFilter_QueryFilterInfo(filter, &filter_info);
     ok(hr == S_OK, "IBaseFilter_QueryFilterInfo failed: %08x\n", hr);
     ok(!wcscmp(filter_info.achName, L"Source"), "Wrong filter name: %s\n", wine_dbgstr_w(filter_info.achName));
+    graph = filter_info.pGraph;
+
+    filter2 = create_testfilter();
+    hr = IMediaDet_put_Filter(pM, (IUnknown*)filter2);
+    ok(hr == S_OK, "IMediaDet_put_Filter failed: %08x\n", hr);
+    IBaseFilter_Release(filter2);
+
+    hr = IMediaDet_get_Filter(pM, &unk);
+    ok(hr == S_OK, "IMediaDet_get_Filter failed: %08x\n", hr);
+    ok(unk != NULL, "NULL filter\n");
+    hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void**)&filter2);
+    IUnknown_Release(unk);
+    ok(hr == S_OK, "Could not get IBaseFilter interface: %08x\n", hr);
+    ok(filter != filter2, "Same filter\n");
+
+    hr = IBaseFilter_QueryFilterInfo(filter2, &filter_info);
+    ok(hr == S_OK, "IBaseFilter_QueryFilterInfo failed: %08x\n", hr);
+    ok(!wcscmp(filter_info.achName, L"Source"), "Wrong filter name: %s\n", wine_dbgstr_w(filter_info.achName));
+    ok(graph != filter_info.pGraph, "Same filter graph was used\n");
     IFilterGraph_Release(filter_info.pGraph);
+    IFilterGraph_Release(graph);
+    IBaseFilter_Release(filter2);
+
+    filename = NULL;
+    hr = IMediaDet_get_Filename(pM, &filename);
+todo_wine
+    ok(hr == S_OK, "IMediaDet_get_Filename failed: %08x\n", hr);
+    ok(!filename, "Expected NULL filename, got %s.\n", debugstr_w(filename));
+    SysFreeString(filename);
+
+    hr = IMediaDet_get_OutputStreams(pM, &nstrms);
+    ok(hr == S_OK, "IMediaDet_get_OutputStreams failed: %08x\n", hr);
+    ok(nstrms == 1, "IMediaDet_get_OutputStreams: 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, "IMediaDet_put_Filter failed: %08x\n", hr);
     IBaseFilter_Release(filter);
 
+    filename = NULL;
+    hr = IMediaDet_get_Filename(pM, &filename);
+    ok(hr == S_OK, "IMediaDet_get_Filename failed: %08x\n", hr);
+todo_wine
+    ok(!filename, "Expected NULL filename, got %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, "IMediaDet_get_OutputStreams failed: %08x\n", hr);
+    ok(nstrms == 2, "IMediaDet_get_OutputStreams: nstrms is %i\n", nstrms);
+
     hr = IMediaDet_Release(pM);
     ok(hr == 0, "IMediaDet_Release returned: %x\n", hr);
 
-- 
2.21.0




More information about the wine-devel mailing list