Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/avisplit.c | 10 +++++++--- dlls/quartz/dsoundrender.c | 2 +- dlls/quartz/mpegsplit.c | 2 +- dlls/quartz/vmr9.c | 23 ++++++++++++++--------- 4 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/dlls/quartz/avisplit.c b/dlls/quartz/avisplit.c index f55ebf2219..a422f45b8c 100644 --- a/dlls/quartz/avisplit.c +++ b/dlls/quartz/avisplit.c @@ -105,6 +105,11 @@ static inline AVISplitterImpl *impl_from_IMediaSeeking( IMediaSeeking *iface ) return CONTAINING_RECORD(iface, AVISplitterImpl, Parser.sourceSeeking.IMediaSeeking_iface); }
+static inline AVISplitterImpl *impl_from_IBaseFilter(IBaseFilter *iface) +{ + return CONTAINING_RECORD(iface, AVISplitterImpl, Parser.filter.IBaseFilter_iface); +} + /* The threading stuff cries for an explanation * * PullPin starts processing and calls AVISplitter_first_request @@ -1025,6 +1030,7 @@ static HRESULT AVISplitter_Disconnect(LPVOID iface); static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin, ALLOCATOR_PROPERTIES *props) { PullPin *This = impl_PullPin_from_IPin(iface); + AVISplitterImpl *pAviSplit = impl_from_IBaseFilter(This->pin.pinInfo.pFilter); HRESULT hr; RIFFLIST list; LONGLONG pos = 0; /* in bytes */ @@ -1034,8 +1040,6 @@ static HRESULT AVISplitter_InputPin_PreConnect(IPin * iface, IPin * pConnectPin, ULONG x; DWORD indexes;
- AVISplitterImpl * pAviSplit = (AVISplitterImpl *)This->pin.pinInfo.pFilter; - hr = IAsyncReader_SyncRead(This->pReader, pos, sizeof(list), (BYTE *)&list); pos += sizeof(list);
@@ -1264,7 +1268,7 @@ static HRESULT AVISplitter_Disconnect(LPVOID iface)
static ULONG WINAPI AVISplitter_Release(IBaseFilter *iface) { - AVISplitterImpl *This = (AVISplitterImpl *)iface; + AVISplitterImpl *This = impl_from_IBaseFilter(iface); ULONG ref;
ref = InterlockedDecrement(&This->Parser.filter.refCount); diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index b9eb14952e..31862d23b3 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -759,8 +759,8 @@ static ULONG WINAPI DSoundRender_Release(IBaseFilter * iface)
static HRESULT WINAPI DSoundRender_Pause(IBaseFilter * iface) { + DSoundRenderImpl *This = impl_from_IBaseFilter(iface); HRESULT hr = S_OK; - DSoundRenderImpl *This = (DSoundRenderImpl *)iface;
TRACE("(%p/%p)->()\n", This, iface);
diff --git a/dlls/quartz/mpegsplit.c b/dlls/quartz/mpegsplit.c index 226fcacff5..c4cf93b13d 100644 --- a/dlls/quartz/mpegsplit.c +++ b/dlls/quartz/mpegsplit.c @@ -485,7 +485,7 @@ static HRESULT MPEGSplitter_init_audio(MPEGSplitterImpl *This, const BYTE *heade static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props) { PullPin *pPin = impl_PullPin_from_IPin(iface); - MPEGSplitterImpl *This = (MPEGSplitterImpl*)pPin->pin.pinInfo.pFilter; + MPEGSplitterImpl *This = impl_from_IBaseFilter(pPin->pin.pinInfo.pFilter); HRESULT hr; LONGLONG pos = 0; /* in bytes */ BYTE header[10]; diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c index 3d22f123b1..847dc40b04 100644 --- a/dlls/quartz/vmr9.c +++ b/dlls/quartz/vmr9.c @@ -206,6 +206,11 @@ static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorE
static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv);
+static inline struct quartz_vmr *impl_from_IBaseFilter(IBaseFilter *iface) +{ + return CONTAINING_RECORD(iface, struct quartz_vmr, renderer.filter.IBaseFilter_iface); +} + static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data, DWORD size) { @@ -286,7 +291,7 @@ static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *
static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample) { - struct quartz_vmr *This = (struct quartz_vmr*)iface; + struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface); LPBYTE pbSrcStream = NULL; long cbSrcStream = 0; REFERENCE_TIME tStart, tStop; @@ -351,7 +356,7 @@ static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pS
static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt) { - struct quartz_vmr *This = (struct quartz_vmr*)iface; + struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat) return S_FALSE; @@ -445,7 +450,7 @@ static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
static VOID WINAPI VMR9_OnStartStreaming(BaseRenderer* iface) { - struct quartz_vmr *This = (struct quartz_vmr*)iface; + struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
TRACE("(%p)\n", This);
@@ -463,7 +468,7 @@ static VOID WINAPI VMR9_OnStartStreaming(BaseRenderer* iface)
static VOID WINAPI VMR9_OnStopStreaming(BaseRenderer* iface) { - struct quartz_vmr *This = (struct quartz_vmr*)iface; + struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
TRACE("(%p)\n", This);
@@ -481,7 +486,7 @@ static HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample
static HRESULT WINAPI VMR9_CompleteConnect(BaseRenderer *This, IPin *pReceivePin) { - struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This; + struct quartz_vmr *pVMR9 = impl_from_IBaseFilter(&This->filter.IBaseFilter_iface); HRESULT hr;
TRACE("(%p)\n", This); @@ -495,7 +500,7 @@ static HRESULT WINAPI VMR9_CompleteConnect(BaseRenderer *This, IPin *pReceivePin
static HRESULT WINAPI VMR9_BreakConnect(BaseRenderer *This) { - struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This; + struct quartz_vmr *pVMR9 = impl_from_IBaseFilter(&This->filter.IBaseFilter_iface); HRESULT hr = S_OK;
if (!pVMR9->mode) @@ -863,7 +868,7 @@ static const IUnknownVtbl IInner_VTable =
static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) { - struct quartz_vmr *This = (struct quartz_vmr*)iface; + struct quartz_vmr *This = impl_from_IBaseFilter(iface);
if (This->bAggregatable) This->bUnkOuterValid = TRUE; @@ -893,7 +898,7 @@ static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVO
static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface) { - struct quartz_vmr *This = (struct quartz_vmr*)iface; + struct quartz_vmr *This = impl_from_IBaseFilter(iface); LONG ret;
if (This->outer_unk && This->bUnkOuterValid) @@ -908,7 +913,7 @@ static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface)
static ULONG WINAPI VMR9_Release(IBaseFilter * iface) { - struct quartz_vmr *This = (struct quartz_vmr*)iface; + struct quartz_vmr *This = impl_from_IBaseFilter(iface); LONG ret;
if (This->outer_unk && This->bUnkOuterValid)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/samplegrabber.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/dlls/qedit/samplegrabber.c b/dlls/qedit/samplegrabber.c index 9474a5826c..56947a1f6b 100644 --- a/dlls/qedit/samplegrabber.c +++ b/dlls/qedit/samplegrabber.c @@ -672,31 +672,22 @@ SampleGrabber_ISampleGrabber_SetCallback(ISampleGrabber *iface, ISampleGrabberCB return S_OK; }
- -/* SampleGrabber implementation of IMemInputPin interface */ - -/* IUnknown */ -static HRESULT WINAPI -SampleGrabber_IMemInputPin_QueryInterface(IMemInputPin *iface, REFIID riid, void **ppv) +static HRESULT WINAPI SampleGrabber_IMemInputPin_QueryInterface(IMemInputPin *iface, REFIID iid, void **out) { - SG_Impl *This = impl_from_IMemInputPin(iface); - return IUnknown_QueryInterface(This->outer_unk, riid, ppv); + SG_Impl *filter = impl_from_IMemInputPin(iface); + return IPin_QueryInterface(&filter->pin_in.IPin_iface, iid, out); }
-/* IUnknown */ -static ULONG WINAPI -SampleGrabber_IMemInputPin_AddRef(IMemInputPin *iface) +static ULONG WINAPI SampleGrabber_IMemInputPin_AddRef(IMemInputPin *iface) { - SG_Impl *This = impl_from_IMemInputPin(iface); - return IUnknown_AddRef(This->outer_unk); + SG_Impl *filter = impl_from_IMemInputPin(iface); + return IPin_AddRef(&filter->pin_in.IPin_iface); }
-/* IUnknown */ -static ULONG WINAPI -SampleGrabber_IMemInputPin_Release(IMemInputPin *iface) +static ULONG WINAPI SampleGrabber_IMemInputPin_Release(IMemInputPin *iface) { - SG_Impl *This = impl_from_IMemInputPin(iface); - return IUnknown_Release(This->outer_unk); + SG_Impl *filter = impl_from_IMemInputPin(iface); + return IPin_Release(&filter->pin_in.IPin_iface); }
/* IMemInputPin */
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/amstream/amstream_private.h | 1 + dlls/amstream/mediastreamfilter.c | 167 +++++++++++++++++++++++++++++- dlls/amstream/tests/amstream.c | 16 +-- 3 files changed, 174 insertions(+), 10 deletions(-)
diff --git a/dlls/amstream/amstream_private.h b/dlls/amstream/amstream_private.h index 8f25b8e248..3cbc5c8e64 100644 --- a/dlls/amstream/amstream_private.h +++ b/dlls/amstream/amstream_private.h @@ -32,6 +32,7 @@ #include "mmstream.h" #include "austream.h" #include "amstream.h" +#include "wine/heap.h"
HRESULT AM_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; HRESULT AMAudioData_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; diff --git a/dlls/amstream/mediastreamfilter.c b/dlls/amstream/mediastreamfilter.c index a61d1e767c..e9f98b63ca 100644 --- a/dlls/amstream/mediastreamfilter.c +++ b/dlls/amstream/mediastreamfilter.c @@ -34,6 +34,142 @@
WINE_DEFAULT_DEBUG_CHANNEL(amstream);
+struct enum_pins +{ + IEnumPins IEnumPins_iface; + LONG refcount; + + IPin **pins; + unsigned int count, index; +}; + +static const IEnumPinsVtbl enum_pins_vtbl; + +static struct enum_pins *impl_from_IEnumPins(IEnumPins *iface) +{ + return CONTAINING_RECORD(iface, struct enum_pins, IEnumPins_iface); +} + +static HRESULT WINAPI enum_pins_QueryInterface(IEnumPins *iface, REFIID iid, void **out) +{ + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IEnumPins)) + { + IEnumPins_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI enum_pins_AddRef(IEnumPins *iface) +{ + struct enum_pins *enum_pins = impl_from_IEnumPins(iface); + ULONG refcount = InterlockedIncrement(&enum_pins->refcount); + TRACE("%p increasing refcount to %u.\n", enum_pins, refcount); + return refcount; +} + +static ULONG WINAPI enum_pins_Release(IEnumPins *iface) +{ + struct enum_pins *enum_pins = impl_from_IEnumPins(iface); + ULONG refcount = InterlockedDecrement(&enum_pins->refcount); + unsigned int i; + + TRACE("%p decreasing refcount to %u.\n", enum_pins, refcount); + if (!refcount) + { + for (i = 0; i < enum_pins->count; ++i) + IPin_Release(enum_pins->pins[i]); + heap_free(enum_pins->pins); + heap_free(enum_pins); + } + return refcount; +} + +static HRESULT WINAPI enum_pins_Next(IEnumPins *iface, ULONG count, IPin **pins, ULONG *ret_count) +{ + struct enum_pins *enum_pins = impl_from_IEnumPins(iface); + unsigned int i; + + TRACE("iface %p, count %u, pins %p, ret_count %p.\n", iface, count, pins, ret_count); + + if (!pins || (count > 1 && !ret_count)) + return E_POINTER; + + for (i = 0; i < count && enum_pins->index < enum_pins->count; ++i) + { + IPin_AddRef(pins[i] = enum_pins->pins[i]); + enum_pins->index++; + } + + if (ret_count) *ret_count = i; + return i == count ? S_OK : S_FALSE; +} + +static HRESULT WINAPI enum_pins_Skip(IEnumPins *iface, ULONG count) +{ + struct enum_pins *enum_pins = impl_from_IEnumPins(iface); + + TRACE("iface %p, count %u.\n", iface, count); + + enum_pins->index += count; + + return enum_pins->index >= enum_pins->count ? S_FALSE : S_OK; +} + +static HRESULT WINAPI enum_pins_Reset(IEnumPins *iface) +{ + struct enum_pins *enum_pins = impl_from_IEnumPins(iface); + + TRACE("iface %p.\n", iface); + + enum_pins->index = 0; + return S_OK; +} + +static HRESULT WINAPI enum_pins_Clone(IEnumPins *iface, IEnumPins **out) +{ + struct enum_pins *enum_pins = impl_from_IEnumPins(iface); + struct enum_pins *object; + unsigned int i; + + TRACE("iface %p, out %p.\n", iface, out); + + if (!(object = heap_alloc(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IEnumPins_iface.lpVtbl = &enum_pins_vtbl; + object->refcount = 1; + object->count = enum_pins->count; + object->index = enum_pins->index; + if (!(object->pins = heap_alloc(enum_pins->count * sizeof(*object->pins)))) + { + heap_free(object); + return E_OUTOFMEMORY; + } + for (i = 0; i < enum_pins->count; ++i) + IPin_AddRef(object->pins[i] = enum_pins->pins[i]); + + *out = &object->IEnumPins_iface; + return S_OK; +} + +static const IEnumPinsVtbl enum_pins_vtbl = +{ + enum_pins_QueryInterface, + enum_pins_AddRef, + enum_pins_Release, + enum_pins_Next, + enum_pins_Skip, + enum_pins_Reset, + enum_pins_Clone, +}; + typedef struct { BaseFilter filter; ULONG nb_streams; @@ -153,8 +289,35 @@ static HRESULT WINAPI MediaStreamFilterImpl_GetSyncSource(IMediaStreamFilter *if
static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, IEnumPins **enum_pins) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_EnumPins(&This->filter.IBaseFilter_iface, enum_pins); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + struct enum_pins *object; + unsigned int i; + + TRACE("iface %p, enum_pins %p.\n", iface, enum_pins); + + if (!enum_pins) + return E_POINTER; + + if (!(object = heap_alloc(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IEnumPins_iface.lpVtbl = &enum_pins_vtbl; + object->refcount = 1; + object->count = filter->nb_streams; + object->index = 0; + if (!(object->pins = heap_alloc(filter->nb_streams * sizeof(*object->pins)))) + { + heap_free(object); + return E_OUTOFMEMORY; + } + for (i = 0; i < filter->nb_streams; ++i) + { + if (FAILED(IAMMediaStream_QueryInterface(filter->streams[i], &IID_IPin, (void **)&object->pins[i]))) + WARN("Stream %p does not support IPin.\n", filter->streams[i]); + } + + *enum_pins = &object->IEnumPins_iface; + return S_OK; }
static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter *iface, LPCWSTR id, IPin **pin) diff --git a/dlls/amstream/tests/amstream.c b/dlls/amstream/tests/amstream.c index 148e6bdc78..72157755d1 100644 --- a/dlls/amstream/tests/amstream.c +++ b/dlls/amstream/tests/amstream.c @@ -652,7 +652,7 @@ static void test_enum_pins(void) hr = IMediaStreamFilter_EnumPins(filter, &enum1); ok(hr == S_OK, "Got hr %#x.\n", hr); ref = get_refcount(filter); - todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ok(ref == 3, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref);
@@ -666,7 +666,7 @@ static void test_enum_pins(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Skip(enum1, 0); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IEnumPins_Skip(enum1, 1); ok(hr == S_FALSE, "Got hr %#x.\n", hr); @@ -682,7 +682,7 @@ static void test_enum_pins(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum1, 1, pins, NULL); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr);
IEnumPins_Release(enum1);
@@ -690,7 +690,7 @@ static void test_enum_pins(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = get_refcount(filter); - ok(ref == 4, "Got unexpected refcount %d.\n", ref); + todo_wine ok(ref == 4, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); @@ -700,7 +700,7 @@ static void test_enum_pins(void) ok(hr == S_OK, "Got hr %#x.\n", hr); ok(pins[0] == pin, "Expected pin %p, got %p.\n", pin, pins[0]); ref = get_refcount(filter); - ok(ref == 4, "Got unexpected refcount %d.\n", ref); + todo_wine ok(ref == 4, "Got unexpected refcount %d.\n", ref); ref = get_refcount(enum1); ok(ref == 1, "Got unexpected refcount %d.\n", ref); ref = get_refcount(pin); @@ -723,7 +723,7 @@ static void test_enum_pins(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum1, 2, pins, NULL); - todo_wine ok(hr == E_POINTER, "Got hr %#x.\n", hr); + ok(hr == E_POINTER, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum1, 2, pins, &count); ok(hr == S_FALSE, "Got hr %#x.\n", hr); @@ -741,7 +741,7 @@ static void test_enum_pins(void) ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IEnumPins_Skip(enum1, 1); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr);
hr = IEnumPins_Next(enum1, 1, pins, NULL); ok(hr == S_FALSE, "Got hr %#x.\n", hr); @@ -759,7 +759,7 @@ static void test_enum_pins(void) ok(!ref, "Got outstanding refcount %d.\n", ref); IMediaStream_Release(stream); ref = IPin_Release(pin); - todo_wine ok(!ref, "Got outstanding refcount %d.\n", ref); + ok(!ref, "Got outstanding refcount %d.\n", ref); }
static void test_find_pin(void)
In the long (or even short) term we probably want to decouple amstream from strmbase entirely. The fact that pins and filters belong to separate objects (and either one can even be provided by the application) prevents us from performing some helpful restructuring.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/amstream/mediastreamfilter.c | 225 +++++++++++++++++++----------- 1 file changed, 144 insertions(+), 81 deletions(-)
diff --git a/dlls/amstream/mediastreamfilter.c b/dlls/amstream/mediastreamfilter.c index e9f98b63ca..2daffeabdb 100644 --- a/dlls/amstream/mediastreamfilter.c +++ b/dlls/amstream/mediastreamfilter.c @@ -18,19 +18,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "wine/debug.h" - #define COBJMACROS - -#include "winbase.h" -#include "wingdi.h" -#include "dshow.h" - -#include "wine/strmbase.h" - #include "amstream_private.h" - -#include "ddstream.h" +#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(amstream);
@@ -171,18 +161,22 @@ static const IEnumPinsVtbl enum_pins_vtbl = };
typedef struct { - BaseFilter filter; + IMediaStreamFilter IMediaStreamFilter_iface; + LONG refcount; + CRITICAL_SECTION cs; + + IReferenceClock *clock; + WCHAR name[128]; + IFilterGraph *graph; ULONG nb_streams; IAMMediaStream** streams; } IMediaStreamFilterImpl;
static inline IMediaStreamFilterImpl *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface) { - return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, filter); + return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, IMediaStreamFilter_iface); }
-/*** IUnknown methods ***/ - static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *iface, REFIID riid, void **ret_iface) { TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ret_iface); @@ -207,47 +201,45 @@ static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *i
static ULONG WINAPI MediaStreamFilterImpl_AddRef(IMediaStreamFilter *iface) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - ULONG ref = BaseFilterImpl_AddRef(&This->filter.IBaseFilter_iface); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + ULONG refcount = InterlockedIncrement(&filter->refcount);
- TRACE("(%p)->(): new ref = %u\n", iface, ref); + TRACE("%p increasing refcount to %u.\n", iface, refcount);
- return ref; + return refcount; }
static ULONG WINAPI MediaStreamFilterImpl_Release(IMediaStreamFilter *iface) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - ULONG ref = InterlockedDecrement(&This->filter.refCount); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + ULONG refcount = InterlockedDecrement(&filter->refcount); + unsigned int i;
- TRACE("(%p)->(): new ref = %u\n", iface, ref); + TRACE("%p decreasing refcount to %u.\n", iface, refcount);
- if (!ref) + if (!refcount) { - ULONG i; - for (i = 0; i < This->nb_streams; i++) + for (i = 0; i < filter->nb_streams; ++i) { - IAMMediaStream_JoinFilter(This->streams[i], NULL); - IAMMediaStream_Release(This->streams[i]); + IAMMediaStream_JoinFilter(filter->streams[i], NULL); + IAMMediaStream_Release(filter->streams[i]); } - CoTaskMemFree(This->streams); - BaseFilter_Destroy(&This->filter); - HeapFree(GetProcessHeap(), 0, This); + heap_free(filter->streams); + if (filter->clock) + IReferenceClock_Release(filter->clock); + DeleteCriticalSection(&filter->cs); + heap_free(filter); }
- return ref; + return refcount; }
-/*** IPersist methods ***/ - static HRESULT WINAPI MediaStreamFilterImpl_GetClassID(IMediaStreamFilter *iface, CLSID *clsid) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_GetClassID(&This->filter.IBaseFilter_iface, clsid); + *clsid = CLSID_MediaStreamFilter; + return S_OK; }
-/*** IBaseFilter methods ***/ - static HRESULT WINAPI MediaStreamFilterImpl_Stop(IMediaStreamFilter *iface) { FIXME("(%p)->(): Stub!\n", iface); @@ -269,22 +261,48 @@ static HRESULT WINAPI MediaStreamFilterImpl_Run(IMediaStreamFilter *iface, REFER return E_NOTIMPL; }
-static HRESULT WINAPI MediaStreamFilterImpl_GetState(IMediaStreamFilter *iface, DWORD ms_timeout, FILTER_STATE *state) +static HRESULT WINAPI MediaStreamFilterImpl_GetState(IMediaStreamFilter *iface, DWORD timeout, FILTER_STATE *state) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_GetState(&This->filter.IBaseFilter_iface, ms_timeout, state); + FIXME("iface %p, timeout %u, state %p, stub!\n", iface, timeout, state); + + *state = State_Stopped; + return S_OK; }
static HRESULT WINAPI MediaStreamFilterImpl_SetSyncSource(IMediaStreamFilter *iface, IReferenceClock *clock) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_SetSyncSource(&This->filter.IBaseFilter_iface, clock); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + + TRACE("iface %p, clock %p.\n", iface, clock); + + EnterCriticalSection(&filter->cs); + + if (clock) + IReferenceClock_AddRef(clock); + if (filter->clock) + IReferenceClock_Release(filter->clock); + filter->clock = clock; + + LeaveCriticalSection(&filter->cs); + + return S_OK; }
static HRESULT WINAPI MediaStreamFilterImpl_GetSyncSource(IMediaStreamFilter *iface, IReferenceClock **clock) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_GetSyncSource(&This->filter.IBaseFilter_iface, clock); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + + TRACE("iface %p, clock %p.\n", iface, clock); + + EnterCriticalSection(&filter->cs); + + if (filter->clock) + IReferenceClock_AddRef(filter->clock); + *clock = filter->clock; + + LeaveCriticalSection(&filter->cs); + + return S_OK; }
static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, IEnumPins **enum_pins) @@ -295,6 +313,8 @@ static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface,
TRACE("iface %p, enum_pins %p.\n", iface, enum_pins);
+ EnterCriticalSection(&filter->cs); + if (!enum_pins) return E_POINTER;
@@ -316,32 +336,91 @@ static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter *iface, WARN("Stream %p does not support IPin.\n", filter->streams[i]); }
+ LeaveCriticalSection(&filter->cs); + *enum_pins = &object->IEnumPins_iface; return S_OK; }
-static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter *iface, LPCWSTR id, IPin **pin) +static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter *iface, const WCHAR *id, IPin **out) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_FindPin(&This->filter.IBaseFilter_iface, id, pin); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + unsigned int i; + WCHAR *ret_id; + IPin *pin; + + TRACE("iface %p, id %s, out %p.\n", iface, debugstr_w(id), out); + + EnterCriticalSection(&filter->cs); + + for (i = 0; i < filter->nb_streams; ++i) + { + if (FAILED(IAMMediaStream_QueryInterface(filter->streams[i], &IID_IPin, (void **)&pin))) + { + WARN("Stream %p does not support IPin.\n", filter->streams[i]); + continue; + } + + if (SUCCEEDED(IPin_QueryId(pin, &ret_id))) + { + if (!lstrcmpW(id, ret_id)) + { + CoTaskMemFree(ret_id); + *out = pin; + return S_OK; + } + CoTaskMemFree(ret_id); + } + IPin_Release(pin); + } + + LeaveCriticalSection(&filter->cs); + + return VFW_E_NOT_FOUND; }
static HRESULT WINAPI MediaStreamFilterImpl_QueryFilterInfo(IMediaStreamFilter *iface, FILTER_INFO *info) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_QueryFilterInfo(&This->filter.IBaseFilter_iface, info); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + + TRACE("iface %p, info %p.\n", iface, info); + + EnterCriticalSection(&filter->cs); + + lstrcpyW(info->achName, filter->name); + if (filter->graph) + IFilterGraph_AddRef(filter->graph); + info->pGraph = filter->graph; + + LeaveCriticalSection(&filter->cs); + + return S_OK; }
-static HRESULT WINAPI MediaStreamFilterImpl_JoinFilterGraph(IMediaStreamFilter *iface, IFilterGraph *graph, LPCWSTR name) +static HRESULT WINAPI MediaStreamFilterImpl_JoinFilterGraph(IMediaStreamFilter *iface, + IFilterGraph *graph, const WCHAR *name) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_JoinFilterGraph(&This->filter.IBaseFilter_iface, graph, name); + IMediaStreamFilterImpl *filter = impl_from_IMediaStreamFilter(iface); + + TRACE("iface %p, graph %p, name.%s.\n", iface, graph, debugstr_w(name)); + + EnterCriticalSection(&filter->cs); + + if (name) + lstrcpynW(filter->name, name, ARRAY_SIZE(filter->name)); + else + filter->name[0] = 0; + filter->graph = graph; + + LeaveCriticalSection(&filter->cs); + + return S_OK; }
static HRESULT WINAPI MediaStreamFilterImpl_QueryVendorInfo(IMediaStreamFilter *iface, LPWSTR *vendor_info) { - IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface); - return BaseFilterImpl_QueryVendorInfo(&This->filter.IBaseFilter_iface, vendor_info); + WARN("iface %p, vendor_info %p, stub!\n", iface, vendor_info); + return E_NOTIMPL; }
/*** IMediaStreamFilter methods ***/ @@ -470,40 +549,24 @@ static const IMediaStreamFilterVtbl MediaStreamFilter_Vtbl = MediaStreamFilterImpl_EndOfStream };
-static IPin* WINAPI MediaStreamFilterImpl_GetPin(BaseFilter *iface, int pos) +HRESULT MediaStreamFilter_create(IUnknown *outer, void **out) { - IMediaStreamFilterImpl* This = (IMediaStreamFilterImpl*)iface; + IMediaStreamFilterImpl *object;
- if (pos < This->nb_streams) - { - IPin *pin = NULL; - IAMMediaStream_QueryInterface(This->streams[pos], &IID_IPin, (void **)&pin); - return pin; - } - - return NULL; -} - -static const BaseFilterFuncTable BaseFuncTable = { - MediaStreamFilterImpl_GetPin, -}; + TRACE("outer %p, out %p.\n", outer, out);
-HRESULT MediaStreamFilter_create(IUnknown *pUnkOuter, void **ppObj) -{ - IMediaStreamFilterImpl* object; - - TRACE("(%p,%p)\n", pUnkOuter, ppObj); - - if( pUnkOuter ) + if (outer) return CLASS_E_NOAGGREGATION;
- object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMediaStreamFilterImpl)); - if (!object) + if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY;
- BaseFilter_Init(&object->filter, (IBaseFilterVtbl*)&MediaStreamFilter_Vtbl, &CLSID_MediaStreamFilter, (DWORD_PTR)(__FILE__ ": MediaStreamFilterImpl.csFilter"), &BaseFuncTable); - - *ppObj = &object->filter.IBaseFilter_iface; + object->IMediaStreamFilter_iface.lpVtbl = &MediaStreamFilter_Vtbl; + object->refcount = 1; + InitializeCriticalSection(&object->cs); + object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MediaStreamFilter.cs");
+ TRACE("Created media stream filter %p.\n", object); + *out = &object->IMediaStreamFilter_iface; return S_OK; }