Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/tests/smartteefilter.c | 1653 ------------------------------ 1 file changed, 1653 deletions(-)
diff --git a/dlls/qcap/tests/smartteefilter.c b/dlls/qcap/tests/smartteefilter.c index bd51743de76..df741ba1284 100644 --- a/dlls/qcap/tests/smartteefilter.c +++ b/dlls/qcap/tests/smartteefilter.c @@ -563,1657 +563,6 @@ static void test_enum_media_types(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
-typedef struct { - IBaseFilter IBaseFilter_iface; - LONG ref; - BOOL isCapture; - DWORD receiveThreadId; - IPin IPin_iface; - IMemInputPin IMemInputPin_iface; - IMemAllocator *allocator; - IBaseFilter *nullRenderer; - IPin *nullRendererPin; - IMemInputPin *nullRendererMemInputPin; -} SinkFilter; - -typedef struct { - IEnumPins IEnumPins_iface; - LONG ref; - ULONG index; - SinkFilter *filter; -} SinkEnumPins; - -static SinkEnumPins* create_SinkEnumPins(SinkFilter *filter); - -static inline SinkFilter* impl_from_SinkFilter_IBaseFilter(IBaseFilter *iface) -{ - return CONTAINING_RECORD(iface, SinkFilter, IBaseFilter_iface); -} - -static inline SinkFilter* impl_from_SinkFilter_IPin(IPin *iface) -{ - return CONTAINING_RECORD(iface, SinkFilter, IPin_iface); -} - -static inline SinkFilter* impl_from_SinkFilter_IMemInputPin(IMemInputPin *iface) -{ - return CONTAINING_RECORD(iface, SinkFilter, IMemInputPin_iface); -} - -static inline SinkEnumPins* impl_from_SinkFilter_IEnumPins(IEnumPins *iface) -{ - return CONTAINING_RECORD(iface, SinkEnumPins, IEnumPins_iface); -} - -static HRESULT WINAPI SinkFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - if(IsEqualIID(riid, &IID_IUnknown)) { - *ppv = &This->IBaseFilter_iface; - } else if(IsEqualIID(riid, &IID_IPersist)) { - *ppv = &This->IBaseFilter_iface; - } else if(IsEqualIID(riid, &IID_IMediaFilter)) { - *ppv = &This->IBaseFilter_iface; - } else if(IsEqualIID(riid, &IID_IBaseFilter)) { - *ppv = &This->IBaseFilter_iface; - } else { - trace("no interface for %s\n", wine_dbgstr_guid(riid)); - *ppv = NULL; - return E_NOINTERFACE; - } - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI SinkFilter_AddRef(IBaseFilter *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI SinkFilter_Release(IBaseFilter *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - ULONG ref = InterlockedDecrement(&This->ref); - if(!ref) { - if (This->allocator) - IMemAllocator_Release(This->allocator); - IMemInputPin_Release(This->nullRendererMemInputPin); - IPin_Release(This->nullRendererPin); - IBaseFilter_Release(This->nullRenderer); - CoTaskMemFree(This); - } - return ref; -} - -static HRESULT WINAPI SinkFilter_GetClassID(IBaseFilter *iface, CLSID *pClassID) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_GetClassID(This->nullRenderer, pClassID); -} - -static HRESULT WINAPI SinkFilter_Stop(IBaseFilter *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_Stop(This->nullRenderer); -} - -static HRESULT WINAPI SinkFilter_Pause(IBaseFilter *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_Pause(This->nullRenderer); -} - -static HRESULT WINAPI SinkFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_Run(This->nullRenderer, tStart); -} - -static HRESULT WINAPI SinkFilter_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *state) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_GetState(This->nullRenderer, dwMilliSecsTimeout, state); -} - -static HRESULT WINAPI SinkFilter_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_SetSyncSource(This->nullRenderer, pClock); -} - -static HRESULT WINAPI SinkFilter_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_GetSyncSource(This->nullRenderer, ppClock); -} - -static HRESULT WINAPI SinkFilter_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - SinkEnumPins *sinkEnumPins = create_SinkEnumPins(This); - if (sinkEnumPins) { - *ppEnum = &sinkEnumPins->IEnumPins_iface; - return S_OK; - } - else - return E_OUTOFMEMORY; -} - -static HRESULT WINAPI SinkFilter_FindPin(IBaseFilter *iface, LPCWSTR id, IPin **ppPin) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - HRESULT hr = IBaseFilter_FindPin(This->nullRenderer, id, ppPin); - if (SUCCEEDED(hr)) { - IPin_Release(*ppPin); - *ppPin = &This->IPin_iface; - IPin_AddRef(&This->IPin_iface); - } - return hr; -} - -static HRESULT WINAPI SinkFilter_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_QueryFilterInfo(This->nullRenderer, pInfo); -} - -static HRESULT WINAPI SinkFilter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_JoinFilterGraph(This->nullRenderer, pGraph, pName); -} - -static HRESULT WINAPI SinkFilter_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo) -{ - SinkFilter *This = impl_from_SinkFilter_IBaseFilter(iface); - return IBaseFilter_QueryVendorInfo(This->nullRenderer, pVendorInfo); -} - -static const IBaseFilterVtbl SinkFilterVtbl = { - SinkFilter_QueryInterface, - SinkFilter_AddRef, - SinkFilter_Release, - SinkFilter_GetClassID, - SinkFilter_Stop, - SinkFilter_Pause, - SinkFilter_Run, - SinkFilter_GetState, - SinkFilter_SetSyncSource, - SinkFilter_GetSyncSource, - SinkFilter_EnumPins, - SinkFilter_FindPin, - SinkFilter_QueryFilterInfo, - SinkFilter_JoinFilterGraph, - SinkFilter_QueryVendorInfo -}; - -static HRESULT WINAPI SinkEnumPins_QueryInterface(IEnumPins *iface, REFIID riid, void **ppv) -{ - SinkEnumPins *This = impl_from_SinkFilter_IEnumPins(iface); - if(IsEqualIID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumPins_iface; - } else if(IsEqualIID(riid, &IID_IEnumPins)) { - *ppv = &This->IEnumPins_iface; - } else { - trace("no interface for %s\n", wine_dbgstr_guid(riid)); - *ppv = NULL; - return E_NOINTERFACE; - } - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI SinkEnumPins_AddRef(IEnumPins *iface) -{ - SinkEnumPins *This = impl_from_SinkFilter_IEnumPins(iface); - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI SinkEnumPins_Release(IEnumPins *iface) -{ - SinkEnumPins *This = impl_from_SinkFilter_IEnumPins(iface); - ULONG ref; - ref = InterlockedDecrement(&This->ref); - if (ref == 0) - { - IBaseFilter_Release(&This->filter->IBaseFilter_iface); - CoTaskMemFree(This); - } - return ref; -} - -static HRESULT WINAPI SinkEnumPins_Next(IEnumPins *iface, ULONG cPins, IPin **ppPins, ULONG *pcFetched) -{ - SinkEnumPins *This = impl_from_SinkFilter_IEnumPins(iface); - if (!ppPins) - return E_POINTER; - if (cPins > 1 && !pcFetched) - return E_INVALIDARG; - if (pcFetched) - *pcFetched = 0; - if (cPins == 0) - return S_OK; - if (This->index == 0) { - ppPins[0] = &This->filter->IPin_iface; - IPin_AddRef(&This->filter->IPin_iface); - ++This->index; - if (pcFetched) - *pcFetched = 1; - return S_OK; - } - return S_FALSE; -} - -static HRESULT WINAPI SinkEnumPins_Skip(IEnumPins *iface, ULONG cPins) -{ - SinkEnumPins *This = impl_from_SinkFilter_IEnumPins(iface); - if (This->index + cPins >= 1) - return S_FALSE; - This->index += cPins; - return S_OK; -} - -static HRESULT WINAPI SinkEnumPins_Reset(IEnumPins *iface) -{ - SinkEnumPins *This = impl_from_SinkFilter_IEnumPins(iface); - This->index = 0; - return S_OK; -} - -static HRESULT WINAPI SinkEnumPins_Clone(IEnumPins *iface, IEnumPins **ppEnum) -{ - SinkEnumPins *This = impl_from_SinkFilter_IEnumPins(iface); - SinkEnumPins *clone = create_SinkEnumPins(This->filter); - if (clone == NULL) - return E_OUTOFMEMORY; - clone->index = This->index; - *ppEnum = &clone->IEnumPins_iface; - return S_OK; -} - -static const IEnumPinsVtbl SinkEnumPinsVtbl = { - SinkEnumPins_QueryInterface, - SinkEnumPins_AddRef, - SinkEnumPins_Release, - SinkEnumPins_Next, - SinkEnumPins_Skip, - SinkEnumPins_Reset, - SinkEnumPins_Clone -}; - -static SinkEnumPins* create_SinkEnumPins(SinkFilter *filter) -{ - SinkEnumPins *This; - This = CoTaskMemAlloc(sizeof(*This)); - if (This == NULL) { - return NULL; - } - This->IEnumPins_iface.lpVtbl = &SinkEnumPinsVtbl; - This->ref = 1; - This->index = 0; - This->filter = filter; - IBaseFilter_AddRef(&filter->IBaseFilter_iface); - return This; -} - -static HRESULT WINAPI SinkPin_QueryInterface(IPin *iface, REFIID riid, void **ppv) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - if(IsEqualIID(riid, &IID_IUnknown)) { - *ppv = &This->IPin_iface; - } else if(IsEqualIID(riid, &IID_IPin)) { - *ppv = &This->IPin_iface; - } else if(IsEqualIID(riid, &IID_IMemInputPin)) { - *ppv = &This->IMemInputPin_iface; - } else { - trace("no interface for %s\n", wine_dbgstr_guid(riid)); - *ppv = NULL; - return E_NOINTERFACE; - } - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI SinkPin_AddRef(IPin *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IBaseFilter_AddRef(&This->IBaseFilter_iface); -} - -static ULONG WINAPI SinkPin_Release(IPin *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IBaseFilter_Release(&This->IBaseFilter_iface); -} - -static HRESULT WINAPI SinkPin_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_Connect(This->nullRendererPin, pReceivePin, pmt); -} - -static HRESULT WINAPI SinkPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_MEDIA_TYPE *pmt) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_ReceiveConnection(This->nullRendererPin, connector, pmt); -} - -static HRESULT WINAPI SinkPin_Disconnect(IPin *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_Disconnect(This->nullRendererPin); -} - -static HRESULT WINAPI SinkPin_ConnectedTo(IPin *iface, IPin **pPin) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_ConnectedTo(This->nullRendererPin, pPin); -} - -static HRESULT WINAPI SinkPin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_ConnectionMediaType(This->nullRendererPin, pmt); -} - -static HRESULT WINAPI SinkPin_QueryPinInfo(IPin *iface, PIN_INFO *pInfo) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - HRESULT hr = IPin_QueryPinInfo(This->nullRendererPin, pInfo); - if (SUCCEEDED(hr)) { - IBaseFilter_Release(pInfo->pFilter); - pInfo->pFilter = &This->IBaseFilter_iface; - IBaseFilter_AddRef(&This->IBaseFilter_iface); - } - return hr; -} - -static HRESULT WINAPI SinkPin_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_QueryDirection(This->nullRendererPin, pPinDir); -} - -static HRESULT WINAPI SinkPin_QueryId(IPin *iface, LPWSTR *id) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_QueryId(This->nullRendererPin, id); -} - -static HRESULT WINAPI SinkPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_QueryAccept(This->nullRendererPin, pmt); -} - -static HRESULT WINAPI SinkPin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_EnumMediaTypes(This->nullRendererPin, ppEnum); -} - -static HRESULT WINAPI SinkPin_QueryInternalConnections(IPin *iface, IPin **apPin, ULONG *nPin) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_QueryInternalConnections(This->nullRendererPin, apPin, nPin); -} - -static HRESULT WINAPI SinkPin_EndOfStream(IPin *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_EndOfStream(This->nullRendererPin); -} - -static HRESULT WINAPI SinkPin_BeginFlush(IPin *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_BeginFlush(This->nullRendererPin); -} - -static HRESULT WINAPI SinkPin_EndFlush(IPin *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_EndFlush(This->nullRendererPin); -} - -static HRESULT WINAPI SinkPin_NewSegment(IPin *iface, REFERENCE_TIME tStart, - REFERENCE_TIME tStop, double dRate) -{ - SinkFilter *This = impl_from_SinkFilter_IPin(iface); - return IPin_NewSegment(This->nullRendererPin, tStart, tStop, dRate); -} - -static const IPinVtbl SinkPinVtbl = { - SinkPin_QueryInterface, - SinkPin_AddRef, - SinkPin_Release, - SinkPin_Connect, - SinkPin_ReceiveConnection, - SinkPin_Disconnect, - SinkPin_ConnectedTo, - SinkPin_ConnectionMediaType, - SinkPin_QueryPinInfo, - SinkPin_QueryDirection, - SinkPin_QueryId, - SinkPin_QueryAccept, - SinkPin_EnumMediaTypes, - SinkPin_QueryInternalConnections, - SinkPin_EndOfStream, - SinkPin_BeginFlush, - SinkPin_EndFlush, - SinkPin_NewSegment -}; - -static HRESULT WINAPI SinkMemInputPin_QueryInterface(IMemInputPin *iface, REFIID riid, void **ppv) -{ - SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface); - return IPin_QueryInterface(&This->IPin_iface, riid, ppv); -} - -static ULONG WINAPI SinkMemInputPin_AddRef(IMemInputPin *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface); - return IBaseFilter_AddRef(&This->IBaseFilter_iface); -} - -static ULONG WINAPI SinkMemInputPin_Release(IMemInputPin *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface); - return IBaseFilter_Release(&This->IBaseFilter_iface); -} - -static HRESULT WINAPI SinkMemInputPin_GetAllocator(IMemInputPin *iface, IMemAllocator **ppAllocator) -{ - SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface); - ok(0, "SmartTeeFilter never calls IMemInputPin_GetAllocator()\n"); - return IMemInputPin_GetAllocator(This->nullRendererMemInputPin, ppAllocator); -} - -static HRESULT WINAPI SinkMemInputPin_NotifyAllocator(IMemInputPin *iface, IMemAllocator *pAllocator, - BOOL bReadOnly) -{ - SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface); - This->allocator = pAllocator; - IMemAllocator_AddRef(This->allocator); - ok(bReadOnly, "bReadOnly isn't supposed to be FALSE\n"); - return IMemInputPin_NotifyAllocator(This->nullRendererMemInputPin, pAllocator, bReadOnly); -} - -static HRESULT WINAPI SinkMemInputPin_GetAllocatorRequirements(IMemInputPin *iface, - ALLOCATOR_PROPERTIES *pProps) -{ - SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface); - ok(0, "SmartTeeFilter never calls IMemInputPin_GetAllocatorRequirements()\n"); - return IMemInputPin_GetAllocatorRequirements(This->nullRendererMemInputPin, pProps); -} - -static HRESULT WINAPI SinkMemInputPin_Receive(IMemInputPin *iface, IMediaSample *pSample) -{ - LONG samplesProcessed; - todo_wine ok(0, "SmartTeeFilter never calls IMemInputPin_Receive(), only IMemInputPin_ReceiveMultiple()\n"); - return IMemInputPin_ReceiveMultiple(iface, &pSample, 1, &samplesProcessed); -} - -static HRESULT WINAPI SinkMemInputPin_ReceiveMultiple(IMemInputPin *iface, IMediaSample **pSamples, - LONG nSamples, LONG *nSamplesProcessed) -{ - SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface); - IMediaSample *pSample; - REFERENCE_TIME startTime, endTime; - HRESULT hr; - ok(nSamples == 1, "expected 1 sample, got %d\n", nSamples); - pSample = pSamples[0]; - hr = IMediaSample_GetTime(pSample, &startTime, &endTime); - if (This->isCapture) - ok(SUCCEEDED(hr), "IMediaSample_GetTime() from Capture pin failed, hr=0x%08x\n", hr); - else - ok(hr == VFW_E_SAMPLE_TIME_NOT_SET, "IMediaSample_GetTime() from Preview pin returned hr=0x%08x\n", hr); - This->receiveThreadId = GetCurrentThreadId(); - SetEvent(event); - return IMemInputPin_ReceiveMultiple(This->nullRendererMemInputPin, pSamples, - nSamples, nSamplesProcessed); -} - -static HRESULT WINAPI SinkMemInputPin_ReceiveCanBlock(IMemInputPin *iface) -{ - SinkFilter *This = impl_from_SinkFilter_IMemInputPin(iface); - return IMemInputPin_ReceiveCanBlock(This->nullRendererMemInputPin); -} - -static const IMemInputPinVtbl SinkMemInputPinVtbl = { - SinkMemInputPin_QueryInterface, - SinkMemInputPin_AddRef, - SinkMemInputPin_Release, - SinkMemInputPin_GetAllocator, - SinkMemInputPin_NotifyAllocator, - SinkMemInputPin_GetAllocatorRequirements, - SinkMemInputPin_Receive, - SinkMemInputPin_ReceiveMultiple, - SinkMemInputPin_ReceiveCanBlock -}; - -static SinkFilter* create_SinkFilter(BOOL isCapture) -{ - SinkFilter *This = NULL; - HRESULT hr; - This = CoTaskMemAlloc(sizeof(*This)); - if (This) { - memset(This, 0, sizeof(*This)); - This->IBaseFilter_iface.lpVtbl = &SinkFilterVtbl; - This->ref = 1; - This->isCapture = isCapture; - This->IPin_iface.lpVtbl = &SinkPinVtbl; - This->IMemInputPin_iface.lpVtbl = &SinkMemInputPinVtbl; - hr = CoCreateInstance(&CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, - &IID_IBaseFilter, (LPVOID*)&This->nullRenderer); - if (SUCCEEDED(hr)) { - IEnumPins *enumPins = NULL; - hr = IBaseFilter_EnumPins(This->nullRenderer, &enumPins); - if (SUCCEEDED(hr)) { - hr = IEnumPins_Next(enumPins, 1, &This->nullRendererPin, NULL); - IEnumPins_Release(enumPins); - if (SUCCEEDED(hr)) { - hr = IPin_QueryInterface(This->nullRendererPin, &IID_IMemInputPin, - (LPVOID*)&This->nullRendererMemInputPin); - if (SUCCEEDED(hr)) - return This; - IPin_Release(This->nullRendererPin); - } - } - IBaseFilter_Release(This->nullRenderer); - } - CoTaskMemFree(This); - } - return NULL; -} - -typedef struct { - IBaseFilter IBaseFilter_iface; - LONG ref; - IPin IPin_iface; - IKsPropertySet IKsPropertySet_iface; - CRITICAL_SECTION cs; - FILTER_STATE state; - IReferenceClock *referenceClock; - FILTER_INFO filterInfo; - AM_MEDIA_TYPE mediaType; - VIDEOINFOHEADER videoInfo; - WAVEFORMATEX audioInfo; - IPin *connectedTo; - IMemInputPin *memInputPin; - IMemAllocator *allocator; - DWORD mediaThreadId; -} SourceFilter; - -typedef struct { - IEnumPins IEnumPins_iface; - LONG ref; - ULONG index; - SourceFilter *filter; -} SourceEnumPins; - -typedef struct { - IEnumMediaTypes IEnumMediaTypes_iface; - LONG ref; - ULONG index; - SourceFilter *filter; -} SourceEnumMediaTypes; - -static const WCHAR sourcePinName[] = {'C','a','p','t','u','r','e',0}; - -static SourceEnumPins* create_SourceEnumPins(SourceFilter *filter); -static SourceEnumMediaTypes* create_SourceEnumMediaTypes(SourceFilter *filter); - -static inline SourceFilter* impl_from_SourceFilter_IBaseFilter(IBaseFilter *iface) -{ - return CONTAINING_RECORD(iface, SourceFilter, IBaseFilter_iface); -} - -static inline SourceFilter* impl_from_SourceFilter_IPin(IPin *iface) -{ - return CONTAINING_RECORD(iface, SourceFilter, IPin_iface); -} - -static inline SourceFilter* impl_from_SourceFilter_IKsPropertySet(IKsPropertySet *iface) -{ - return CONTAINING_RECORD(iface, SourceFilter, IKsPropertySet_iface); -} - -static inline SourceEnumPins* impl_from_SourceFilter_IEnumPins(IEnumPins *iface) -{ - return CONTAINING_RECORD(iface, SourceEnumPins, IEnumPins_iface); -} - -static inline SourceEnumMediaTypes* impl_from_SourceFilter_IEnumMediaTypes(IEnumMediaTypes *iface) -{ - return CONTAINING_RECORD(iface, SourceEnumMediaTypes, IEnumMediaTypes_iface); -} - -static HRESULT WINAPI SourceFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - if(IsEqualIID(riid, &IID_IUnknown)) { - *ppv = &This->IBaseFilter_iface; - } else if(IsEqualIID(riid, &IID_IPersist)) { - *ppv = &This->IBaseFilter_iface; - } else if(IsEqualIID(riid, &IID_IMediaFilter)) { - *ppv = &This->IBaseFilter_iface; - } else if(IsEqualIID(riid, &IID_IBaseFilter)) { - *ppv = &This->IBaseFilter_iface; - } else { - trace("no interface for %s\n", wine_dbgstr_guid(riid)); - *ppv = NULL; - return E_NOINTERFACE; - } - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI SourceFilter_AddRef(IBaseFilter *iface) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI SourceFilter_Release(IBaseFilter *iface) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - ULONG ref = InterlockedDecrement(&This->ref); - if(!ref) { - if (This->referenceClock) - IReferenceClock_Release(This->referenceClock); - if (This->connectedTo) - IPin_Disconnect(&This->IPin_iface); - DeleteCriticalSection(&This->cs); - CoTaskMemFree(This); - } - return ref; -} - -static HRESULT WINAPI SourceFilter_GetClassID(IBaseFilter *iface, CLSID *pClassID) -{ - *pClassID = CLSID_VfwCapture; - return S_OK; -} - -static HRESULT WINAPI SourceFilter_Stop(IBaseFilter *iface) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - EnterCriticalSection(&This->cs); - IMemAllocator_Decommit(This->allocator); - This->state = State_Stopped; - LeaveCriticalSection(&This->cs); - return S_OK; -} - -static HRESULT WINAPI SourceFilter_Pause(IBaseFilter *iface) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - EnterCriticalSection(&This->cs); - This->state = State_Paused; - LeaveCriticalSection(&This->cs); - return S_OK; -} - -static DWORD WINAPI media_thread(LPVOID param) -{ - SourceFilter *This = (SourceFilter*) param; - HRESULT hr; - IMediaSample *sample = NULL; - REFERENCE_TIME startTime; - REFERENCE_TIME endTime; - BYTE *buffer; - - hr = IMemAllocator_GetBuffer(This->allocator, &sample, NULL, NULL, 0); - ok(SUCCEEDED(hr), "IMemAllocator_GetBuffer() failed, hr=0x%08x\n", hr); - if (SUCCEEDED(hr)) { - startTime = 10; - endTime = 20; - hr = IMediaSample_SetTime(sample, &startTime, &endTime); - ok(SUCCEEDED(hr), "IMediaSample_SetTime() failed, hr=0x%08x\n", hr); - hr = IMediaSample_SetMediaType(sample, &This->mediaType); - ok(SUCCEEDED(hr), "IMediaSample_SetMediaType() failed, hr=0x%08x\n", hr); - - hr = IMediaSample_GetPointer(sample, &buffer); - ok(SUCCEEDED(hr), "IMediaSample_GetPointer() failed, hr=0x%08x\n", hr); - if (SUCCEEDED(hr)) { - /* 10 by 10 pixel 32 RGB */ - int i; - for (i = 0; i < 100; i++) - buffer[4*i] = i; - } - - hr = IMemInputPin_Receive(This->memInputPin, sample); - ok(SUCCEEDED(hr), "delivering sample to SmartTeeFilter's Input pin failed, hr=0x%08x\n", hr); - - IMediaSample_Release(sample); - } - return 0; -} - -static HRESULT WINAPI SourceFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - HRESULT hr; - EnterCriticalSection(&This->cs); - hr = IMemAllocator_Commit(This->allocator); - if (SUCCEEDED(hr)) { - HANDLE thread = CreateThread(NULL, 0, media_thread, This, 0, &This->mediaThreadId); - ok(thread != NULL, "couldn't create media thread, GetLastError()=%u\n", GetLastError()); - if (thread != NULL) { - CloseHandle(thread); - This->state = State_Running; - } else { - IMemAllocator_Decommit(This->allocator); - hr = E_FAIL; - } - } - LeaveCriticalSection(&This->cs); - return hr; -} - -static HRESULT WINAPI SourceFilter_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *state) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - EnterCriticalSection(&This->cs); - *state = This->state; - LeaveCriticalSection(&This->cs); - return S_OK; -} - -static HRESULT WINAPI SourceFilter_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - EnterCriticalSection(&This->cs); - if (This->referenceClock) - IReferenceClock_Release(This->referenceClock); - This->referenceClock = pClock; - if (This->referenceClock) - IReferenceClock_AddRef(This->referenceClock); - LeaveCriticalSection(&This->cs); - return S_OK; -} - -static HRESULT WINAPI SourceFilter_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - EnterCriticalSection(&This->cs); - *ppClock = This->referenceClock; - if (This->referenceClock) - IReferenceClock_AddRef(This->referenceClock); - LeaveCriticalSection(&This->cs); - return S_OK; -} - -static HRESULT WINAPI SourceFilter_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - SourceEnumPins *sourceEnumPins = create_SourceEnumPins(This); - if (sourceEnumPins) { - *ppEnum = &sourceEnumPins->IEnumPins_iface; - return S_OK; - } - else - return E_OUTOFMEMORY; -} - -static HRESULT WINAPI SourceFilter_FindPin(IBaseFilter *iface, LPCWSTR id, IPin **ppPin) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - if (ppPin == NULL) - return E_POINTER; - *ppPin = NULL; - if (lstrcmpW(id, sourcePinName) == 0) { - *ppPin = &This->IPin_iface; - IPin_AddRef(&This->IPin_iface); - return S_OK; - } - return VFW_E_NOT_FOUND; -} - -static HRESULT WINAPI SourceFilter_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - if (!pInfo) - return E_POINTER; - EnterCriticalSection(&This->cs); - *pInfo = This->filterInfo; - if (This->filterInfo.pGraph) - IFilterGraph_AddRef(This->filterInfo.pGraph); - LeaveCriticalSection(&This->cs); - return S_OK; -} - -static HRESULT WINAPI SourceFilter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName) -{ - SourceFilter *This = impl_from_SourceFilter_IBaseFilter(iface); - EnterCriticalSection(&This->cs); - if (pName) - lstrcpyW(This->filterInfo.achName, pName); - else - This->filterInfo.achName[0] = 0; - This->filterInfo.pGraph = pGraph; - LeaveCriticalSection(&This->cs); - return S_OK; -} - -static HRESULT WINAPI SourceFilter_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo) -{ - return E_NOTIMPL; -} - -static const IBaseFilterVtbl SourceFilterVtbl = { - SourceFilter_QueryInterface, - SourceFilter_AddRef, - SourceFilter_Release, - SourceFilter_GetClassID, - SourceFilter_Stop, - SourceFilter_Pause, - SourceFilter_Run, - SourceFilter_GetState, - SourceFilter_SetSyncSource, - SourceFilter_GetSyncSource, - SourceFilter_EnumPins, - SourceFilter_FindPin, - SourceFilter_QueryFilterInfo, - SourceFilter_JoinFilterGraph, - SourceFilter_QueryVendorInfo -}; - -static HRESULT WINAPI SourceEnumPins_QueryInterface(IEnumPins *iface, REFIID riid, void **ppv) -{ - SourceEnumPins *This = impl_from_SourceFilter_IEnumPins(iface); - if(IsEqualIID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumPins_iface; - } else if(IsEqualIID(riid, &IID_IEnumPins)) { - *ppv = &This->IEnumPins_iface; - } else { - trace("no interface for %s\n", wine_dbgstr_guid(riid)); - *ppv = NULL; - return E_NOINTERFACE; - } - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI SourceEnumPins_AddRef(IEnumPins *iface) -{ - SourceEnumPins *This = impl_from_SourceFilter_IEnumPins(iface); - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI SourceEnumPins_Release(IEnumPins *iface) -{ - SourceEnumPins *This = impl_from_SourceFilter_IEnumPins(iface); - ULONG ref; - ref = InterlockedDecrement(&This->ref); - if (ref == 0) - { - IBaseFilter_Release(&This->filter->IBaseFilter_iface); - CoTaskMemFree(This); - } - return ref; -} - -static HRESULT WINAPI SourceEnumPins_Next(IEnumPins *iface, ULONG cPins, IPin **ppPins, ULONG *pcFetched) -{ - SourceEnumPins *This = impl_from_SourceFilter_IEnumPins(iface); - if (!ppPins) - return E_POINTER; - if (cPins > 1 && !pcFetched) - return E_INVALIDARG; - if (pcFetched) - *pcFetched = 0; - if (cPins == 0) - return S_OK; - if (This->index == 0) { - ppPins[0] = &This->filter->IPin_iface; - IPin_AddRef(&This->filter->IPin_iface); - ++This->index; - if (pcFetched) - *pcFetched = 1; - return S_OK; - } - return S_FALSE; -} - -static HRESULT WINAPI SourceEnumPins_Skip(IEnumPins *iface, ULONG cPins) -{ - SourceEnumPins *This = impl_from_SourceFilter_IEnumPins(iface); - if (This->index + cPins >= 1) - return S_FALSE; - This->index += cPins; - return S_OK; -} - -static HRESULT WINAPI SourceEnumPins_Reset(IEnumPins *iface) -{ - SourceEnumPins *This = impl_from_SourceFilter_IEnumPins(iface); - This->index = 0; - return S_OK; -} - -static HRESULT WINAPI SourceEnumPins_Clone(IEnumPins *iface, IEnumPins **ppEnum) -{ - SourceEnumPins *This = impl_from_SourceFilter_IEnumPins(iface); - SourceEnumPins *clone = create_SourceEnumPins(This->filter); - if (clone == NULL) - return E_OUTOFMEMORY; - clone->index = This->index; - *ppEnum = &clone->IEnumPins_iface; - return S_OK; -} - -static const IEnumPinsVtbl SourceEnumPinsVtbl = { - SourceEnumPins_QueryInterface, - SourceEnumPins_AddRef, - SourceEnumPins_Release, - SourceEnumPins_Next, - SourceEnumPins_Skip, - SourceEnumPins_Reset, - SourceEnumPins_Clone -}; - -static SourceEnumPins* create_SourceEnumPins(SourceFilter *filter) -{ - SourceEnumPins *This; - This = CoTaskMemAlloc(sizeof(*This)); - if (This == NULL) { - return NULL; - } - This->IEnumPins_iface.lpVtbl = &SourceEnumPinsVtbl; - This->ref = 1; - This->index = 0; - This->filter = filter; - IBaseFilter_AddRef(&filter->IBaseFilter_iface); - return This; -} - -static HRESULT WINAPI SourceEnumMediaTypes_QueryInterface(IEnumMediaTypes *iface, REFIID riid, void **ppv) -{ - SourceEnumMediaTypes *This = impl_from_SourceFilter_IEnumMediaTypes(iface); - if(IsEqualIID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumMediaTypes_iface; - } else if(IsEqualIID(riid, &IID_IEnumMediaTypes)) { - *ppv = &This->IEnumMediaTypes_iface; - } else { - trace("no interface for %s\n", wine_dbgstr_guid(riid)); - *ppv = NULL; - return E_NOINTERFACE; - } - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI SourceEnumMediaTypes_AddRef(IEnumMediaTypes *iface) -{ - SourceEnumMediaTypes *This = impl_from_SourceFilter_IEnumMediaTypes(iface); - return InterlockedIncrement(&This->ref); -} - -static ULONG WINAPI SourceEnumMediaTypes_Release(IEnumMediaTypes *iface) -{ - SourceEnumMediaTypes *This = impl_from_SourceFilter_IEnumMediaTypes(iface); - ULONG ref; - ref = InterlockedDecrement(&This->ref); - if (ref == 0) - { - IBaseFilter_Release(&This->filter->IBaseFilter_iface); - CoTaskMemFree(This); - } - return ref; -} - -static HRESULT WINAPI SourceEnumMediaTypes_Next(IEnumMediaTypes *iface, ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched) -{ - SourceEnumMediaTypes *This = impl_from_SourceFilter_IEnumMediaTypes(iface); - if (!ppMediaTypes) - return E_POINTER; - if (cMediaTypes > 1 && !pcFetched) - return E_INVALIDARG; - if (pcFetched) - *pcFetched = 0; - if (cMediaTypes == 0) - return S_OK; - if (This->index == 0) { - ppMediaTypes[0] = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); - if (ppMediaTypes[0]) { - *ppMediaTypes[0] = This->filter->mediaType; - ppMediaTypes[0]->pbFormat = CoTaskMemAlloc(This->filter->mediaType.cbFormat); - if (ppMediaTypes[0]->pbFormat) { - memcpy(ppMediaTypes[0]->pbFormat, This->filter->mediaType.pbFormat, This->filter->mediaType.cbFormat); - ++This->index; - if (pcFetched) - *pcFetched = 1; - return S_OK; - } - CoTaskMemFree(ppMediaTypes[0]); - } - return E_OUTOFMEMORY; - } - return S_FALSE; -} - -static HRESULT WINAPI SourceEnumMediaTypes_Skip(IEnumMediaTypes *iface, ULONG cMediaTypes) -{ - SourceEnumMediaTypes *This = impl_from_SourceFilter_IEnumMediaTypes(iface); - This->index += cMediaTypes; - if (This->index >= 1) - return S_FALSE; - return S_OK; -} - -static HRESULT WINAPI SourceEnumMediaTypes_Reset(IEnumMediaTypes *iface) -{ - SourceEnumMediaTypes *This = impl_from_SourceFilter_IEnumMediaTypes(iface); - This->index = 0; - return S_OK; -} - -static HRESULT WINAPI SourceEnumMediaTypes_Clone(IEnumMediaTypes *iface, IEnumMediaTypes **ppEnum) -{ - SourceEnumMediaTypes *This = impl_from_SourceFilter_IEnumMediaTypes(iface); - SourceEnumMediaTypes *clone = create_SourceEnumMediaTypes(This->filter); - if (clone == NULL) - return E_OUTOFMEMORY; - clone->index = This->index; - *ppEnum = &clone->IEnumMediaTypes_iface; - return S_OK; -} - -static const IEnumMediaTypesVtbl SourceEnumMediaTypesVtbl = { - SourceEnumMediaTypes_QueryInterface, - SourceEnumMediaTypes_AddRef, - SourceEnumMediaTypes_Release, - SourceEnumMediaTypes_Next, - SourceEnumMediaTypes_Skip, - SourceEnumMediaTypes_Reset, - SourceEnumMediaTypes_Clone -}; - -static SourceEnumMediaTypes* create_SourceEnumMediaTypes(SourceFilter *filter) -{ - SourceEnumMediaTypes *This; - This = CoTaskMemAlloc(sizeof(*This)); - if (This == NULL) { - return NULL; - } - This->IEnumMediaTypes_iface.lpVtbl = &SourceEnumMediaTypesVtbl; - This->ref = 1; - This->index = 0; - This->filter = filter; - IBaseFilter_AddRef(&filter->IBaseFilter_iface); - return This; -} - -static HRESULT WINAPI SourcePin_QueryInterface(IPin *iface, REFIID riid, void **ppv) -{ - SourceFilter *This = impl_from_SourceFilter_IPin(iface); - if(IsEqualIID(riid, &IID_IUnknown)) { - *ppv = &This->IPin_iface; - } else if(IsEqualIID(riid, &IID_IPin)) { - *ppv = &This->IPin_iface; - } else if(IsEqualIID(riid, &IID_IKsPropertySet)) { - *ppv = &This->IKsPropertySet_iface; - } else { - trace("no interface for %s\n", wine_dbgstr_guid(riid)); - *ppv = NULL; - return E_NOINTERFACE; - } - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI SourcePin_AddRef(IPin *iface) -{ - SourceFilter *This = impl_from_SourceFilter_IPin(iface); - return IBaseFilter_AddRef(&This->IBaseFilter_iface); -} - -static ULONG WINAPI SourcePin_Release(IPin *iface) -{ - SourceFilter *This = impl_from_SourceFilter_IPin(iface); - return IBaseFilter_Release(&This->IBaseFilter_iface); -} - -static HRESULT WINAPI SourcePin_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) -{ - SourceFilter *This = impl_from_SourceFilter_IPin(iface); - HRESULT hr; - - if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->majortype, &MEDIATYPE_Video)) - return VFW_E_TYPE_NOT_ACCEPTED; - if (pmt && !IsEqualGUID(&pmt->subtype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &MEDIASUBTYPE_RGB32)) - return VFW_E_TYPE_NOT_ACCEPTED; - if (pmt && !IsEqualGUID(&pmt->formattype, &GUID_NULL)) - return VFW_E_TYPE_NOT_ACCEPTED; - hr = IPin_ReceiveConnection(pReceivePin, &This->IPin_iface, &This->mediaType); - ok(SUCCEEDED(hr), "SmartTeeFilter's Input pin's IPin_ReceiveConnection() failed with 0x%08x\n", hr); - if (SUCCEEDED(hr)) { - EnterCriticalSection(&This->cs); - hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (void**)&This->memInputPin); - if (SUCCEEDED(hr)) { - hr = IMemInputPin_GetAllocator(This->memInputPin, &This->allocator); - ok(SUCCEEDED(hr), "couldn't get allocator from SmartTeeFilter, hr=0x%08x\n", hr); - if (SUCCEEDED(hr)) { - ALLOCATOR_PROPERTIES requested, actual; - ZeroMemory(&requested, sizeof(ALLOCATOR_PROPERTIES)); - IMemInputPin_GetAllocatorRequirements(This->memInputPin, &requested); - if (requested.cBuffers < 3) requested.cBuffers = 3; - if (requested.cbBuffer < 4096) requested.cbBuffer = 4096; - if (requested.cbAlign < 1) requested.cbAlign = 1; - if (requested.cbPrefix < 0) requested.cbPrefix = 0; - hr = IMemAllocator_SetProperties(This->allocator, &requested, &actual); - if (SUCCEEDED(hr)) { - hr = IMemInputPin_NotifyAllocator(This->memInputPin, This->allocator, FALSE); - if (SUCCEEDED(hr)) { - This->connectedTo = pReceivePin; - IPin_AddRef(pReceivePin); - } - } - if (FAILED(hr)) { - IMemAllocator_Release(This->allocator); - This->allocator = NULL; - } - } - if (FAILED(hr)) { - IMemInputPin_Release(This->memInputPin); - This->memInputPin = NULL; - } - } - LeaveCriticalSection(&This->cs); - - if (FAILED(hr)) - IPin_Disconnect(pReceivePin); - } - return hr; -} - -static HRESULT WINAPI SourcePin_ReceiveConnection(IPin *iface, IPin *connector, const AM_MEDIA_TYPE *pmt) -{ - return E_UNEXPECTED; -} - -static HRESULT WINAPI SourcePin_Disconnect(IPin *iface) -{ - SourceFilter *This = impl_from_SourceFilter_IPin(iface); - HRESULT hr; - EnterCriticalSection(&This->cs); - if (This->connectedTo) { - if (This->state == State_Stopped) { - IMemAllocator_Release(This->allocator); - This->allocator = NULL; - IMemInputPin_Release(This->memInputPin); - This->memInputPin = NULL; - IPin_Release(This->connectedTo); - This->connectedTo = NULL; - hr = S_OK; - } - else - hr = VFW_E_NOT_STOPPED; - } else - hr = S_FALSE; - LeaveCriticalSection(&This->cs); - return hr; -} - -static HRESULT WINAPI SourcePin_ConnectedTo(IPin *iface, IPin **pPin) -{ - SourceFilter *This = impl_from_SourceFilter_IPin(iface); - HRESULT hr; - if (!pPin) - return E_POINTER; - EnterCriticalSection(&This->cs); - if (This->connectedTo) { - *pPin = This->connectedTo; - IPin_AddRef(This->connectedTo); - hr = S_OK; - } else - hr = VFW_E_NOT_CONNECTED; - LeaveCriticalSection(&This->cs); - return hr; -} - -static HRESULT WINAPI SourcePin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt) -{ - SourceFilter *This = impl_from_SourceFilter_IPin(iface); - HRESULT hr; - if (!pmt) - return E_POINTER; - EnterCriticalSection(&This->cs); - if (This->connectedTo) { - *pmt = This->mediaType; - pmt->pbFormat = CoTaskMemAlloc(sizeof(This->videoInfo)); - if (pmt->pbFormat) { - memcpy(pmt->pbFormat, &This->videoInfo, sizeof(This->videoInfo)); - hr = S_OK; - } else { - memset(pmt, 0, sizeof(*pmt)); - hr = E_OUTOFMEMORY; - } - } else { - memset(pmt, 0, sizeof(*pmt)); - hr = VFW_E_NOT_CONNECTED; - } - LeaveCriticalSection(&This->cs); - return hr; -} - -static HRESULT WINAPI SourcePin_QueryPinInfo(IPin *iface, PIN_INFO *pInfo) -{ - SourceFilter *This = impl_from_SourceFilter_IPin(iface); - if (!pInfo) - return E_POINTER; - lstrcpyW(pInfo->achName, sourcePinName); - pInfo->dir = PINDIR_OUTPUT; - pInfo->pFilter = &This->IBaseFilter_iface; - IBaseFilter_AddRef(&This->IBaseFilter_iface); - return S_OK; -} - -static HRESULT WINAPI SourcePin_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir) -{ - if (!pPinDir) - return E_POINTER; - *pPinDir = PINDIR_OUTPUT; - return S_OK; -} - -static HRESULT WINAPI SourcePin_QueryId(IPin *iface, LPWSTR *id) -{ - if (!id) - return E_POINTER; - *id = CoTaskMemAlloc((lstrlenW(sourcePinName) + 1)*sizeof(WCHAR)); - if (*id) { - lstrcpyW(*id, sourcePinName); - return S_OK; - } - return E_OUTOFMEMORY; -} - -static HRESULT WINAPI SourcePin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt) -{ - return S_OK; -} - -static HRESULT WINAPI SourcePin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum) -{ - SourceFilter *This = impl_from_SourceFilter_IPin(iface); - SourceEnumMediaTypes *sourceEnumMediaTypes = create_SourceEnumMediaTypes(This); - if (sourceEnumMediaTypes) { - *ppEnum = &sourceEnumMediaTypes->IEnumMediaTypes_iface; - return S_OK; - } - else - return E_OUTOFMEMORY; -} - -static HRESULT WINAPI SourcePin_QueryInternalConnections(IPin *iface, IPin **apPin, ULONG *nPin) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI SourcePin_EndOfStream(IPin *iface) -{ - return E_UNEXPECTED; -} - -static HRESULT WINAPI SourcePin_BeginFlush(IPin *iface) -{ - return E_UNEXPECTED; -} - -static HRESULT WINAPI SourcePin_EndFlush(IPin *iface) -{ - return E_UNEXPECTED; -} - -static HRESULT WINAPI SourcePin_NewSegment(IPin *iface, REFERENCE_TIME tStart, - REFERENCE_TIME tStop, double dRate) -{ - return S_OK; -} - -static const IPinVtbl SourcePinVtbl = { - SourcePin_QueryInterface, - SourcePin_AddRef, - SourcePin_Release, - SourcePin_Connect, - SourcePin_ReceiveConnection, - SourcePin_Disconnect, - SourcePin_ConnectedTo, - SourcePin_ConnectionMediaType, - SourcePin_QueryPinInfo, - SourcePin_QueryDirection, - SourcePin_QueryId, - SourcePin_QueryAccept, - SourcePin_EnumMediaTypes, - SourcePin_QueryInternalConnections, - SourcePin_EndOfStream, - SourcePin_BeginFlush, - SourcePin_EndFlush, - SourcePin_NewSegment -}; - -static HRESULT WINAPI SourceKSP_QueryInterface(IKsPropertySet *iface, REFIID riid, LPVOID *ppv) -{ - SourceFilter *This = impl_from_SourceFilter_IKsPropertySet(iface); - return IPin_QueryInterface(&This->IPin_iface, riid, ppv); -} - -static ULONG WINAPI SourceKSP_AddRef(IKsPropertySet *iface) -{ - SourceFilter *This = impl_from_SourceFilter_IKsPropertySet(iface); - return IBaseFilter_AddRef(&This->IBaseFilter_iface); -} - -static ULONG WINAPI SourceKSP_Release(IKsPropertySet *iface) -{ - SourceFilter *This = impl_from_SourceFilter_IKsPropertySet(iface); - return IBaseFilter_Release(&This->IBaseFilter_iface); -} - -static HRESULT WINAPI SourceKSP_Set(IKsPropertySet *iface, REFGUID guidPropSet, DWORD dwPropID, - LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData) -{ - SourceFilter *This = impl_from_SourceFilter_IKsPropertySet(iface); - trace("(%p)->(%s, %u, %p, %u, %p, %u): stub\n", This, wine_dbgstr_guid(guidPropSet), - dwPropID, pInstanceData, cbInstanceData, pPropData, cbPropData); - return E_NOTIMPL; -} - -static HRESULT WINAPI SourceKSP_Get(IKsPropertySet *iface, REFGUID guidPropSet, DWORD dwPropID, - LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, - DWORD cbPropData, DWORD *pcbReturned) -{ - SourceFilter *This = impl_from_SourceFilter_IKsPropertySet(iface); - trace("(%p)->(%s, %u, %p, %u, %p, %u, %p)\n", This, wine_dbgstr_guid(guidPropSet), - dwPropID, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned); - if (IsEqualIID(guidPropSet, &ROPSETID_Pin)) { - if (pcbReturned) - *pcbReturned = sizeof(GUID); - if (pPropData) { - LPGUID guid = pPropData; - if (cbPropData >= sizeof(GUID)) - *guid = PIN_CATEGORY_CAPTURE; - } else { - if (!pcbReturned) - return E_POINTER; - } - return S_OK; - } - return E_PROP_SET_UNSUPPORTED; -} - -static HRESULT WINAPI SourceKSP_QuerySupported(IKsPropertySet *iface, REFGUID guidPropSet, - DWORD dwPropID, DWORD *pTypeSupport) -{ - SourceFilter *This = impl_from_SourceFilter_IKsPropertySet(iface); - trace("(%p)->(%s, %u, %p): stub\n", This, wine_dbgstr_guid(guidPropSet), - dwPropID, pTypeSupport); - return E_NOTIMPL; -} - -static const IKsPropertySetVtbl SourceKSPVtbl = -{ - SourceKSP_QueryInterface, - SourceKSP_AddRef, - SourceKSP_Release, - SourceKSP_Set, - SourceKSP_Get, - SourceKSP_QuerySupported -}; - -static SourceFilter* create_SourceFilter(void) -{ - SourceFilter *This = NULL; - This = CoTaskMemAlloc(sizeof(*This)); - if (This) { - memset(This, 0, sizeof(*This)); - This->IBaseFilter_iface.lpVtbl = &SourceFilterVtbl; - This->ref = 1; - This->IPin_iface.lpVtbl = &SourcePinVtbl; - This->IKsPropertySet_iface.lpVtbl = &SourceKSPVtbl; - InitializeCriticalSection(&This->cs); - return This; - } - return NULL; -} - -static SourceFilter* create_video_SourceFilter(void) -{ - SourceFilter *This = create_SourceFilter(); - if (!This) - return NULL; - This->mediaType.majortype = MEDIATYPE_Video; - This->mediaType.subtype = MEDIASUBTYPE_RGB32; - This->mediaType.bFixedSizeSamples = FALSE; - This->mediaType.bTemporalCompression = FALSE; - This->mediaType.lSampleSize = 0; - This->mediaType.formattype = FORMAT_VideoInfo; - This->mediaType.pUnk = NULL; - This->mediaType.cbFormat = sizeof(VIDEOINFOHEADER); - This->mediaType.pbFormat = (BYTE*) &This->videoInfo; - This->videoInfo.dwBitRate = 1000000; - This->videoInfo.dwBitErrorRate = 0; - This->videoInfo.AvgTimePerFrame = 400000; - This->videoInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - This->videoInfo.bmiHeader.biWidth = 10; - This->videoInfo.bmiHeader.biHeight = 10; - This->videoInfo.bmiHeader.biPlanes = 1; - This->videoInfo.bmiHeader.biBitCount = 32; - This->videoInfo.bmiHeader.biCompression = BI_RGB; - This->videoInfo.bmiHeader.biSizeImage = 0; - This->videoInfo.bmiHeader.biXPelsPerMeter = 96; - This->videoInfo.bmiHeader.biYPelsPerMeter = 96; - This->videoInfo.bmiHeader.biClrUsed = 0; - This->videoInfo.bmiHeader.biClrImportant = 0; - return This; -} - -static void test_smart_tee_filter_in_graph(IBaseFilter *smartTeeFilter, IPin *inputPin, - IPin *capturePin, IPin *previewPin) -{ - HRESULT hr; - IGraphBuilder *graphBuilder = NULL; - IMediaControl *mediaControl = NULL; - SourceFilter *sourceFilter = NULL; - SinkFilter *captureSinkFilter = NULL; - SinkFilter *previewSinkFilter = NULL; - DWORD endTime; - - hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, - (LPVOID*)&graphBuilder); - ok(SUCCEEDED(hr), "couldn't create graph builder, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - - hr = IGraphBuilder_AddFilter(graphBuilder, smartTeeFilter, NULL); - ok(SUCCEEDED(hr), "couldn't add smart tee filter to graph, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - - captureSinkFilter = create_SinkFilter(TRUE); - if (captureSinkFilter == NULL) { - skip("couldn't create capture sink filter\n"); - goto end; - } - hr = IGraphBuilder_AddFilter(graphBuilder, &captureSinkFilter->IBaseFilter_iface, NULL); - if (FAILED(hr)) { - skip("couldn't add capture sink filter to graph, hr=0x%08x\n", hr); - goto end; - } - - previewSinkFilter = create_SinkFilter(FALSE); - if (previewSinkFilter == NULL) { - skip("couldn't create preview sink filter\n"); - goto end; - } - hr = IGraphBuilder_AddFilter(graphBuilder, &previewSinkFilter->IBaseFilter_iface, NULL); - if (FAILED(hr)) { - skip("couldn't add preview sink filter to graph, hr=0x%08x\n", hr); - goto end; - } - - hr = IGraphBuilder_Connect(graphBuilder, capturePin, &captureSinkFilter->IPin_iface); - ok(hr == VFW_E_NOT_CONNECTED, "connecting Capture pin without first connecting Input pin returned 0x%08x\n", hr); - hr = IGraphBuilder_Connect(graphBuilder, previewPin, &previewSinkFilter->IPin_iface); - ok(hr == VFW_E_NOT_CONNECTED, "connecting Preview pin without first connecting Input pin returned 0x%08x\n", hr); - - sourceFilter = create_video_SourceFilter(); - if (sourceFilter == NULL) { - skip("couldn't create source filter\n"); - goto end; - } - hr = IGraphBuilder_AddFilter(graphBuilder, &sourceFilter->IBaseFilter_iface, NULL); - ok(SUCCEEDED(hr), "couldn't add source filter to graph, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - - hr = IGraphBuilder_Connect(graphBuilder, &sourceFilter->IPin_iface, inputPin); - ok(SUCCEEDED(hr), "couldn't connect source filter to Input pin, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - hr = IGraphBuilder_Connect(graphBuilder, capturePin, &captureSinkFilter->IPin_iface); - ok(SUCCEEDED(hr), "couldn't connect Capture pin to sink, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - hr = IGraphBuilder_Connect(graphBuilder, previewPin, &previewSinkFilter->IPin_iface); - ok(SUCCEEDED(hr), "couldn't connect Preview pin to sink, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - - ok(sourceFilter->allocator == captureSinkFilter->allocator, "input and capture allocators don't match\n"); - ok(sourceFilter->allocator == previewSinkFilter->allocator, "input and preview allocators don't match\n"); - - hr = IGraphBuilder_QueryInterface(graphBuilder, &IID_IMediaControl, (void**)&mediaControl); - ok(SUCCEEDED(hr), "couldn't get IMediaControl interface from IGraphBuilder, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - hr = IMediaControl_Run(mediaControl); - ok(SUCCEEDED(hr), "IMediaControl_Run() failed, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - - endTime = GetTickCount() + 5000; - while (previewSinkFilter->receiveThreadId == 0 || captureSinkFilter->receiveThreadId == 0) { - DWORD now = GetTickCount(); - if (now < endTime) - WaitForSingleObject(event, endTime - now); - else - break; - } - if (previewSinkFilter->receiveThreadId != 0 && captureSinkFilter->receiveThreadId != 0) { - todo_wine ok(sourceFilter->mediaThreadId != captureSinkFilter->receiveThreadId, - "sending thread should != capture receiving thread\n"); - todo_wine ok(sourceFilter->mediaThreadId != previewSinkFilter->receiveThreadId, - "sending thread should != preview receiving thread\n"); - todo_wine ok(captureSinkFilter->receiveThreadId != previewSinkFilter->receiveThreadId, - "capture receiving thread should != preview receiving thread\n"); - } else { - ok(0, "timeout: threads did not receive sample in time\n"); - } - - IMediaControl_Stop(mediaControl); - -end: - if (mediaControl) - IMediaControl_Release(mediaControl); - if (graphBuilder) - IGraphBuilder_Release(graphBuilder); - if (sourceFilter) - IBaseFilter_Release(&sourceFilter->IBaseFilter_iface); - if (captureSinkFilter) - IBaseFilter_Release(&captureSinkFilter->IBaseFilter_iface); - if (previewSinkFilter) - IBaseFilter_Release(&previewSinkFilter->IBaseFilter_iface); -} - -static void test_smart_tee_filter(void) -{ - HRESULT hr; - IBaseFilter *smartTeeFilter = NULL; - IEnumPins *enumPins = NULL; - IPin *pin; - IPin *inputPin = NULL; - IPin *capturePin = NULL; - IPin *previewPin = NULL; - FILTER_INFO filterInfo; - int pinNumber = 0; - IMemInputPin *memInputPin = NULL; - - hr = CoCreateInstance(&CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER, - &IID_IBaseFilter, (void**)&smartTeeFilter); - ok(SUCCEEDED(hr), "couldn't create smart tee filter, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - - hr = IBaseFilter_QueryFilterInfo(smartTeeFilter, &filterInfo); - ok(SUCCEEDED(hr), "QueryFilterInfo failed, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - - ok(!*filterInfo.achName, - "filter's name is meant to be empty but it's %s\n", wine_dbgstr_w(filterInfo.achName)); - - hr = IBaseFilter_EnumPins(smartTeeFilter, &enumPins); - ok(SUCCEEDED(hr), "cannot enum filter pins, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - - while (IEnumPins_Next(enumPins, 1, &pin, NULL) == S_OK) - { - if (pinNumber == 0) - { - inputPin = pin; - IPin_AddRef(inputPin); - } - else if (pinNumber == 1) - { - capturePin = pin; - IPin_AddRef(capturePin); - } - else if (pinNumber == 2) - { - previewPin = pin; - IPin_AddRef(previewPin); - } - else - ok(0, "pin %d isn't supposed to exist\n", pinNumber); - - IPin_Release(pin); - pinNumber++; - } - - ok(inputPin && capturePin && previewPin, "couldn't find all pins\n"); - if (!(inputPin && capturePin && previewPin)) - goto end; - - hr = IPin_QueryInterface(inputPin, &IID_IMemInputPin, (void**)&memInputPin); - ok(SUCCEEDED(hr), "couldn't get mem input pin, hr=0x%08x\n", hr); - if (FAILED(hr)) - goto end; - hr = IMemInputPin_ReceiveCanBlock(memInputPin); - ok(hr == S_OK, "unexpected IMemInputPin_ReceiveCanBlock() = 0x%08x\n", hr); - - test_smart_tee_filter_in_graph(smartTeeFilter, inputPin, capturePin, previewPin); - -end: - if (inputPin) - IPin_Release(inputPin); - if (capturePin) - IPin_Release(capturePin); - if (previewPin) - IPin_Release(previewPin); - if (smartTeeFilter) - IBaseFilter_Release(smartTeeFilter); - if (enumPins) - IEnumPins_Release(enumPins); - if (memInputPin) - IMemInputPin_Release(memInputPin); -} - static void test_unconnected_filter_state(void) { IBaseFilter *filter = create_smart_tee(); @@ -3066,8 +1415,6 @@ START_TEST(smartteefilter) test_connect_pin(); test_streaming();
- test_smart_tee_filter(); - CloseHandle(event); CoUninitialize(); }