[PATCH v2 12/13] qedit/tests: Add tests for get_Filter and put_Filter with a custom filter.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Thu Apr 16 10:25:04 CDT 2020
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
dlls/qedit/tests/mediadet.c | 965 ++++++++++++++++++++++++++++++++++++
1 file changed, 965 insertions(+)
diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c
index 596171b..10127cf 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,867 @@ static const IUnknownVtbl outer_vtbl =
static IUnknown test_outer = {&outer_vtbl};
+struct testfilter
+{
+ IBaseFilter IBaseFilter_iface;
+ IMediaSeeking IMediaSeeking_iface;
+ IMediaPosition IMediaPosition_iface;
+ LONG ref;
+ WCHAR *name;
+ IFilterGraph *graph;
+ FILTER_STATE state;
+ double rate;
+
+ 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 (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 (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IPin))
+ *out = &filter->IPin_iface;
+ else if (IsEqualGUID(iid, &IID_IMediaSeeking))
+ *out = &filter->IMediaSeeking_iface;
+ else if (IsEqualGUID(iid, &IID_IMediaPosition))
+ *out = &filter->IMediaPosition_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;
+
+ 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 (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 (!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);
+
+ 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)
+{
+ *dir = PINDIR_OUTPUT;
+ return S_OK;
+}
+
+static HRESULT WINAPI testpin_QueryId(IPin *iface, WCHAR **id)
+{
+ 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);
+
+ *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)
+{
+ *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;
+
+ /* 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_IMediaSeeking(IMediaSeeking *iface)
+{
+ return CONTAINING_RECORD(iface, struct testfilter, IMediaSeeking_iface);
+}
+
+static HRESULT WINAPI testseek_QueryInterface(IMediaSeeking *iface, REFIID iid, void **out)
+{
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+ return IBaseFilter_QueryInterface(&filter->IBaseFilter_iface, iid, out);
+}
+
+static ULONG WINAPI testseek_AddRef(IMediaSeeking *iface)
+{
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+ return IBaseFilter_AddRef(&filter->IBaseFilter_iface);
+}
+
+static ULONG WINAPI testseek_Release(IMediaSeeking *iface)
+{
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+ return IBaseFilter_Release(&filter->IBaseFilter_iface);
+}
+
+static HRESULT WINAPI testseek_GetCapabilities(IMediaSeeking *iface, DWORD *caps)
+{
+ *caps = AM_SEEKING_CanGetDuration;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_CheckCapabilities(IMediaSeeking *iface, DWORD *caps)
+{
+ ok(0, "Unexpected call.\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testseek_IsFormatSupported(IMediaSeeking *iface, const GUID *format)
+{
+ return IsEqualGUID(format, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI testseek_QueryPreferredFormat(IMediaSeeking *iface, GUID *format)
+{
+ *format = TIME_FORMAT_MEDIA_TIME;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_GetTimeFormat(IMediaSeeking *iface, GUID *format)
+{
+ *format = TIME_FORMAT_MEDIA_TIME;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_IsUsingTimeFormat(IMediaSeeking *iface, const GUID *format)
+{
+ return IsEqualGUID(format, &TIME_FORMAT_MEDIA_TIME) ? S_OK : S_FALSE;
+}
+
+static HRESULT WINAPI testseek_SetTimeFormat(IMediaSeeking *iface, const GUID *format)
+{
+ return IsEqualGUID(format, &TIME_FORMAT_MEDIA_TIME) ? S_OK : E_INVALIDARG;
+}
+
+static HRESULT WINAPI testseek_GetDuration(IMediaSeeking *iface, LONGLONG *duration)
+{
+ *duration = 42000000;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_GetStopPosition(IMediaSeeking *iface, LONGLONG *stop)
+{
+ *stop = 42000000;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_GetCurrentPosition(IMediaSeeking *iface, LONGLONG *current)
+{
+ *current = 0;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_ConvertTimeFormat(IMediaSeeking *iface, LONGLONG *target,
+ const GUID *target_format, LONGLONG source, const GUID *source_format)
+{
+ ok(0, "Unexpected call.\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testseek_SetPositions(IMediaSeeking *iface, LONGLONG *current,
+ DWORD current_flags, LONGLONG *stop, DWORD stop_flags)
+{
+ *current = 0;
+ *stop = 42000000;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_GetPositions(IMediaSeeking *iface, LONGLONG *current, LONGLONG *stop)
+{
+ *current = 0;
+ *stop = 42000000;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_GetAvailable(IMediaSeeking *iface, LONGLONG *earliest, LONGLONG *latest)
+{
+ *earliest = 0;
+ *latest = 42000000;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_SetRate(IMediaSeeking *iface, double rate)
+{
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+
+ filter->rate = rate;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_GetRate(IMediaSeeking *iface, double *rate)
+{
+ struct testfilter *filter = impl_from_IMediaSeeking(iface);
+
+ *rate = filter->rate;
+ return S_OK;
+}
+
+static HRESULT WINAPI testseek_GetPreroll(IMediaSeeking *iface, LONGLONG *preroll)
+{
+ *preroll = 0;
+ return S_OK;
+}
+
+static const IMediaSeekingVtbl testseek_vtbl =
+{
+ testseek_QueryInterface,
+ testseek_AddRef,
+ testseek_Release,
+ testseek_GetCapabilities,
+ testseek_CheckCapabilities,
+ testseek_IsFormatSupported,
+ testseek_QueryPreferredFormat,
+ testseek_GetTimeFormat,
+ testseek_IsUsingTimeFormat,
+ testseek_SetTimeFormat,
+ testseek_GetDuration,
+ testseek_GetStopPosition,
+ testseek_GetCurrentPosition,
+ testseek_ConvertTimeFormat,
+ testseek_SetPositions,
+ testseek_GetPositions,
+ testseek_GetAvailable,
+ testseek_SetRate,
+ testseek_GetRate,
+ testseek_GetPreroll
+};
+
+static inline struct testfilter *impl_from_IMediaPosition(IMediaPosition *iface)
+{
+ return CONTAINING_RECORD(iface, struct testfilter, IMediaPosition_iface);
+}
+
+static HRESULT WINAPI testpos_QueryInterface(IMediaPosition *iface, REFIID iid, void **out)
+{
+ struct testfilter *filter = impl_from_IMediaPosition(iface);
+ return IBaseFilter_QueryInterface(&filter->IBaseFilter_iface, iid, out);
+}
+
+static ULONG WINAPI testpos_AddRef(IMediaPosition *iface)
+{
+ struct testfilter *filter = impl_from_IMediaPosition(iface);
+ return IBaseFilter_AddRef(&filter->IBaseFilter_iface);
+}
+
+static ULONG WINAPI testpos_Release(IMediaPosition *iface)
+{
+ struct testfilter *filter = impl_from_IMediaPosition(iface);
+ return IBaseFilter_Release(&filter->IBaseFilter_iface);
+}
+
+static HRESULT WINAPI testpos_GetTypeInfoCount(IMediaPosition *iface, UINT *pctinfo)
+{
+ ok(0, "Unexpected call.\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpos_GetTypeInfo(IMediaPosition *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
+{
+ ok(0, "Unexpected call.\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpos_GetIDsOfNames(IMediaPosition *iface, REFIID riid, LPOLESTR *rgszNames,
+ UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+ ok(0, "Unexpected call.\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpos_Invoke(IMediaPosition *iface, DISPID dispIdMember, REFIID riid, LCID lcid,
+ WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+ ok(0, "Unexpected call.\n");
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI testpos_get_Duration(IMediaPosition *iface, REFTIME *duration)
+{
+ *duration = 4.2;
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_put_CurrentPosition(IMediaPosition *iface, REFTIME current)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_get_CurrentPosition(IMediaPosition *iface, REFTIME *current)
+{
+ *current = 0.0;
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_get_StopTime(IMediaPosition *iface, REFTIME *stop)
+{
+ *stop = 4.2;
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_put_StopTime(IMediaPosition *iface, REFTIME stop)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_get_PrerollTime(IMediaPosition *iface, REFTIME *preroll)
+{
+ *preroll = 0.0;
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_put_PrerollTime(IMediaPosition *iface, REFTIME preroll)
+{
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_put_Rate(IMediaPosition *iface, double rate)
+{
+ struct testfilter *filter = impl_from_IMediaPosition(iface);
+
+ filter->rate = rate;
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_get_Rate(IMediaPosition *iface, double *rate)
+{
+ struct testfilter *filter = impl_from_IMediaPosition(iface);
+
+ *rate = filter->rate;
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_CanSeekForward(IMediaPosition *iface, LONG *can_seek)
+{
+ *can_seek = OAFALSE;
+ return S_OK;
+}
+
+static HRESULT WINAPI testpos_CanSeekBackward(IMediaPosition *iface, LONG *can_seek)
+{
+ *can_seek = OAFALSE;
+ return S_OK;
+}
+
+static const IMediaPositionVtbl testpos_vtbl =
+{
+ testpos_QueryInterface,
+ testpos_AddRef,
+ testpos_Release,
+ testpos_GetTypeInfoCount,
+ testpos_GetTypeInfo,
+ testpos_GetIDsOfNames,
+ testpos_Invoke,
+ testpos_get_Duration,
+ testpos_put_CurrentPosition,
+ testpos_get_CurrentPosition,
+ testpos_get_StopTime,
+ testpos_put_StopTime,
+ testpos_get_PrerollTime,
+ testpos_put_PrerollTime,
+ testpos_put_Rate,
+ testpos_get_Rate,
+ testpos_CanSeekForward,
+ testpos_CanSeekBackward
+};
+
+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 (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_IMediaSeeking))
+ *out = &filter->IMediaSeeking_iface;
+ else if (IsEqualGUID(iid, &IID_IMediaPosition))
+ *out = &filter->IMediaPosition_iface;
+ else
+ {
+ if (IsEqualGUID(iid, &IID_IFileSourceFilter)) 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)
+ {
+ HeapFree(GetProcessHeap(), 0, filter->name);
+ HeapFree(GetProcessHeap(), 0, filter);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI testfilter_GetClassID(IBaseFilter *iface, CLSID *clsid)
+{
+ memset(clsid, 0xde, sizeof(*clsid));
+ return S_OK;
+}
+
+static HRESULT WINAPI testfilter_Stop(IBaseFilter *iface)
+{
+ struct testfilter *filter = impl_from_IBaseFilter(iface);
+
+ filter->state = State_Stopped;
+ return S_OK;
+}
+
+static HRESULT WINAPI testfilter_Pause(IBaseFilter *iface)
+{
+ struct testfilter *filter = impl_from_IBaseFilter(iface);
+
+ filter->state = State_Paused;
+ return S_OK;
+}
+
+static HRESULT WINAPI testfilter_Run(IBaseFilter *iface, REFERENCE_TIME start)
+{
+ struct testfilter *filter = impl_from_IBaseFilter(iface);
+
+ 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);
+
+ *state = filter->state;
+ return S_OK;
+}
+
+static HRESULT WINAPI testfilter_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock)
+{
+ 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);
+
+ *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);
+
+ 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);
+
+ filter->graph = graph;
+ HeapFree(GetProcessHeap(), 0, filter->name);
+ if (name)
+ {
+ filter->name = HeapAlloc(GetProcessHeap(), 0, (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 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*filter));
+
+ if (!filter) return NULL;
+
+ filter->IBaseFilter_iface.lpVtbl = &testfilter_vtbl;
+ filter->IMediaSeeking_iface.lpVtbl = &testseek_vtbl;
+ filter->IMediaPosition_iface.lpVtbl = &testpos_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;
+ filter->rate = 1.0;
+
+ return &filter->IBaseFilter_iface;
+}
+
static void test_aggregation(void)
{
IMediaDet *detector, *detector2;
@@ -188,13 +1050,17 @@ static BOOL init_tests(void)
static void test_mediadet(void)
{
HRESULT hr;
+ IBaseFilter *filter, *filter2;
+ FILTER_INFO filter_info;
IMediaDet *pM = NULL;
BSTR filename = NULL;
+ IFilterGraph *graph;
LONG nstrms = 0;
LONG strm;
GUID guid;
BSTR bstr;
AM_MEDIA_TYPE mt;
+ IUnknown *unk;
double fps;
int flags;
int i;
@@ -256,6 +1122,61 @@ static void test_mediadet(void)
hr = IMediaDet_get_StreamTypeB(pM, NULL);
ok(hr == E_INVALIDARG, "IMediaDet_get_StreamTypeB failed: %08x\n", hr);
+ hr = IMediaDet_get_Filter(pM, NULL);
+ ok(hr == E_POINTER, "IMediaDet_get_Filter failed: %08x\n", hr);
+
+ unk = (IUnknown*)0xdeadbeef;
+ hr = IMediaDet_get_Filter(pM, &unk);
+ 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);
@@ -427,6 +1348,50 @@ static void test_mediadet(void)
ok(hr == S_OK, "IMediaDet_get_CurrentStream failed: %08x\n", hr);
ok(strm == 1, "IMediaDet_get_CurrentStream: strm is %i\n", strm);
+ 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);
+
+ 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));
+ 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);
+ ok(filter != filter2, "Same 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));
+ ok(graph != filter_info.pGraph, "Same filter graph was used\n");
+ IFilterGraph_Release(filter_info.pGraph);
+ IFilterGraph_Release(graph);
+ IBaseFilter_Release(filter);
+
+ filename = NULL;
+ hr = IMediaDet_get_Filename(pM, &filename);
+ 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);
+
hr = IMediaDet_Release(pM);
ok(hr == 0, "IMediaDet_Release returned: %x\n", hr);
--
2.21.0
More information about the wine-devel
mailing list