1 /* Video For Windows Steering structure
3 * Copyright 2005 Maarten Lankhorst
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define NONAMELESSSTRUCT
22 #define NONAMELESSUNION
35 #include "qcap_main.h"
36 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(qcap);
51 #define ICOM_THIS_MULTI(impl,field,iface) \
52 impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
54 static const IBaseFilterVtbl VfwCapture_Vtbl;
55 static const IAMStreamConfigVtbl IAMStreamConfig_VTable;
56 static const IAMVideoProcAmpVtbl IAMVideoProcAmp_VTable;
57 static const IPersistPropertyBagVtbl IPersistPropertyBag_VTable;
58 static const IPinVtbl VfwPin_Vtbl;
60 static HRESULT VfwPin_Construct( IBaseFilter *, LPCRITICAL_SECTION, IPin ** );
62 typedef struct VfwCapture
64 const struct IBaseFilterVtbl * lpVtbl;
65 const struct IAMStreamConfigVtbl * IAMStreamConfig_vtbl;
66 const struct IAMVideoProcAmpVtbl * IAMVideoProcAmp_vtbl;
67 const struct IPersistPropertyBagVtbl * IPersistPropertyBag_vtbl;
72 FILTER_INFO filterInfo;
74 CRITICAL_SECTION csFilter;
79 /* VfwPin implementation */
80 typedef struct VfwPinImpl
84 IKsPropertySetVtbl * KSP_VT;
87 static const Video_Init Constructors[] =
93 static HRESULT Capture_Initialise(Capture **dimi, IPin *pOut, USHORT card)
99 TRACE("%p %p %hu\n", dimi, pOut, card);
101 driver = CoTaskMemAlloc( sizeof(Capture) );
103 return E_OUTOFMEMORY;
105 for( i=0; FAILED(r) && Constructors[i]; i++ )
106 r = Constructors[i]( driver, pOut, card );
111 CoTaskMemFree( driver );
116 IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr)
118 VfwCapture *pVfwCapture;
121 TRACE("%p - %p\n", pUnkOuter, phr);
123 *phr = CLASS_E_NOAGGREGATION;
126 *phr = E_OUTOFMEMORY;
128 pVfwCapture = CoTaskMemAlloc( sizeof(VfwCapture) );
133 pVfwCapture->lpVtbl = &VfwCapture_Vtbl;
134 pVfwCapture->IAMStreamConfig_vtbl = &IAMStreamConfig_VTable;
135 pVfwCapture->IAMVideoProcAmp_vtbl = &IAMVideoProcAmp_VTable;
136 pVfwCapture->IPersistPropertyBag_vtbl = &IPersistPropertyBag_VTable;
137 pVfwCapture->refCount = 1;
138 pVfwCapture->filterInfo.achName[0] = '\0';
139 pVfwCapture->filterInfo.pGraph = NULL;
140 pVfwCapture->state = State_Stopped;
141 pVfwCapture->init = FALSE;
142 InitializeCriticalSection(&pVfwCapture->csFilter);
143 hr = VfwPin_Construct((IBaseFilter *)&pVfwCapture->lpVtbl,
144 &pVfwCapture->csFilter, &pVfwCapture->pOutputPin);
147 CoTaskMemFree(pVfwCapture);
150 TRACE("-- created at %p\n", pVfwCapture);
152 ObjectRefCount(TRUE);
154 return (IUnknown *)pVfwCapture;
157 static HRESULT WINAPI VfwCapture_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
159 VfwCapture *This = (VfwCapture *)iface;
160 TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
163 if (IsEqualIID(riid, &IID_IUnknown) ||
164 IsEqualIID(riid, &IID_IPersist) ||
165 IsEqualIID(riid, &IID_IMediaFilter) ||
166 IsEqualIID(riid, &IID_IBaseFilter))
170 else if (IsEqualIID(riid, &IID_IAMStreamConfig))
171 *ppv = &(This->IAMStreamConfig_vtbl);
172 else if (IsEqualIID(riid, &IID_IAMVideoProcAmp))
173 *ppv = &(This->IAMVideoProcAmp_vtbl);
174 else if (IsEqualIID(riid, &IID_IPersistPropertyBag))
175 *ppv = &(This->IPersistPropertyBag_vtbl);
177 if (!IsEqualIID(riid, &IID_IUnknown) &&
178 !IsEqualIID(riid, &IID_IPersist) &&
179 !IsEqualIID(riid, &IID_IPersistPropertyBag) &&
182 FIXME("Capture system not initialised when looking for %s, "
183 "trying it on primary device now\n", debugstr_guid(riid));
184 if (FAILED(Capture_Initialise(&This->myCap, (IPin *)This->pOutputPin, 0)))
186 ERR("VfwCapture initialisation failed\n");
194 TRACE("Returning %s interface\n", debugstr_guid(riid));
195 IUnknown_AddRef((IUnknown *)(*ppv));
199 FIXME("No interface for %s!\n", debugstr_guid(riid));
200 return E_NOINTERFACE;
203 static ULONG WINAPI VfwCapture_AddRef(IBaseFilter * iface)
205 VfwCapture *This = (VfwCapture *)iface;
206 ULONG refCount = InterlockedIncrement(&This->refCount);
208 TRACE("%p->() New refcount: %ld\n", This, refCount);
213 static ULONG WINAPI VfwCapture_Release(IBaseFilter * iface)
215 VfwCapture *This = (VfwCapture *)iface;
216 ULONG refCount = InterlockedDecrement(&This->refCount);
218 TRACE("%p->() New refcount: %ld\n", This, refCount);
224 TRACE("destroying everything\n");
227 if (This->state != State_Stopped)
228 INVOKE(This->myCap, Stop, &This->state);
229 INVOKENP(This->myCap, Destroy);
231 pin = (IPinImpl*) This->pOutputPin;
232 if (pin->pConnectedTo != NULL)
234 IPin_Disconnect(pin->pConnectedTo);
235 IPin_Disconnect(This->pOutputPin);
237 IPin_Release(This->pOutputPin);
238 DeleteCriticalSection(&This->csFilter);
241 ObjectRefCount(FALSE);
246 /** IPersist methods **/
248 static HRESULT WINAPI VfwCapture_GetClassID(IBaseFilter * iface, CLSID * pClsid)
250 TRACE("(%p)\n", pClsid);
251 *pClsid = CLSID_VfwCapture;
255 /** IMediaFilter methods **/
257 static HRESULT WINAPI VfwCapture_Stop(IBaseFilter * iface)
259 VfwCapture *This = (VfwCapture *)iface;
262 return INVOKE(This->myCap, Stop, &This->state);
265 static HRESULT WINAPI VfwCapture_Pause(IBaseFilter * iface)
267 VfwCapture *This = (VfwCapture *)iface;
270 return INVOKE(This->myCap, Pause, &This->state);
273 static HRESULT WINAPI VfwCapture_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
275 VfwCapture *This = (VfwCapture *)iface;
276 TRACE("(%lx%08lx)\n", (ULONG)(tStart >> 32), (ULONG)tStart);
277 return INVOKE(This->myCap, Run, &This->state);
280 static HRESULT WINAPI
281 VfwCapture_GetState( IBaseFilter * iface, DWORD dwMilliSecsTimeout,
282 FILTER_STATE *pState )
284 VfwCapture *This = (VfwCapture *)iface;
286 TRACE("(%lu, %p)\n", dwMilliSecsTimeout, pState);
288 *pState = This->state;
292 static HRESULT WINAPI
293 VfwCapture_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
295 TRACE("(%p)\n", pClock);
300 static HRESULT WINAPI
301 VfwCapture_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
303 TRACE("(%p)\n", ppClock);
308 /** IBaseFilter methods **/
310 static HRESULT WINAPI
311 VfwCapture_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
314 VfwCapture *This = (VfwCapture *)iface;
316 TRACE("(%p)\n", ppEnum);
319 epd.ppPins = &This->pOutputPin;
320 return IEnumPinsImpl_Construct(&epd, ppEnum);
323 static HRESULT WINAPI VfwCapture_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin)
325 FIXME("(%s, %p) - stub\n", debugstr_w(Id), ppPin);
329 static HRESULT WINAPI VfwCapture_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
331 VfwCapture *This = (VfwCapture *)iface;
333 TRACE("(%p)\n", pInfo);
335 lstrcpyW(pInfo->achName, This->filterInfo.achName);
336 pInfo->pGraph = This->filterInfo.pGraph;
339 IFilterGraph_AddRef(pInfo->pGraph);
343 static HRESULT WINAPI
344 VfwCapture_JoinFilterGraph( IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName )
346 VfwCapture *This = (VfwCapture *)iface;
348 TRACE("(%p, %s)\n", pGraph, debugstr_w(pName));
351 lstrcpyW(This->filterInfo.achName, pName);
353 *This->filterInfo.achName = 0;
354 This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
359 static HRESULT WINAPI
360 VfwCapture_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
362 FIXME("(%p) - stub\n", pVendorInfo);
366 static const IBaseFilterVtbl VfwCapture_Vtbl =
368 VfwCapture_QueryInterface,
371 VfwCapture_GetClassID,
376 VfwCapture_SetSyncSource,
377 VfwCapture_GetSyncSource,
380 VfwCapture_QueryFilterInfo,
381 VfwCapture_JoinFilterGraph,
382 VfwCapture_QueryVendorInfo
385 /* AMStreamConfig interface, we only need to implement {G,S}etFormat */
386 static HRESULT WINAPI
387 AMStreamConfig_QueryInterface( IAMStreamConfig * iface, REFIID riid, LPVOID * ppv )
389 ICOM_THIS_MULTI(VfwCapture, IAMStreamConfig_vtbl, iface);
391 TRACE("%p --> %s\n", This, debugstr_guid(riid));
393 if (IsEqualIID(riid, &IID_IUnknown) ||
394 IsEqualIID(riid, &IID_IAMStreamConfig))
396 IAMStreamConfig_AddRef(iface);
401 FIXME("No interface for iid %s\n", debugstr_guid(riid));
402 return E_NOINTERFACE;
405 static ULONG WINAPI AMStreamConfig_AddRef( IAMStreamConfig * iface )
407 ICOM_THIS_MULTI(VfwCapture, IAMStreamConfig_vtbl, iface);
409 TRACE("%p --> Forwarding to VfwCapture (%p)\n", iface, This);
410 return IUnknown_AddRef((IUnknown *)This);
413 static ULONG WINAPI AMStreamConfig_Release( IAMStreamConfig * iface )
415 ICOM_THIS_MULTI(VfwCapture, IAMStreamConfig_vtbl, iface);
417 TRACE("%p --> Forwarding to VfwCapture (%p)\n", iface, This);
418 return IUnknown_Release((IUnknown *)This);
421 static HRESULT WINAPI
422 AMStreamConfig_SetFormat(IAMStreamConfig *iface, AM_MEDIA_TYPE *pmt)
425 ICOM_THIS_MULTI(VfwCapture, IAMStreamConfig_vtbl, iface);
428 TRACE("(%p): %p->%p\n", iface, pmt, pmt->pbFormat);
430 if (This->state != State_Stopped)
432 TRACE("Returning not stopped error\n");
433 return VFW_E_NOT_STOPPED;
436 dump_AM_MEDIA_TYPE(pmt);
438 pin = (IPinImpl *)This->pOutputPin;
439 if (pin->pConnectedTo != NULL)
441 hr = IPin_QueryAccept(pin->pConnectedTo, pmt);
442 TRACE("Would accept: %ld\n", hr);
444 return VFW_E_INVALIDMEDIATYPE;
447 hr = INVOKE(This->myCap, SetFormat, pmt);
448 if (SUCCEEDED(hr) && This->filterInfo.pGraph && pin->pConnectedTo )
450 hr = IFilterGraph_Reconnect(This->filterInfo.pGraph, This->pOutputPin);
452 TRACE("Reconnection completed, with new media format..\n");
454 TRACE("Returning: %ld\n", hr);
458 static HRESULT WINAPI
459 AMStreamConfig_GetFormat( IAMStreamConfig *iface, AM_MEDIA_TYPE **pmt )
461 ICOM_THIS_MULTI(VfwCapture, IAMStreamConfig_vtbl, iface);
463 TRACE("%p -> (%p)\n", iface, pmt);
464 return INVOKE(This->myCap, GetFormat, pmt);
467 static HRESULT WINAPI
468 AMStreamConfig_GetNumberOfCapabilities( IAMStreamConfig *iface, int *piCount,
471 FIXME("%p: %p %p - stub, intentional\n", iface, piCount, piSize);
472 return E_NOTIMPL; /* Not implemented for this interface */
475 static HRESULT WINAPI
476 AMStreamConfig_GetStreamCaps( IAMStreamConfig *iface, int iIndex,
477 AM_MEDIA_TYPE **pmt, BYTE *pSCC )
479 FIXME("%p: %d %p %p - stub, intentional\n", iface, iIndex, pmt, pSCC);
480 return E_NOTIMPL; /* Not implemented for this interface */
483 static const IAMStreamConfigVtbl IAMStreamConfig_VTable =
485 AMStreamConfig_QueryInterface,
486 AMStreamConfig_AddRef,
487 AMStreamConfig_Release,
488 AMStreamConfig_SetFormat,
489 AMStreamConfig_GetFormat,
490 AMStreamConfig_GetNumberOfCapabilities,
491 AMStreamConfig_GetStreamCaps
494 static HRESULT WINAPI
495 AMVideoProcAmp_QueryInterface( IAMVideoProcAmp * iface, REFIID riid,
498 if (IsEqualIID(riid, &IID_IUnknown) ||
499 IsEqualIID(riid, &IID_IAMVideoProcAmp))
502 IAMVideoProcAmp_AddRef( iface );
506 FIXME("No interface for iid %s\n", debugstr_guid(riid));
507 return E_NOINTERFACE;
510 static ULONG WINAPI AMVideoProcAmp_AddRef(IAMVideoProcAmp * iface)
512 ICOM_THIS_MULTI(VfwCapture, IAMVideoProcAmp_vtbl, iface);
514 return IUnknown_AddRef((IUnknown *)This);
517 static ULONG WINAPI AMVideoProcAmp_Release(IAMVideoProcAmp * iface)
519 ICOM_THIS_MULTI(VfwCapture, IAMVideoProcAmp_vtbl, iface);
521 return IUnknown_Release((IUnknown *)This);
524 static HRESULT WINAPI
525 AMVideoProcAmp_GetRange( IAMVideoProcAmp * iface, long Property, long *pMin,
526 long *pMax, long *pSteppingDelta, long *pDefault, long *pCapsFlags )
528 ICOM_THIS_MULTI(VfwCapture, IAMVideoProcAmp_vtbl, iface);
530 return INVOKE( This->myCap, GetPropRange, Property, pMin, pMax,
531 pSteppingDelta, pDefault, pCapsFlags );
534 static HRESULT WINAPI
535 AMVideoProcAmp_Set( IAMVideoProcAmp * iface, long Property, long lValue,
538 ICOM_THIS_MULTI(VfwCapture, IAMVideoProcAmp_vtbl, iface);
540 return INVOKE(This->myCap, Set_Prop, Property, lValue, Flags);
543 static HRESULT WINAPI
544 AMVideoProcAmp_Get( IAMVideoProcAmp * iface, long Property, long *lValue,
547 ICOM_THIS_MULTI(VfwCapture, IAMVideoProcAmp_vtbl, iface);
549 return INVOKE(This->myCap, Get_Prop, Property, lValue, Flags);
552 static const IAMVideoProcAmpVtbl IAMVideoProcAmp_VTable =
554 AMVideoProcAmp_QueryInterface,
555 AMVideoProcAmp_AddRef,
556 AMVideoProcAmp_Release,
557 AMVideoProcAmp_GetRange,
562 static HRESULT WINAPI
563 PPB_QueryInterface( IPersistPropertyBag * iface, REFIID riid, LPVOID * ppv )
565 if (IsEqualIID(riid, &IID_IUnknown) ||
566 IsEqualIID(riid, &IID_IPersist) ||
567 IsEqualIID(riid, &IID_IPersistPropertyBag))
569 IPersistPropertyBag_AddRef(iface);
573 if (IsEqualIID(riid, &IID_IBaseFilter))
575 /* FIXME: native devenum asks for IBaseFilter, should we return it? */
576 IPersistPropertyBag_AddRef(iface);
581 FIXME("No interface for iid %s\n", debugstr_guid(riid));
582 return E_NOINTERFACE;
585 static ULONG WINAPI PPB_AddRef(IPersistPropertyBag * iface)
587 ICOM_THIS_MULTI(VfwCapture, IPersistPropertyBag_vtbl, iface);
589 TRACE("%p --> Forwarding to VfwCapture (%p)\n", iface, This);
591 return IUnknown_AddRef((IUnknown *)This);
594 static ULONG WINAPI PPB_Release(IPersistPropertyBag * iface)
596 ICOM_THIS_MULTI(VfwCapture, IPersistPropertyBag_vtbl, iface);
598 TRACE("%p --> Forwarding to VfwCapture (%p)\n", iface, This);
600 return IUnknown_Release((IUnknown *)This);
603 static HRESULT WINAPI
604 PPB_GetClassID( IPersistPropertyBag * iface, CLSID * pClassID )
606 ICOM_THIS_MULTI(VfwCapture, IPersistPropertyBag_vtbl, iface);
608 FIXME("%p - stub\n", This);
613 static HRESULT WINAPI PPB_InitNew(IPersistPropertyBag * iface)
615 ICOM_THIS_MULTI(VfwCapture, IPersistPropertyBag_vtbl, iface);
617 FIXME("%p - stub\n", This);
622 static HRESULT WINAPI
623 PPB_Load( IPersistPropertyBag * iface, IPropertyBag *pPropBag,
624 IErrorLog *pErrorLog )
626 ICOM_THIS_MULTI(VfwCapture, IPersistPropertyBag_vtbl, iface);
629 const OLECHAR VFWIndex[] = {'V','F','W','I','n','d','e','x',0};
631 TRACE("%p/%p-> (%p, %p)\n", iface, This, pPropBag, pErrorLog);
634 hr = IPropertyBag_Read(pPropBag, (LPCOLESTR)VFWIndex, &var, pErrorLog);
640 hr = Capture_Initialise(&This->myCap, This->pOutputPin,
641 (USHORT)var.__VARIANT_NAME_1.__VARIANT_NAME_2.__VARIANT_NAME_3.ulVal);
642 pin = (VfwPinImpl *)This->pOutputPin;
643 pin->myCap = This->myCap;
651 static HRESULT WINAPI
652 PPB_Save( IPersistPropertyBag * iface, IPropertyBag *pPropBag,
653 BOOL fClearDirty, BOOL fSaveAllProperties )
655 ICOM_THIS_MULTI(VfwCapture, IPersistPropertyBag_vtbl, iface);
656 FIXME("%p - stub\n", This);
660 static const IPersistPropertyBagVtbl IPersistPropertyBag_VTable =
671 /* IKsPropertySet interface */
672 static HRESULT WINAPI
673 KSP_QueryInterface( IKsPropertySet * iface, REFIID riid, LPVOID * ppv )
675 if (IsEqualIID(riid, &IID_IUnknown) ||
676 IsEqualIID(riid, &IID_IKsPropertySet))
678 *ppv = (LPVOID)iface;
679 IKsPropertySet_AddRef( iface );
683 FIXME("No interface for iid %s\n", debugstr_guid(riid));
684 return E_NOINTERFACE;
687 static ULONG WINAPI KSP_AddRef(IKsPropertySet * iface)
689 ICOM_THIS_MULTI(VfwPinImpl, KSP_VT, iface);
691 TRACE("%p --> Forwarding to VfwPin (%p)\n", iface, This);
693 return IUnknown_AddRef((IUnknown *)This);
696 static ULONG WINAPI KSP_Release(IKsPropertySet * iface)
698 ICOM_THIS_MULTI(VfwPinImpl, KSP_VT, iface);
700 TRACE("%p --> Forwarding to VfwPin (%p)\n", iface, This);
702 return IUnknown_Release((IUnknown *)This);
705 static HRESULT WINAPI
706 KSP_Set( IKsPropertySet * iface, REFGUID guidPropSet, DWORD dwPropID,
707 LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData,
710 FIXME("%p: stub\n", iface);
714 static HRESULT WINAPI
715 KSP_Get( IKsPropertySet * iface, REFGUID guidPropSet, DWORD dwPropID,
716 LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData,
717 DWORD cbPropData, DWORD *pcbReturned )
723 if (!IsEqualIID(guidPropSet, &ROPSETID_Pin))
724 return E_PROP_SET_UNSUPPORTED;
725 if (pPropData == NULL && pcbReturned == NULL)
728 *pcbReturned = sizeof(GUID);
729 if (pPropData == NULL)
731 if (cbPropData < sizeof(GUID))
734 *pGuid = PIN_CATEGORY_PREVIEW;
735 FIXME("() Not adding a pin with PIN_CATEGORY_CAPTURE\n");
739 static HRESULT WINAPI
740 KSP_QuerySupported( IKsPropertySet * iface, REFGUID guidPropSet,
741 DWORD dwPropID, DWORD *pTypeSupport )
743 FIXME("%p: stub\n", iface);
747 static IKsPropertySetVtbl KSP_VTable =
758 VfwPin_Construct( IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec,
761 static const WCHAR wszOutputPinName[] = { 'O','u','t','p','u','t',0 };
762 ALLOCATOR_PROPERTIES ap;
763 VfwPinImpl * pPinImpl;
767 pPinImpl = CoTaskMemAlloc( sizeof(*pPinImpl) );
769 return E_OUTOFMEMORY;
771 /* What we put here doesn't matter, the
772 driver function should override it then commit */
774 ap.cbBuffer = 230400;
778 piOutput.dir = PINDIR_OUTPUT;
779 piOutput.pFilter = pBaseFilter;
780 lstrcpyW(piOutput.achName, wszOutputPinName);
781 ObjectRefCount(TRUE);
783 hr = OutputPin_Init(&piOutput, &ap, pBaseFilter, NULL, pCritSec, &pPinImpl->pin);
786 pPinImpl->KSP_VT = &KSP_VTable;
787 pPinImpl->pin.pin.lpVtbl = &VfwPin_Vtbl;
788 *ppPin = (IPin *)(&pPinImpl->pin.pin.lpVtbl);
794 static HRESULT WINAPI VfwPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
796 VfwPinImpl *This = (VfwPinImpl *)iface;
798 TRACE("%s %p\n", debugstr_guid(riid), ppv);
801 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin))
803 else if (IsEqualIID(riid, &IID_IKsPropertySet))
804 *ppv = (LPVOID)&(This->KSP_VT);
808 IUnknown_AddRef((IUnknown *)(*ppv));
812 FIXME("No interface for %s!\n", debugstr_guid(riid));
813 return E_NOINTERFACE;
816 static ULONG WINAPI VfwPin_AddRef(IPin * iface)
818 VfwPinImpl *This = (VfwPinImpl *)iface;
819 ULONG refCount = InterlockedIncrement(&This->pin.pin.refCount);
821 TRACE("() -> new refcount: %lu\n", refCount);
827 VfwPin_Release(IPin * iface)
829 VfwPinImpl *This = (VfwPinImpl *)iface;
830 ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount);
832 TRACE("() -> new refcount: %lu\n", refCount);
837 ObjectRefCount(FALSE);
842 static HRESULT WINAPI
843 VfwPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
845 ENUMMEDIADETAILS emd;
849 VfwPinImpl *This = (VfwPinImpl *)iface;
851 hr = INVOKE(This->myCap, GetFormat, &pmt);
852 emd.pMediaTypes = pmt;
854 hr = IEnumMediaTypesImpl_Construct(&emd, ppEnum);
855 TRACE("%p -- %lx\n", This, hr);
856 DeleteMediaType(pmt);
860 static HRESULT WINAPI
861 VfwPin_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin)
863 TRACE("(%p)->(%p, %p)\n", iface, apPin, cPin);
867 static HRESULT WINAPI VfwPin_EndOfStream(IPin * iface)
873 static HRESULT WINAPI VfwPin_BeginFlush(IPin * iface)
875 TRACE("(%p)->()\n", iface);
879 static HRESULT WINAPI VfwPin_EndFlush(IPin * iface)
881 TRACE("(%p)->()\n", iface);
885 static HRESULT WINAPI
886 VfwPin_NewSegment(IPin * iface, REFERENCE_TIME tStart,
887 REFERENCE_TIME tStop, double dRate)
889 TRACE("(%p)->(%s, %s, %e)\n", iface, wine_dbgstr_longlong(tStart),
890 wine_dbgstr_longlong(tStop), dRate);
894 static const IPinVtbl VfwPin_Vtbl =
896 VfwPin_QueryInterface,
900 OutputPin_ReceiveConnection,
901 OutputPin_Disconnect,
902 IPinImpl_ConnectedTo,
903 IPinImpl_ConnectionMediaType,
904 IPinImpl_QueryPinInfo,
905 IPinImpl_QueryDirection,
907 IPinImpl_QueryAccept,
908 VfwPin_EnumMediaTypes,
909 VfwPin_QueryInternalConnections,