Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/samplegrabber.c | 239 +++++++++++++------------------ dlls/qedit/tests/samplegrabber.c | 1 + 2 files changed, 104 insertions(+), 136 deletions(-)
diff --git a/dlls/qedit/samplegrabber.c b/dlls/qedit/samplegrabber.c index 9a67b31fb4..21634a145d 100644 --- a/dlls/qedit/samplegrabber.c +++ b/dlls/qedit/samplegrabber.c @@ -34,7 +34,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(qedit);
static const WCHAR pin_in_name[] = { 'I', 'n', 0 }; -static const WCHAR pin_out_name[] = { 'O', 'u', 't', 0 };
static IEnumMediaTypes *mediaenum_create(const AM_MEDIA_TYPE *mtype, BOOL past);
@@ -213,14 +212,17 @@ static inline SG_Pin *impl_from_IPin(IPin *iface) typedef struct _SG_Impl { struct strmbase_filter filter; ISampleGrabber ISampleGrabber_iface; + + struct strmbase_source source; /* IMediaSeeking and IMediaPosition are implemented by ISeekingPassThru */ - IUnknown* seekthru_unk; - AM_MEDIA_TYPE mtype; + IUnknown *seekthru_unk; + IMemInputPin *memOutput; + SG_Pin pin_in; - SG_Pin pin_out; + AM_MEDIA_TYPE mtype; IMemInputPin IMemInputPin_iface; IMemAllocator *allocator; - IMemInputPin *memOutput; + ISampleGrabberCB *grabberIface; LONG grabberMethod; LONG oneShot; @@ -280,7 +282,7 @@ static IPin *sample_grabber_get_pin(struct strmbase_filter *iface, unsigned int if (index == 0) return &filter->pin_in.IPin_iface; else if (index == 1) - return &filter->pin_out.IPin_iface; + return &filter->source.pin.IPin_iface; return NULL; }
@@ -609,8 +611,8 @@ SampleGrabber_IMemInputPin_Receive(IMemInputPin *iface, IMediaSample *sample) if (This->oneShot == OneShot_Wait) { This->oneShot = OneShot_Past; hr = S_FALSE; - if (This->pin_out.pair) - IPin_EndOfStream(This->pin_out.pair); + if (This->source.pin.peer) + IPin_EndOfStream(This->source.pin.peer); } return hr; } @@ -689,55 +691,6 @@ SampleGrabber_In_IPin_Connect(IPin *iface, IPin *receiver, const AM_MEDIA_TYPE * return E_UNEXPECTED; }
-/* IPin - output pin */ -static HRESULT WINAPI -SampleGrabber_Out_IPin_Connect(IPin *iface, IPin *receiver, const AM_MEDIA_TYPE *type) -{ - SG_Pin *This = impl_from_IPin(iface); - HRESULT hr; - - TRACE("(%p)->(%p, %p)\n", This, receiver, type); - if (!receiver) - return E_POINTER; - if (This->pair) - return VFW_E_ALREADY_CONNECTED; - if (This->sg->filter.state != State_Stopped) - return VFW_E_NOT_STOPPED; - if (type) { - TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n", - debugstr_guid(&type->majortype), debugstr_guid(&type->subtype), - type->lSampleSize, - debugstr_guid(&type->formattype), type->cbFormat); - if (!IsEqualGUID(&This->sg->mtype.majortype,&GUID_NULL) && - !IsEqualGUID(&This->sg->mtype.majortype,&type->majortype)) - return VFW_E_TYPE_NOT_ACCEPTED; - if (!IsEqualGUID(&This->sg->mtype.subtype,&MEDIASUBTYPE_None) && - !IsEqualGUID(&This->sg->mtype.subtype,&type->subtype)) - return VFW_E_TYPE_NOT_ACCEPTED; - if (!IsEqualGUID(&This->sg->mtype.formattype,&GUID_NULL) && - !IsEqualGUID(&This->sg->mtype.formattype,&FORMAT_None) && - !IsEqualGUID(&This->sg->mtype.formattype,&type->formattype)) - return VFW_E_TYPE_NOT_ACCEPTED; - } - else - type = &This->sg->mtype; - if (!IsEqualGUID(&type->formattype, &FORMAT_None) && - !IsEqualGUID(&type->formattype, &GUID_NULL) && - !type->pbFormat) - return VFW_E_TYPE_NOT_ACCEPTED; - hr = IPin_ReceiveConnection(receiver, &This->IPin_iface, type); - if (FAILED(hr)) - return hr; - This->pair = receiver; - if (This->sg->memOutput) { - IMemInputPin_Release(This->sg->memOutput); - This->sg->memOutput = NULL; - } - IPin_QueryInterface(receiver,&IID_IMemInputPin,(void **)&(This->sg->memOutput)); - TRACE("(%p) Accepted IPin %p, IMemInputPin %p\n", This, receiver, This->sg->memOutput); - return S_OK; -} - /* IPin - input pin */ static HRESULT WINAPI SampleGrabber_In_IPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_MEDIA_TYPE *type) @@ -785,14 +738,6 @@ SampleGrabber_In_IPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_M return S_OK; }
-/* IPin - output pin */ -static HRESULT WINAPI -SampleGrabber_Out_IPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_MEDIA_TYPE *mtype) -{ - WARN("(%p, %p): unexpected\n", connector, mtype); - return E_UNEXPECTED; -} - /* IPin - input pin */ static HRESULT WINAPI SampleGrabber_In_IPin_Disconnect(IPin *iface) @@ -809,26 +754,6 @@ SampleGrabber_In_IPin_Disconnect(IPin *iface) return S_FALSE; }
-/* IPin - output pin */ -static HRESULT WINAPI -SampleGrabber_Out_IPin_Disconnect(IPin *iface) -{ - SG_Pin *This = impl_from_IPin(iface); - - TRACE("(%p)->() pair = %p\n", This, This->pair); - if (This->sg->filter.state != State_Stopped) - return VFW_E_NOT_STOPPED; - if (This->pair) { - This->pair = NULL; - if (This->sg->memOutput) { - IMemInputPin_Release(This->sg->memOutput); - This->sg->memOutput = NULL; - } - return S_OK; - } - return S_FALSE; -} - /* IPin */ static HRESULT WINAPI SampleGrabber_IPin_ConnectedTo(IPin *iface, IPin **pin) @@ -943,8 +868,8 @@ SampleGrabber_In_IPin_QueryInternalConnections(IPin *iface, IPin **pins, ULONG * if (*nPins) { if (!pins) return E_POINTER; - IPin_AddRef(&This->sg->pin_out.IPin_iface); - *pins = &This->sg->pin_out.IPin_iface; + IPin_AddRef(&This->sg->source.pin.IPin_iface); + *pins = &This->sg->source.pin.IPin_iface; *nPins = 1; return S_OK; } @@ -952,16 +877,6 @@ SampleGrabber_In_IPin_QueryInternalConnections(IPin *iface, IPin **pins, ULONG * return S_FALSE; }
-/* IPin - output pin */ -static HRESULT WINAPI -SampleGrabber_Out_IPin_QueryInternalConnections(IPin *iface, IPin **pins, ULONG *nPins) -{ - WARN("(%p, %p): unexpected\n", pins, nPins); - if (nPins) - *nPins = 0; - return E_NOTIMPL; -} - /* IPin */ static HRESULT WINAPI SampleGrabber_IPin_EndOfStream(IPin *iface) @@ -1065,51 +980,105 @@ static const IPinVtbl IPin_In_VTable = SampleGrabber_IPin_NewSegment, };
-static HRESULT WINAPI sample_grabber_source_QueryInterface(IPin *iface, REFIID iid, void **out) +static inline SG_Impl *impl_from_source_pin(struct strmbase_pin *iface) { - SG_Pin *pin = impl_from_IPin(iface); + return CONTAINING_RECORD(iface, SG_Impl, source.pin); +}
- TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); +static HRESULT sample_grabber_source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out) +{ + SG_Impl *filter = impl_from_source_pin(iface);
- if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IPin)) - { - *out = iface; - } - else if (IsEqualGUID(iid, &IID_IMediaPosition) || IsEqualGUID(iid, &IID_IMediaSeeking)) + if (IsEqualGUID(iid, &IID_IMediaPosition) || IsEqualGUID(iid, &IID_IMediaSeeking)) + return IUnknown_QueryInterface(filter->seekthru_unk, iid, out); + else + return E_NOINTERFACE; +} + +static HRESULT sample_grabber_source_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt) +{ + return S_OK; +} + +static HRESULT sample_grabber_source_get_media_type(struct strmbase_pin *iface, + unsigned int index, AM_MEDIA_TYPE *mt) +{ + SG_Impl *filter = impl_from_source_pin(iface); + + if (!index) { - return IUnknown_QueryInterface(pin->sg->seekthru_unk, iid, out); + CopyMediaType(mt, &filter->mtype); + return S_OK; } - else + return VFW_S_NO_MORE_ITEMS; +} + +static HRESULT WINAPI sample_grabber_source_AttemptConnection(struct strmbase_source *iface, + IPin *peer, const AM_MEDIA_TYPE *mt) +{ + SG_Impl *filter = impl_from_source_pin(&iface->pin); + HRESULT hr; + + if (filter->source.pin.peer) + return VFW_E_ALREADY_CONNECTED; + if (filter->filter.state != State_Stopped) + return VFW_E_NOT_STOPPED; + if (!IsEqualGUID(&mt->majortype, &filter->mtype.majortype)) + return VFW_E_TYPE_NOT_ACCEPTED; + if (!IsEqualGUID(&mt->subtype, &filter->mtype.subtype)) + return VFW_E_TYPE_NOT_ACCEPTED; + if (!IsEqualGUID(&mt->formattype, &FORMAT_None) + && !IsEqualGUID(&mt->formattype, &GUID_NULL) + && !IsEqualGUID(&mt->formattype, &filter->mtype.majortype)) + return VFW_E_TYPE_NOT_ACCEPTED; + if (!IsEqualGUID(&mt->formattype, &FORMAT_None) + && !IsEqualGUID(&mt->formattype, &GUID_NULL) + && !mt->pbFormat) + return VFW_E_TYPE_NOT_ACCEPTED; + + IPin_AddRef(filter->source.pin.peer = peer); + CopyMediaType(&filter->source.pin.mt, mt); + if (SUCCEEDED(hr = IPin_ReceiveConnection(peer, &filter->source.pin.IPin_iface, mt))) + hr = IPin_QueryInterface(peer, &IID_IMemInputPin, (void **)&filter->source.pMemInputPin); + + if (FAILED(hr)) { - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - *out = NULL; - return E_NOINTERFACE; + IPin_Release(filter->source.pin.peer); + filter->source.pin.peer = NULL; + FreeMediaType(&filter->source.pin.mt); }
- IUnknown_AddRef((IUnknown *)*out); - return S_OK; + return hr; }
-static const IPinVtbl IPin_Out_VTable = +static const struct strmbase_source_ops source_ops = { - sample_grabber_source_QueryInterface, - SampleGrabber_IPin_AddRef, - SampleGrabber_IPin_Release, - SampleGrabber_Out_IPin_Connect, - SampleGrabber_Out_IPin_ReceiveConnection, - SampleGrabber_Out_IPin_Disconnect, - SampleGrabber_IPin_ConnectedTo, - SampleGrabber_IPin_ConnectionMediaType, - SampleGrabber_IPin_QueryPinInfo, - SampleGrabber_IPin_QueryDirection, - SampleGrabber_IPin_QueryId, - SampleGrabber_IPin_QueryAccept, - SampleGrabber_IPin_EnumMediaTypes, - SampleGrabber_Out_IPin_QueryInternalConnections, - SampleGrabber_IPin_EndOfStream, - SampleGrabber_IPin_BeginFlush, - SampleGrabber_IPin_EndFlush, - SampleGrabber_IPin_NewSegment, + .base.pin_query_interface = sample_grabber_source_query_interface, + .base.pin_query_accept = sample_grabber_source_query_accept, + .base.pin_get_media_type = sample_grabber_source_get_media_type, + .pfnAttemptConnection = sample_grabber_source_AttemptConnection, +}; + +static const IPinVtbl source_vtbl = +{ + BasePinImpl_QueryInterface, + BasePinImpl_AddRef, + BasePinImpl_Release, + BaseOutputPinImpl_Connect, + BaseOutputPinImpl_ReceiveConnection, + BaseOutputPinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + BasePinImpl_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseOutputPinImpl_EndOfStream, + BaseOutputPinImpl_BeginFlush, + BaseOutputPinImpl_EndFlush, + BasePinImpl_NewSegment, };
HRESULT SampleGrabber_create(IUnknown *outer, void **out) @@ -1133,11 +1102,9 @@ HRESULT SampleGrabber_create(IUnknown *outer, void **out) obj->pin_in.name = pin_in_name; obj->pin_in.sg = obj; obj->pin_in.pair = NULL; - obj->pin_out.IPin_iface.lpVtbl = &IPin_Out_VTable; - obj->pin_out.dir = PINDIR_OUTPUT; - obj->pin_out.name = pin_out_name; - obj->pin_out.sg = obj; - obj->pin_out.pair = NULL; + + strmbase_source_init(&obj->source, &source_vtbl, &obj->filter, L"Out", &source_ops); + obj->mtype.majortype = GUID_NULL; obj->mtype.subtype = MEDIASUBTYPE_None; obj->mtype.formattype = FORMAT_None; diff --git a/dlls/qedit/tests/samplegrabber.c b/dlls/qedit/tests/samplegrabber.c index 9bb4eb4f01..22112c6143 100644 --- a/dlls/qedit/tests/samplegrabber.c +++ b/dlls/qedit/tests/samplegrabber.c @@ -472,6 +472,7 @@ static void test_media_types(void)
hr = IPin_EnumMediaTypes(pin, &enummt); todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + if (hr == S_OK) IEnumMediaTypes_Release(enummt);
hr = IPin_QueryAccept(pin, &mt); ok(hr == S_OK, "Got hr %#x.\n", hr);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/amstream/ddrawstream.c | 7 ------- dlls/qcap/avico.c | 4 ++-- dlls/qcap/avimux.c | 7 +++---- dlls/qcap/smartteefilter.c | 4 ++-- dlls/strmbase/pin.c | 40 ++++++++++++++++++------------------- dlls/strmbase/renderer.c | 2 +- dlls/strmbase/transform.c | 2 +- include/wine/strmbase.h | 14 ++++++------- 8 files changed, 35 insertions(+), 45 deletions(-)
diff --git a/dlls/amstream/ddrawstream.c b/dlls/amstream/ddrawstream.c index a35a4b1c29..48ccc52d47 100644 --- a/dlls/amstream/ddrawstream.c +++ b/dlls/amstream/ddrawstream.c @@ -33,13 +33,6 @@ static const WCHAR sink_id[] = {'I','{','A','3','5','F','F','5','6','A', static HRESULT ddrawstreamsample_create(IDirectDrawMediaStream *parent, IDirectDrawSurface *surface, const RECT *rect, IDirectDrawStreamSample **ddraw_stream_sample);
-struct ddraw_stream; - -typedef struct { - BaseInputPin pin; - struct ddraw_stream *parent; -} DirectDrawMediaStreamInputPin; - struct ddraw_stream { IAMMediaStream IAMMediaStream_iface; diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c index 8eae692dca..9b32ddb336 100644 --- a/dlls/qcap/avico.c +++ b/dlls/qcap/avico.c @@ -37,7 +37,7 @@ typedef struct { struct strmbase_filter filter; IPersistPropertyBag IPersistPropertyBag_iface;
- BaseInputPin sink; + struct strmbase_sink sink; struct strmbase_source source;
DWORD fcc_handler; @@ -412,7 +412,7 @@ static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void return S_OK; }
-static HRESULT WINAPI AVICompressorIn_Receive(BaseInputPin *base, IMediaSample *pSample) +static HRESULT WINAPI AVICompressorIn_Receive(struct strmbase_sink *base, IMediaSample *pSample) { AVICompressor *This = impl_from_strmbase_pin(&base->pin); VIDEOINFOHEADER *src_videoinfo; diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c index e8067dd61d..0e162dfcde 100644 --- a/dlls/qcap/avimux.c +++ b/dlls/qcap/avimux.c @@ -40,7 +40,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(qcap); #define ALIGN(x) ((x+1)/2*2)
typedef struct { - BaseInputPin pin; + struct strmbase_sink pin; IAMStreamControl IAMStreamControl_iface; IPropertyBag IPropertyBag_iface; IQualityControl IQualityControl_iface; @@ -1380,7 +1380,7 @@ static HRESULT sink_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE return S_FALSE; }
-static HRESULT WINAPI AviMuxIn_Receive(BaseInputPin *base, IMediaSample *pSample) +static HRESULT WINAPI AviMuxIn_Receive(struct strmbase_sink *base, IMediaSample *pSample) { AviMux *avimux = impl_from_strmbase_filter(base->pin.filter); AviMuxIn *avimuxin = CONTAINING_RECORD(base, AviMuxIn, pin); @@ -1698,8 +1698,7 @@ static const IAMStreamControlVtbl AviMuxIn_AMStreamControlVtbl = {
static inline AviMuxIn* AviMuxIn_from_IMemInputPin(IMemInputPin *iface) { - BaseInputPin *bip = CONTAINING_RECORD(iface, BaseInputPin, IMemInputPin_iface); - return CONTAINING_RECORD(bip, AviMuxIn, pin); + return CONTAINING_RECORD(iface, AviMuxIn, pin.IMemInputPin_iface); }
static HRESULT WINAPI AviMuxIn_MemInputPin_QueryInterface( diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c index d3acf47e7e..be19fd5c09 100644 --- a/dlls/qcap/smartteefilter.c +++ b/dlls/qcap/smartteefilter.c @@ -37,7 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(qcap);
typedef struct { struct strmbase_filter filter; - BaseInputPin sink; + struct strmbase_sink sink; struct strmbase_source capture, preview; } SmartTeeFilter;
@@ -242,7 +242,7 @@ end: return hr; }
-static HRESULT WINAPI SmartTeeFilterInput_Receive(BaseInputPin *base, IMediaSample *inputSample) +static HRESULT WINAPI SmartTeeFilterInput_Receive(struct strmbase_sink *base, IMediaSample *inputSample) { SmartTeeFilter *This = impl_from_strmbase_pin(&base->pin); IMediaSample *captureSample = NULL; diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c index 8c337ca471..39512c066b 100644 --- a/dlls/strmbase/pin.c +++ b/dlls/strmbase/pin.c @@ -719,11 +719,9 @@ void strmbase_source_cleanup(struct strmbase_source *pin) pin->pAllocator = NULL; }
-/*** Input Pin implementation ***/ - -static inline BaseInputPin *impl_BaseInputPin_from_IPin( IPin *iface ) +static struct strmbase_sink *impl_sink_from_IPin(IPin *iface) { - return CONTAINING_RECORD(iface, BaseInputPin, pin.IPin_iface); + return CONTAINING_RECORD(iface, struct strmbase_sink, pin.IPin_iface); }
HRESULT WINAPI BaseInputPinImpl_Connect(IPin *iface, IPin *pin, const AM_MEDIA_TYPE *pmt) @@ -735,7 +733,7 @@ HRESULT WINAPI BaseInputPinImpl_Connect(IPin *iface, IPin *pin, const AM_MEDIA_T
HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) { - BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + struct strmbase_sink *This = impl_sink_from_IPin(iface); PIN_DIRECTION pindirReceive; HRESULT hr = S_OK;
@@ -788,8 +786,8 @@ static HRESULT deliver_endofstream(IPin* pin, LPVOID unused)
HRESULT WINAPI BaseInputPinImpl_EndOfStream(IPin * iface) { + struct strmbase_sink *This = impl_sink_from_IPin(iface); HRESULT hr = S_OK; - BaseInputPin *This = impl_BaseInputPin_from_IPin(iface);
TRACE("(%p)->()\n", This);
@@ -812,7 +810,7 @@ static HRESULT deliver_beginflush(IPin* pin, LPVOID unused)
HRESULT WINAPI BaseInputPinImpl_BeginFlush(IPin * iface) { - BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + struct strmbase_sink *This = impl_sink_from_IPin(iface); HRESULT hr; TRACE("(%p) semi-stub\n", This);
@@ -832,7 +830,7 @@ static HRESULT deliver_endflush(IPin* pin, LPVOID unused)
HRESULT WINAPI BaseInputPinImpl_EndFlush(IPin * iface) { - BaseInputPin *This = impl_BaseInputPin_from_IPin(iface); + struct strmbase_sink *This = impl_sink_from_IPin(iface); HRESULT hr; TRACE("(%p)->()\n", This);
@@ -873,35 +871,35 @@ HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin * iface, REFERENCE_TIME start, R
/*** IMemInputPin implementation ***/
-static inline BaseInputPin *impl_from_IMemInputPin( IMemInputPin *iface ) +static inline struct strmbase_sink *impl_from_IMemInputPin(IMemInputPin *iface) { - return CONTAINING_RECORD(iface, BaseInputPin, IMemInputPin_iface); + return CONTAINING_RECORD(iface, struct strmbase_sink, IMemInputPin_iface); }
static HRESULT WINAPI MemInputPin_QueryInterface(IMemInputPin * iface, REFIID riid, LPVOID * ppv) { - BaseInputPin *This = impl_from_IMemInputPin(iface); + struct strmbase_sink *This = impl_from_IMemInputPin(iface);
return IPin_QueryInterface(&This->pin.IPin_iface, riid, ppv); }
static ULONG WINAPI MemInputPin_AddRef(IMemInputPin * iface) { - BaseInputPin *This = impl_from_IMemInputPin(iface); + struct strmbase_sink *This = impl_from_IMemInputPin(iface);
return IPin_AddRef(&This->pin.IPin_iface); }
static ULONG WINAPI MemInputPin_Release(IMemInputPin * iface) { - BaseInputPin *This = impl_from_IMemInputPin(iface); + struct strmbase_sink *This = impl_from_IMemInputPin(iface);
return IPin_Release(&This->pin.IPin_iface); }
static HRESULT WINAPI MemInputPin_GetAllocator(IMemInputPin * iface, IMemAllocator ** ppAllocator) { - BaseInputPin *This = impl_from_IMemInputPin(iface); + struct strmbase_sink *This = impl_from_IMemInputPin(iface);
TRACE("(%p/%p)->(%p)\n", This, iface, ppAllocator);
@@ -914,7 +912,7 @@ static HRESULT WINAPI MemInputPin_GetAllocator(IMemInputPin * iface, IMemAllocat
static HRESULT WINAPI MemInputPin_NotifyAllocator(IMemInputPin * iface, IMemAllocator * pAllocator, BOOL bReadOnly) { - BaseInputPin *This = impl_from_IMemInputPin(iface); + struct strmbase_sink *This = impl_from_IMemInputPin(iface);
TRACE("(%p/%p)->(%p, %d)\n", This, iface, pAllocator, bReadOnly);
@@ -942,7 +940,7 @@ static HRESULT WINAPI MemInputPin_NotifyAllocator(IMemInputPin * iface, IMemAllo
static HRESULT WINAPI MemInputPin_GetAllocatorRequirements(IMemInputPin * iface, ALLOCATOR_PROPERTIES * pProps) { - BaseInputPin *This = impl_from_IMemInputPin(iface); + struct strmbase_sink *This = impl_from_IMemInputPin(iface);
TRACE("(%p/%p)->(%p)\n", This, iface, pProps);
@@ -953,7 +951,7 @@ static HRESULT WINAPI MemInputPin_GetAllocatorRequirements(IMemInputPin * iface,
static HRESULT WINAPI MemInputPin_Receive(IMemInputPin * iface, IMediaSample * pSample) { - BaseInputPin *This = impl_from_IMemInputPin(iface); + struct strmbase_sink *This = impl_from_IMemInputPin(iface); HRESULT hr = S_FALSE;
/* this trace commented out for performance reasons */ @@ -965,8 +963,8 @@ static HRESULT WINAPI MemInputPin_Receive(IMemInputPin * iface, IMediaSample * p
static HRESULT WINAPI MemInputPin_ReceiveMultiple(IMemInputPin * iface, IMediaSample ** pSamples, LONG nSamples, LONG *nSamplesProcessed) { + struct strmbase_sink *This = impl_from_IMemInputPin(iface); HRESULT hr = S_OK; - BaseInputPin *This = impl_from_IMemInputPin(iface);
TRACE("(%p/%p)->(%p, %d, %p)\n", This, iface, pSamples, nSamples, nSamplesProcessed);
@@ -982,7 +980,7 @@ static HRESULT WINAPI MemInputPin_ReceiveMultiple(IMemInputPin * iface, IMediaSa
static HRESULT WINAPI MemInputPin_ReceiveCanBlock(IMemInputPin * iface) { - BaseInputPin *This = impl_from_IMemInputPin(iface); + struct strmbase_sink *This = impl_from_IMemInputPin(iface);
TRACE("(%p/%p)->()\n", This, iface);
@@ -1002,7 +1000,7 @@ static const IMemInputPinVtbl MemInputPin_Vtbl = MemInputPin_ReceiveCanBlock };
-void strmbase_sink_init(BaseInputPin *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter, +void strmbase_sink_init(struct strmbase_sink *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter, const WCHAR *name, const BaseInputPinFuncTable *func_table, IMemAllocator *allocator) { memset(pin, 0, sizeof(*pin)); @@ -1018,7 +1016,7 @@ void strmbase_sink_init(BaseInputPin *pin, const IPinVtbl *vtbl, struct strmbase pin->IMemInputPin_iface.lpVtbl = &MemInputPin_Vtbl; }
-void strmbase_sink_cleanup(BaseInputPin *pin) +void strmbase_sink_cleanup(struct strmbase_sink *pin) { FreeMediaType(&pin->pin.mt); if (pin->pAllocator) diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 57f440b9f4..2e8566b064 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -296,7 +296,7 @@ static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void return S_OK; }
-static HRESULT WINAPI BaseRenderer_Receive(BaseInputPin *pin, IMediaSample *sample) +static HRESULT WINAPI BaseRenderer_Receive(struct strmbase_sink *pin, IMediaSample *sample) { struct strmbase_renderer *filter = impl_from_IPin(&pin->pin.IPin_iface); return BaseRendererImpl_Receive(filter, sample); diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c index f4c2c4be72..3811569da1 100644 --- a/dlls/strmbase/transform.c +++ b/dlls/strmbase/transform.c @@ -57,7 +57,7 @@ static HRESULT sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE return S_OK; }
-static HRESULT WINAPI TransformFilter_Input_Receive(BaseInputPin *This, IMediaSample *pInSample) +static HRESULT WINAPI TransformFilter_Input_Receive(struct strmbase_sink *This, IMediaSample *pInSample) { TransformFilter *pTransform = impl_from_sink_IPin(&This->pin.IPin_iface); HRESULT hr; diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 01a2bc79c3..99c579f8df 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -75,7 +75,7 @@ struct strmbase_source_ops BaseOutputPin_DecideAllocator pfnDecideAllocator; };
-typedef struct BaseInputPin +struct strmbase_sink { struct strmbase_pin pin;
@@ -85,9 +85,9 @@ typedef struct BaseInputPin IMemAllocator *preferred_allocator;
const struct BaseInputPinFuncTable *pFuncsTable; -} BaseInputPin; +};
-typedef HRESULT (WINAPI *BaseInputPin_Receive)(BaseInputPin *This, IMediaSample *pSample); +typedef HRESULT (WINAPI *BaseInputPin_Receive)(struct strmbase_sink *This, IMediaSample *pSample);
typedef struct BaseInputPinFuncTable { BasePinFuncTable base; @@ -142,9 +142,9 @@ HRESULT WINAPI BaseInputPinImpl_BeginFlush(IPin * iface); HRESULT WINAPI BaseInputPinImpl_EndFlush(IPin * iface); HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
-void strmbase_sink_init(BaseInputPin *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter, +void strmbase_sink_init(struct strmbase_sink *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter, const WCHAR *name, const BaseInputPinFuncTable *func_table, IMemAllocator *allocator); -void strmbase_sink_cleanup(BaseInputPin *pin); +void strmbase_sink_cleanup(struct strmbase_sink *pin);
struct strmbase_filter { @@ -207,7 +207,7 @@ typedef struct TransformFilter IQualityControl source_IQualityControl_iface; IQualityControl *source_qc_sink;
- BaseInputPin sink; + struct strmbase_sink sink;
AM_MEDIA_TYPE pmt; CRITICAL_SECTION csReceive; @@ -515,7 +515,7 @@ struct strmbase_renderer { struct strmbase_filter filter;
- BaseInputPin sink; + struct strmbase_sink sink; IUnknown *pPosition; CRITICAL_SECTION csRenderLock; /* Signaled when the filter has completed a state change. The filter waits
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qcap/avico.c | 4 ++-- dlls/qcap/avimux.c | 5 ++--- dlls/qcap/smartteefilter.c | 5 ++--- dlls/strmbase/pin.c | 2 +- dlls/strmbase/renderer.c | 4 ++-- dlls/strmbase/transform.c | 4 ++-- include/wine/strmbase.h | 9 +++++---- 7 files changed, 16 insertions(+), 17 deletions(-)
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c index 9b32ddb336..1cbeb70f03 100644 --- a/dlls/qcap/avico.c +++ b/dlls/qcap/avico.c @@ -499,7 +499,7 @@ static HRESULT WINAPI AVICompressorIn_Receive(struct strmbase_sink *base, IMedia return hres; }
-static const BaseInputPinFuncTable AVICompressorBaseInputPinVtbl = +static const struct strmbase_sink_ops sink_ops = { .base.pin_query_accept = sink_query_accept, .base.pin_get_media_type = strmbase_pin_get_media_type, @@ -597,7 +597,7 @@ IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr) compressor->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
strmbase_sink_init(&compressor->sink, &AVICompressorInputPinVtbl, - &compressor->filter, sink_name, &AVICompressorBaseInputPinVtbl, NULL); + &compressor->filter, sink_name, &sink_ops, NULL); strmbase_source_init(&compressor->source, &AVICompressorOutputPinVtbl, &compressor->filter, source_name, &source_ops);
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c index 0e162dfcde..51a1a503af 100644 --- a/dlls/qcap/avimux.c +++ b/dlls/qcap/avimux.c @@ -1483,7 +1483,7 @@ static HRESULT WINAPI AviMuxIn_Receive(struct strmbase_sink *base, IMediaSample return hr; }
-static const BaseInputPinFuncTable AviMuxIn_BaseInputFuncTable = +static const struct strmbase_sink_ops sink_ops = { .base.pin_query_accept = sink_query_accept, .base.pin_get_media_type = strmbase_pin_get_media_type, @@ -1944,8 +1944,7 @@ static HRESULT create_input_pin(AviMux *avimux) if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY;
- strmbase_sink_init(&object->pin, &AviMuxIn_PinVtbl, &avimux->filter, name, - &AviMuxIn_BaseInputFuncTable, NULL); + strmbase_sink_init(&object->pin, &AviMuxIn_PinVtbl, &avimux->filter, name, &sink_ops, NULL); object->pin.IMemInputPin_iface.lpVtbl = &AviMuxIn_MemInputPinVtbl; object->IAMStreamControl_iface.lpVtbl = &AviMuxIn_AMStreamControlVtbl; object->IPropertyBag_iface.lpVtbl = &AviMuxIn_PropertyBagVtbl; diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c index be19fd5c09..e3740bed13 100644 --- a/dlls/qcap/smartteefilter.c +++ b/dlls/qcap/smartteefilter.c @@ -285,7 +285,7 @@ static HRESULT WINAPI SmartTeeFilterInput_Receive(struct strmbase_sink *base, IM return hrPreview; }
-static const BaseInputPinFuncTable SmartTeeFilterInputFuncs = +static const struct strmbase_sink_ops sink_ops = { .base.pin_query_accept = sink_query_accept, .base.pin_get_media_type = sink_get_media_type, @@ -418,8 +418,7 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr) memset(object, 0, sizeof(*object));
strmbase_filter_init(&object->filter, &SmartTeeFilterVtbl, outer, &CLSID_SmartTee, &filter_ops); - strmbase_sink_init(&object->sink, &SmartTeeFilterInputVtbl, &object->filter, - inputW, &SmartTeeFilterInputFuncs, NULL); + strmbase_sink_init(&object->sink, &SmartTeeFilterInputVtbl, &object->filter, inputW, &sink_ops, NULL); hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (void **)&object->sink.pAllocator); if (FAILED(hr)) diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c index 39512c066b..92a2fe55b9 100644 --- a/dlls/strmbase/pin.c +++ b/dlls/strmbase/pin.c @@ -1001,7 +1001,7 @@ static const IMemInputPinVtbl MemInputPin_Vtbl = };
void strmbase_sink_init(struct strmbase_sink *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter, - const WCHAR *name, const BaseInputPinFuncTable *func_table, IMemAllocator *allocator) + const WCHAR *name, const struct strmbase_sink_ops *func_table, IMemAllocator *allocator) { memset(pin, 0, sizeof(*pin)); pin->pin.IPin_iface.lpVtbl = vtbl; diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c index 2e8566b064..0c33b5ea84 100644 --- a/dlls/strmbase/renderer.c +++ b/dlls/strmbase/renderer.c @@ -302,7 +302,7 @@ static HRESULT WINAPI BaseRenderer_Receive(struct strmbase_sink *pin, IMediaSamp return BaseRendererImpl_Receive(filter, sample); }
-static const BaseInputPinFuncTable input_BaseInputFuncTable = +static const struct strmbase_sink_ops sink_ops = { .base.pin_query_accept = sink_query_accept, .base.pin_query_interface = sink_query_interface, @@ -511,7 +511,7 @@ HRESULT WINAPI strmbase_renderer_init(struct strmbase_renderer *filter, IUnknown filter->pFuncsTable = ops;
strmbase_sink_init(&filter->sink, &BaseRenderer_InputPin_Vtbl, &filter->filter, - sink_name, &input_BaseInputFuncTable, NULL); + sink_name, &sink_ops, NULL);
hr = CreatePosPassThru(outer ? outer : (IUnknown *)&filter->filter.IBaseFilter_iface, TRUE, &filter->sink.pin.IPin_iface, &filter->pPosition); diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c index 3811569da1..e567804ba3 100644 --- a/dlls/strmbase/transform.c +++ b/dlls/strmbase/transform.c @@ -210,7 +210,7 @@ static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void return S_OK; }
-static const BaseInputPinFuncTable tf_input_BaseInputFuncTable = +static const struct strmbase_sink_ops sink_ops = { .base.pin_query_accept = sink_query_accept, .base.pin_get_media_type = strmbase_pin_get_media_type, @@ -353,7 +353,7 @@ static HRESULT strmbase_transform_init(IUnknown *outer, const CLSID *clsid, ZeroMemory(&filter->pmt, sizeof(filter->pmt));
strmbase_sink_init(&filter->sink, &TransformFilter_InputPin_Vtbl, &filter->filter, - wcsInputPinName, &tf_input_BaseInputFuncTable, NULL); + wcsInputPinName, &sink_ops, NULL);
strmbase_source_init(&filter->source, &TransformFilter_OutputPin_Vtbl, &filter->filter, wcsOutputPinName, &source_ops); diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 99c579f8df..fd79e9726d 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -84,16 +84,17 @@ struct strmbase_sink BOOL flushing, end_of_stream; IMemAllocator *preferred_allocator;
- const struct BaseInputPinFuncTable *pFuncsTable; + const struct strmbase_sink_ops *pFuncsTable; };
typedef HRESULT (WINAPI *BaseInputPin_Receive)(struct strmbase_sink *This, IMediaSample *pSample);
-typedef struct BaseInputPinFuncTable { +struct strmbase_sink_ops +{ BasePinFuncTable base; /* Optional */ BaseInputPin_Receive pfnReceive; -} BaseInputPinFuncTable; +};
/* Base Pin */ HRESULT strmbase_pin_get_media_type(struct strmbase_pin *pin, unsigned int index, AM_MEDIA_TYPE *mt); @@ -143,7 +144,7 @@ HRESULT WINAPI BaseInputPinImpl_EndFlush(IPin * iface); HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
void strmbase_sink_init(struct strmbase_sink *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter, - const WCHAR *name, const BaseInputPinFuncTable *func_table, IMemAllocator *allocator); + const WCHAR *name, const struct strmbase_sink_ops *ops, IMemAllocator *allocator); void strmbase_sink_cleanup(struct strmbase_sink *pin);
struct strmbase_filter
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/samplegrabber.c | 535 +++++-------------------------- dlls/qedit/tests/samplegrabber.c | 3 +- 2 files changed, 88 insertions(+), 450 deletions(-)
diff --git a/dlls/qedit/samplegrabber.c b/dlls/qedit/samplegrabber.c index 21634a145d..59238f5896 100644 --- a/dlls/qedit/samplegrabber.c +++ b/dlls/qedit/samplegrabber.c @@ -33,181 +33,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(qedit);
-static const WCHAR pin_in_name[] = { 'I', 'n', 0 }; - -static IEnumMediaTypes *mediaenum_create(const AM_MEDIA_TYPE *mtype, BOOL past); - -/* Single media type enumerator */ -typedef struct _ME_Impl { - IEnumMediaTypes IEnumMediaTypes_iface; - LONG refCount; - BOOL past; - AM_MEDIA_TYPE mtype; -} ME_Impl; - - -/* IEnumMediaTypes interface implementation */ - -static inline ME_Impl *impl_from_IEnumMediaTypes(IEnumMediaTypes *iface) -{ - return CONTAINING_RECORD(iface, ME_Impl, IEnumMediaTypes_iface); -} - -static HRESULT WINAPI Single_IEnumMediaTypes_QueryInterface(IEnumMediaTypes *iface, REFIID riid, - void **ret_iface) -{ - ME_Impl *This = impl_from_IEnumMediaTypes(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ret_iface); - - if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumMediaTypes)) { - *ret_iface = iface; - IEnumMediaTypes_AddRef(iface); - return S_OK; - } - *ret_iface = NULL; - WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ret_iface); - return E_NOINTERFACE; -} - -static ULONG WINAPI Single_IEnumMediaTypes_AddRef(IEnumMediaTypes *iface) -{ - ME_Impl *This = impl_from_IEnumMediaTypes(iface); - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("(%p) new ref = %u\n", This, refCount); - return refCount; -} - -static ULONG WINAPI Single_IEnumMediaTypes_Release(IEnumMediaTypes *iface) -{ - ME_Impl *This = impl_from_IEnumMediaTypes(iface); - ULONG refCount = InterlockedDecrement(&This->refCount); - - TRACE("(%p) new ref = %u\n", This, refCount); - if (refCount == 0) - { - CoTaskMemFree(This->mtype.pbFormat); - CoTaskMemFree(This); - } - return refCount; -} - -/* IEnumMediaTypes */ -static HRESULT WINAPI Single_IEnumMediaTypes_Next(IEnumMediaTypes *iface, ULONG nTypes, - AM_MEDIA_TYPE **types, ULONG *fetched) -{ - ME_Impl *This = impl_from_IEnumMediaTypes(iface); - ULONG count = 0; - - TRACE("(%p)->(%u, %p, %p)\n", This, nTypes, types, fetched); - if (!nTypes) - return E_INVALIDARG; - if (!types || ((nTypes != 1) && !fetched)) - return E_POINTER; - if (!This->past && !IsEqualGUID(&This->mtype.majortype,&GUID_NULL)) { - AM_MEDIA_TYPE *mtype = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); - *mtype = This->mtype; - if (mtype->cbFormat) { - mtype->pbFormat = CoTaskMemAlloc(mtype->cbFormat); - CopyMemory(mtype->pbFormat, This->mtype.pbFormat, mtype->cbFormat); - } - *types = mtype; - This->past = TRUE; - count = 1; - } - if (fetched) - *fetched = count; - return (count == nTypes) ? S_OK : S_FALSE; -} - -static HRESULT WINAPI Single_IEnumMediaTypes_Skip(IEnumMediaTypes *iface, ULONG nTypes) -{ - ME_Impl *This = impl_from_IEnumMediaTypes(iface); - - TRACE("(%p)->(%u)\n", This, nTypes); - if (nTypes) - This->past = TRUE; - return This->past ? S_FALSE : S_OK; -} - -static HRESULT WINAPI Single_IEnumMediaTypes_Reset(IEnumMediaTypes *iface) -{ - ME_Impl *This = impl_from_IEnumMediaTypes(iface); - - TRACE("(%p)->()\n", This); - This->past = FALSE; - return S_OK; -} - -static HRESULT WINAPI Single_IEnumMediaTypes_Clone(IEnumMediaTypes *iface, IEnumMediaTypes **me) -{ - ME_Impl *This = impl_from_IEnumMediaTypes(iface); - - TRACE("(%p)->(%p)\n", This, me); - if (!me) - return E_POINTER; - *me = mediaenum_create(&This->mtype, This->past); - if (!*me) - return E_OUTOFMEMORY; - return S_OK; -} - - -/* Virtual tables and constructor */ - -static const IEnumMediaTypesVtbl IEnumMediaTypes_VTable = -{ - Single_IEnumMediaTypes_QueryInterface, - Single_IEnumMediaTypes_AddRef, - Single_IEnumMediaTypes_Release, - Single_IEnumMediaTypes_Next, - Single_IEnumMediaTypes_Skip, - Single_IEnumMediaTypes_Reset, - Single_IEnumMediaTypes_Clone, -}; - -static IEnumMediaTypes *mediaenum_create(const AM_MEDIA_TYPE *mtype, BOOL past) -{ - ME_Impl *obj = CoTaskMemAlloc(sizeof(ME_Impl)); - - if (!obj) - return NULL; - ZeroMemory(obj, sizeof(*obj)); - obj->IEnumMediaTypes_iface.lpVtbl = &IEnumMediaTypes_VTable; - obj->refCount = 1; - obj->past = past; - if (mtype) { - obj->mtype = *mtype; - obj->mtype.pUnk = NULL; - if (mtype->cbFormat) { - obj->mtype.pbFormat = CoTaskMemAlloc(mtype->cbFormat); - CopyMemory(obj->mtype.pbFormat, mtype->pbFormat, mtype->cbFormat); - } - else - obj->mtype.pbFormat = NULL; - } - else - obj->mtype.majortype = GUID_NULL; - - return &obj->IEnumMediaTypes_iface; -} - - -/* Sample Grabber pin implementation */ -typedef struct _SG_Pin { - IPin IPin_iface; - PIN_DIRECTION dir; - WCHAR const *name; - struct _SG_Impl *sg; - IPin *pair; -} SG_Pin; - -static inline SG_Pin *impl_from_IPin(IPin *iface) -{ - return CONTAINING_RECORD(iface, SG_Pin, IPin_iface); -} - /* Sample Grabber filter implementation */ typedef struct _SG_Impl { struct strmbase_filter filter; @@ -218,7 +43,7 @@ typedef struct _SG_Impl { IUnknown *seekthru_unk; IMemInputPin *memOutput;
- SG_Pin pin_in; + struct strmbase_sink sink; AM_MEDIA_TYPE mtype; IMemInputPin IMemInputPin_iface; IMemAllocator *allocator; @@ -280,7 +105,7 @@ static IPin *sample_grabber_get_pin(struct strmbase_filter *iface, unsigned int SG_Impl *filter = impl_from_strmbase_filter(iface);
if (index == 0) - return &filter->pin_in.IPin_iface; + return &filter->sink.pin.IPin_iface; else if (index == 1) return &filter->source.pin.IPin_iface; return NULL; @@ -455,7 +280,7 @@ SampleGrabber_ISampleGrabber_GetConnectedMediaType(ISampleGrabber *iface, AM_MED TRACE("(%p)->(%p)\n", This, type); if (!type) return E_POINTER; - if (!This->pin_in.pair) + if (!This->sink.pin.peer) return VFW_E_NOT_CONNECTED; *type = This->mtype; if (type->cbFormat) { @@ -492,7 +317,7 @@ SampleGrabber_ISampleGrabber_GetCurrentBuffer(ISampleGrabber *iface, LONG *bufSi if (!bufSize) return E_POINTER; EnterCriticalSection(&This->filter.csFilter); - if (!This->pin_in.pair) + if (!This->sink.pin.peer) ret = VFW_E_NOT_CONNECTED; else if (This->bufferLen < 0) ret = E_INVALIDARG; @@ -538,19 +363,19 @@ SampleGrabber_ISampleGrabber_SetCallback(ISampleGrabber *iface, ISampleGrabberCB static HRESULT WINAPI SampleGrabber_IMemInputPin_QueryInterface(IMemInputPin *iface, REFIID iid, void **out) { SG_Impl *filter = impl_from_IMemInputPin(iface); - return IPin_QueryInterface(&filter->pin_in.IPin_iface, iid, out); + return IPin_QueryInterface(&filter->sink.pin.IPin_iface, iid, out); }
static ULONG WINAPI SampleGrabber_IMemInputPin_AddRef(IMemInputPin *iface) { SG_Impl *filter = impl_from_IMemInputPin(iface); - return IPin_AddRef(&filter->pin_in.IPin_iface); + return IPin_AddRef(&filter->sink.pin.IPin_iface); }
static ULONG WINAPI SampleGrabber_IMemInputPin_Release(IMemInputPin *iface) { SG_Impl *filter = impl_from_IMemInputPin(iface); - return IPin_Release(&filter->pin_in.IPin_iface); + return IPin_Release(&filter->sink.pin.IPin_iface); }
/* IMemInputPin */ @@ -642,67 +467,19 @@ SampleGrabber_IMemInputPin_ReceiveCanBlock(IMemInputPin *iface) return This->memOutput ? IMemInputPin_ReceiveCanBlock(This->memOutput) : S_OK; }
-static HRESULT WINAPI sample_grabber_sink_QueryInterface(IPin *iface, REFIID iid, void **out) -{ - SG_Pin *pin = impl_from_IPin(iface); - - TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); - - if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IPin)) - { - *out = iface; - } - else if (IsEqualGUID(iid, &IID_IMemInputPin)) - { - *out = &pin->sg->IMemInputPin_iface; - } - else - { - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - *out = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown *)*out); - return S_OK; -} - -/* IUnknown */ -static ULONG WINAPI -SampleGrabber_IPin_AddRef(IPin *iface) -{ - SG_Pin *This = impl_from_IPin(iface); - return ISampleGrabber_AddRef(&This->sg->ISampleGrabber_iface); -} - -/* IUnknown */ -static ULONG WINAPI -SampleGrabber_IPin_Release(IPin *iface) -{ - SG_Pin *This = impl_from_IPin(iface); - return ISampleGrabber_Release(&This->sg->ISampleGrabber_iface); -} - -/* IPin - input pin */ -static HRESULT WINAPI -SampleGrabber_In_IPin_Connect(IPin *iface, IPin *receiver, const AM_MEDIA_TYPE *mtype) -{ - WARN("(%p, %p): unexpected\n", receiver, mtype); - return E_UNEXPECTED; -} - /* IPin - input pin */ static HRESULT WINAPI SampleGrabber_In_IPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_MEDIA_TYPE *type) { - SG_Pin *This = impl_from_IPin(iface); + SG_Impl *filter = CONTAINING_RECORD(iface, SG_Impl, sink.pin.IPin_iface); + + TRACE("filter %p, connector %p, type %p.\n", filter, connector, type);
- TRACE("(%p)->(%p, %p)\n", This, connector, type); if (!connector) return E_POINTER; - if (This->pair) + if (filter->sink.pin.peer) return VFW_E_ALREADY_CONNECTED; - if (This->sg->filter.state != State_Stopped) + if (filter->filter.state != State_Stopped) return VFW_E_NOT_STOPPED; if (type) { TRACE("Media type: %s/%s ssize: %u format: %s (%u bytes)\n", @@ -713,205 +490,26 @@ SampleGrabber_In_IPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_M !IsEqualGUID(&type->formattype, &GUID_NULL) && !type->pbFormat) return VFW_E_INVALIDMEDIATYPE; - if (!IsEqualGUID(&This->sg->mtype.majortype,&GUID_NULL) && - !IsEqualGUID(&This->sg->mtype.majortype,&type->majortype)) + if (!IsEqualGUID(&filter->mtype.majortype,&GUID_NULL) && + !IsEqualGUID(&filter->mtype.majortype,&type->majortype)) return VFW_E_TYPE_NOT_ACCEPTED; - if (!IsEqualGUID(&This->sg->mtype.subtype,&MEDIASUBTYPE_None) && - !IsEqualGUID(&This->sg->mtype.subtype,&type->subtype)) + if (!IsEqualGUID(&filter->mtype.subtype,&MEDIASUBTYPE_None) && + !IsEqualGUID(&filter->mtype.subtype,&type->subtype)) return VFW_E_TYPE_NOT_ACCEPTED; - if (!IsEqualGUID(&This->sg->mtype.formattype,&GUID_NULL) && - !IsEqualGUID(&This->sg->mtype.formattype,&FORMAT_None) && - !IsEqualGUID(&This->sg->mtype.formattype,&type->formattype)) + if (!IsEqualGUID(&filter->mtype.formattype,&GUID_NULL) && + !IsEqualGUID(&filter->mtype.formattype,&FORMAT_None) && + !IsEqualGUID(&filter->mtype.formattype,&type->formattype)) return VFW_E_TYPE_NOT_ACCEPTED; - CoTaskMemFree(This->sg->mtype.pbFormat); - This->sg->mtype = *type; - This->sg->mtype.pUnk = NULL; - if (type->cbFormat) { - This->sg->mtype.pbFormat = CoTaskMemAlloc(type->cbFormat); - CopyMemory(This->sg->mtype.pbFormat, type->pbFormat, type->cbFormat); - } - else - This->sg->mtype.pbFormat = NULL; - } - This->pair = connector; - TRACE("(%p) Accepted IPin %p\n", This, connector); - return S_OK; -} - -/* IPin - input pin */ -static HRESULT WINAPI -SampleGrabber_In_IPin_Disconnect(IPin *iface) -{ - SG_Pin *This = impl_from_IPin(iface); - - TRACE("(%p)->() pair = %p\n", This, This->pair); - if (This->sg->filter.state != State_Stopped) - return VFW_E_NOT_STOPPED; - if (This->pair) { - This->pair = NULL; - return S_OK; - } - return S_FALSE; -} - -/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_ConnectedTo(IPin *iface, IPin **pin) -{ - SG_Pin *This = impl_from_IPin(iface);
- TRACE("(%p)->(%p) pair = %p\n", This, pin, This->pair); - if (!pin) - return E_POINTER; - *pin = This->pair; - if (*pin) { - IPin_AddRef(*pin); - return S_OK; + FreeMediaType(&filter->mtype); + CopyMediaType(&filter->mtype, type); + CopyMediaType(&filter->sink.pin.mt, type); } - return VFW_E_NOT_CONNECTED; -} - -/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *mtype) -{ - SG_Pin *This = impl_from_IPin(iface); - - TRACE("(%p)->(%p)\n", This, mtype); - if (!mtype) - return E_POINTER; - if (!This->pair) - return VFW_E_NOT_CONNECTED; - *mtype = This->sg->mtype; - if (mtype->cbFormat) { - mtype->pbFormat = CoTaskMemAlloc(mtype->cbFormat); - CopyMemory(mtype->pbFormat, This->sg->mtype.pbFormat, mtype->cbFormat); - } - return S_OK; -} - -/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_QueryPinInfo(IPin *iface, PIN_INFO *info) -{ - SG_Pin *This = impl_from_IPin(iface); - - TRACE("(%p)->(%p)\n", This, info); - if (!info) - return E_POINTER; - info->pFilter = &This->sg->filter.IBaseFilter_iface; - IBaseFilter_AddRef(info->pFilter); - info->dir = This->dir; - lstrcpynW(info->achName,This->name,MAX_PIN_NAME); - return S_OK; -} - -/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_QueryDirection(IPin *iface, PIN_DIRECTION *dir) -{ - SG_Pin *This = impl_from_IPin(iface); - - TRACE("(%p)->(%p)\n", This, dir); - if (!dir) - return E_POINTER; - *dir = This->dir; - return S_OK; -} - -/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_QueryId(IPin *iface, LPWSTR *id) -{ - SG_Pin *This = impl_from_IPin(iface); - - int len; - TRACE("(%p)->(%p)\n", This, id); - if (!id) - return E_POINTER; - len = sizeof(WCHAR)*(1+lstrlenW(This->name)); - *id = CoTaskMemAlloc(len); - CopyMemory(*id, This->name, len); - return S_OK; -} - -/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *mtype) -{ - TRACE("(%p)\n", mtype); - return S_OK; -} - -/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **mtypes) -{ - SG_Pin *This = impl_from_IPin(iface); - - TRACE("(%p)->(%p)\n", This, mtypes); - if (!mtypes) - return E_POINTER; - *mtypes = mediaenum_create(This->sg->pin_in.pair ? &This->sg->mtype : NULL, FALSE); - return *mtypes ? S_OK : E_OUTOFMEMORY; -} - -/* IPin - input pin */ -static HRESULT WINAPI -SampleGrabber_In_IPin_QueryInternalConnections(IPin *iface, IPin **pins, ULONG *nPins) -{ - SG_Pin *This = impl_from_IPin(iface); - - TRACE("(%p)->(%p, %p) size = %u\n", This, pins, nPins, (nPins ? *nPins : 0)); - if (!nPins) - return E_POINTER; - if (*nPins) { - if (!pins) - return E_POINTER; - IPin_AddRef(&This->sg->source.pin.IPin_iface); - *pins = &This->sg->source.pin.IPin_iface; - *nPins = 1; - return S_OK; - } - *nPins = 1; - return S_FALSE; -} - -/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_EndOfStream(IPin *iface) -{ - FIXME(": stub\n"); - return S_OK; -} + IPin_AddRef(filter->sink.pin.peer = connector);
-/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_BeginFlush(IPin *iface) -{ - FIXME(": stub\n"); return S_OK; }
-/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_EndFlush(IPin *iface) -{ - FIXME(": stub\n"); - return S_OK; -} - -/* IPin */ -static HRESULT WINAPI -SampleGrabber_IPin_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double rate) -{ - FIXME(": stub\n"); - return S_OK; -} - - -/* SampleGrabber vtables and constructor */ - static const IBaseFilterVtbl IBaseFilter_VTable = { BaseFilterImpl_QueryInterface, @@ -958,26 +556,69 @@ static const IMemInputPinVtbl IMemInputPin_VTable = SampleGrabber_IMemInputPin_ReceiveCanBlock, };
-static const IPinVtbl IPin_In_VTable = +static const IPinVtbl sink_vtbl = { - sample_grabber_sink_QueryInterface, - SampleGrabber_IPin_AddRef, - SampleGrabber_IPin_Release, - SampleGrabber_In_IPin_Connect, + BasePinImpl_QueryInterface, + BasePinImpl_AddRef, + BasePinImpl_Release, + BaseInputPinImpl_Connect, SampleGrabber_In_IPin_ReceiveConnection, - SampleGrabber_In_IPin_Disconnect, - SampleGrabber_IPin_ConnectedTo, - SampleGrabber_IPin_ConnectionMediaType, - SampleGrabber_IPin_QueryPinInfo, - SampleGrabber_IPin_QueryDirection, - SampleGrabber_IPin_QueryId, - SampleGrabber_IPin_QueryAccept, - SampleGrabber_IPin_EnumMediaTypes, - SampleGrabber_In_IPin_QueryInternalConnections, - SampleGrabber_IPin_EndOfStream, - SampleGrabber_IPin_BeginFlush, - SampleGrabber_IPin_EndFlush, - SampleGrabber_IPin_NewSegment, + BasePinImpl_Disconnect, + BasePinImpl_ConnectedTo, + BasePinImpl_ConnectionMediaType, + BasePinImpl_QueryPinInfo, + BasePinImpl_QueryDirection, + BasePinImpl_QueryId, + BasePinImpl_QueryAccept, + BasePinImpl_EnumMediaTypes, + BasePinImpl_QueryInternalConnections, + BaseInputPinImpl_EndOfStream, + BaseInputPinImpl_BeginFlush, + BaseInputPinImpl_EndFlush, + BaseInputPinImpl_NewSegment +}; + +static inline SG_Impl *impl_from_sink_pin(struct strmbase_pin *iface) +{ + return CONTAINING_RECORD(iface, SG_Impl, sink.pin); +} + +static HRESULT sample_grabber_sink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out) +{ + SG_Impl *filter = impl_from_sink_pin(iface); + + if (IsEqualGUID(iid, &IID_IMemInputPin)) + *out = &filter->IMemInputPin_iface; + else + return E_NOINTERFACE; + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static HRESULT sample_grabber_sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt) +{ + return S_OK; +} + +static HRESULT sample_grabber_sink_get_media_type(struct strmbase_pin *iface, + unsigned int index, AM_MEDIA_TYPE *mt) +{ + SG_Impl *filter = impl_from_sink_pin(iface); + + if (!index) + { + CopyMediaType(mt, &filter->mtype); + return S_OK; + } + return VFW_S_NO_MORE_ITEMS; +} + +static const struct strmbase_sink_ops sink_ops = +{ + .base.pin_query_interface = sample_grabber_sink_query_interface, + .base.pin_query_accept = sample_grabber_sink_query_accept, + .base.pin_get_media_type = sample_grabber_sink_get_media_type, };
static inline SG_Impl *impl_from_source_pin(struct strmbase_pin *iface) @@ -1097,12 +738,8 @@ HRESULT SampleGrabber_create(IUnknown *outer, void **out) strmbase_filter_init(&obj->filter, &IBaseFilter_VTable, outer, &CLSID_SampleGrabber, &filter_ops); obj->ISampleGrabber_iface.lpVtbl = &ISampleGrabber_VTable; obj->IMemInputPin_iface.lpVtbl = &IMemInputPin_VTable; - obj->pin_in.IPin_iface.lpVtbl = &IPin_In_VTable; - obj->pin_in.dir = PINDIR_INPUT; - obj->pin_in.name = pin_in_name; - obj->pin_in.sg = obj; - obj->pin_in.pair = NULL;
+ strmbase_sink_init(&obj->sink, &sink_vtbl, &obj->filter, L"In", &sink_ops, NULL); strmbase_source_init(&obj->source, &source_vtbl, &obj->filter, L"Out", &source_ops);
obj->mtype.majortype = GUID_NULL; @@ -1121,7 +758,7 @@ HRESULT SampleGrabber_create(IUnknown *outer, void **out) if(hr) return hr; IUnknown_QueryInterface(obj->seekthru_unk, &IID_ISeekingPassThru, (void**)&passthru); - ISeekingPassThru_Init(passthru, FALSE, &obj->pin_in.IPin_iface); + ISeekingPassThru_Init(passthru, FALSE, &obj->sink.pin.IPin_iface); ISeekingPassThru_Release(passthru);
*out = &obj->filter.IUnknown_inner; diff --git a/dlls/qedit/tests/samplegrabber.c b/dlls/qedit/tests/samplegrabber.c index 22112c6143..2fcfe100ce 100644 --- a/dlls/qedit/tests/samplegrabber.c +++ b/dlls/qedit/tests/samplegrabber.c @@ -323,7 +323,7 @@ static void test_pin_info(void) CoTaskMemFree(id);
hr = IPin_QueryInternalConnections(pin, NULL, &count); - todo_wine ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr); + ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
IPin_Release(pin);
@@ -462,6 +462,7 @@ static void test_media_types(void)
hr = IPin_EnumMediaTypes(pin, &enummt); todo_wine ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr); + if (hr == S_OK) IEnumMediaTypes_Release(enummt);
hr = IPin_QueryAccept(pin, &mt); ok(hr == S_OK, "Got hr %#x.\n", hr);