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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define NONAMELESSSTRUCT
22 #define NONAMELESSUNION
35 #include "qcap_main.h"
36 #include "wine/debug.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(qcap
);
49 #define ICOM_THIS_MULTI(impl,field,iface) \
50 impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
52 static const IBaseFilterVtbl VfwCapture_Vtbl
;
53 static const IAMStreamConfigVtbl IAMStreamConfig_VTable
;
54 static const IAMVideoProcAmpVtbl IAMVideoProcAmp_VTable
;
55 static const IPersistPropertyBagVtbl IPersistPropertyBag_VTable
;
56 static const IPinVtbl VfwPin_Vtbl
;
58 static HRESULT
VfwPin_Construct( IBaseFilter
*, LPCRITICAL_SECTION
, IPin
** );
60 typedef struct VfwCapture
63 IAMStreamConfig IAMStreamConfig_iface
;
64 IAMVideoProcAmp IAMVideoProcAmp_iface
;
65 IPersistPropertyBag IPersistPropertyBag_iface
;
73 static inline VfwCapture
*impl_from_IAMStreamConfig(IAMStreamConfig
*iface
)
75 return CONTAINING_RECORD(iface
, VfwCapture
, IAMStreamConfig_iface
);
78 static inline VfwCapture
*impl_from_IAMVideoProcAmp(IAMVideoProcAmp
*iface
)
80 return CONTAINING_RECORD(iface
, VfwCapture
, IAMVideoProcAmp_iface
);
83 static inline VfwCapture
*impl_from_IPersistPropertyBag(IPersistPropertyBag
*iface
)
85 return CONTAINING_RECORD(iface
, VfwCapture
, IPersistPropertyBag_iface
);
88 /* VfwPin implementation */
89 typedef struct VfwPinImpl
94 const IKsPropertySetVtbl
* KSP_VT
;
97 static IPin
* WINAPI
VfwCapture_GetPin(BaseFilter
*iface
, int pos
)
99 VfwCapture
*This
= (VfwCapture
*)iface
;
101 if (pos
>= 1 || pos
< 0)
104 IPin_AddRef(This
->pOutputPin
);
105 return This
->pOutputPin
;
108 static LONG WINAPI
VfwCapture_GetPinCount(BaseFilter
*iface
)
113 static const BaseFilterFuncTable BaseFuncTable
= {
115 VfwCapture_GetPinCount
118 IUnknown
* WINAPI
QCAP_createVFWCaptureFilter(IUnknown
*pUnkOuter
, HRESULT
*phr
)
120 VfwCapture
*pVfwCapture
;
123 TRACE("%p - %p\n", pUnkOuter
, phr
);
125 *phr
= CLASS_E_NOAGGREGATION
;
128 *phr
= E_OUTOFMEMORY
;
130 pVfwCapture
= CoTaskMemAlloc( sizeof(VfwCapture
) );
135 BaseFilter_Init(&pVfwCapture
->filter
, &VfwCapture_Vtbl
, &CLSID_VfwCapture
, (DWORD_PTR
)(__FILE__
": VfwCapture.csFilter"), &BaseFuncTable
);
137 pVfwCapture
->IAMStreamConfig_iface
.lpVtbl
= &IAMStreamConfig_VTable
;
138 pVfwCapture
->IAMVideoProcAmp_iface
.lpVtbl
= &IAMVideoProcAmp_VTable
;
139 pVfwCapture
->IPersistPropertyBag_iface
.lpVtbl
= &IPersistPropertyBag_VTable
;
140 pVfwCapture
->init
= FALSE
;
142 hr
= VfwPin_Construct(&pVfwCapture
->filter
.IBaseFilter_iface
,
143 &pVfwCapture
->filter
.csFilter
, &pVfwCapture
->pOutputPin
);
146 CoTaskMemFree(pVfwCapture
);
149 TRACE("-- created at %p\n", pVfwCapture
);
151 ObjectRefCount(TRUE
);
153 return (IUnknown
*)pVfwCapture
;
156 static HRESULT WINAPI
VfwCapture_QueryInterface(IBaseFilter
* iface
, REFIID riid
, LPVOID
* ppv
)
158 VfwCapture
*This
= (VfwCapture
*)iface
;
159 TRACE("(%s, %p)\n", debugstr_guid(riid
), ppv
);
162 if (IsEqualIID(riid
, &IID_IUnknown
) ||
163 IsEqualIID(riid
, &IID_IPersist
) ||
164 IsEqualIID(riid
, &IID_IMediaFilter
) ||
165 IsEqualIID(riid
, &IID_IBaseFilter
))
169 else if (IsEqualIID(riid
, &IID_IAMStreamConfig
))
170 *ppv
= &This
->IAMStreamConfig_iface
;
171 else if (IsEqualIID(riid
, &IID_IAMVideoProcAmp
))
172 *ppv
= &This
->IAMVideoProcAmp_iface
;
173 else if (IsEqualIID(riid
, &IID_IPersistPropertyBag
))
174 *ppv
= &This
->IPersistPropertyBag_iface
;
176 if (!IsEqualIID(riid
, &IID_IUnknown
) &&
177 !IsEqualIID(riid
, &IID_IPersist
) &&
178 !IsEqualIID(riid
, &IID_IPersistPropertyBag
) &&
181 FIXME("Capture system not initialised when looking for %s, "
182 "trying it on primary device now\n", debugstr_guid(riid
));
183 This
->driver_info
= qcap_driver_init( This
->pOutputPin
, 0 );
184 if (!This
->driver_info
)
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_Release(IBaseFilter
* iface
)
205 VfwCapture
*This
= (VfwCapture
*)iface
;
206 ULONG refCount
= InterlockedDecrement(&This
->filter
.refCount
);
208 TRACE("%p->() New refcount: %d\n", This
, refCount
);
214 TRACE("destroying everything\n");
217 if (This
->filter
.state
!= State_Stopped
)
218 qcap_driver_stop(This
->driver_info
, &This
->filter
.state
);
219 qcap_driver_destroy(This
->driver_info
);
221 pin
= (BasePin
*) This
->pOutputPin
;
222 if (pin
->pConnectedTo
!= NULL
)
224 IPin_Disconnect(pin
->pConnectedTo
);
225 IPin_Disconnect(This
->pOutputPin
);
227 IPin_Release(This
->pOutputPin
);
228 BaseFilter_Destroy(&This
->filter
);
230 ObjectRefCount(FALSE
);
235 /** IMediaFilter methods **/
237 static HRESULT WINAPI
VfwCapture_Stop(IBaseFilter
* iface
)
239 VfwCapture
*This
= (VfwCapture
*)iface
;
242 return qcap_driver_stop(This
->driver_info
, &This
->filter
.state
);
245 static HRESULT WINAPI
VfwCapture_Pause(IBaseFilter
* iface
)
247 VfwCapture
*This
= (VfwCapture
*)iface
;
250 return qcap_driver_pause(This
->driver_info
, &This
->filter
.state
);
253 static HRESULT WINAPI
VfwCapture_Run(IBaseFilter
* iface
, REFERENCE_TIME tStart
)
255 VfwCapture
*This
= (VfwCapture
*)iface
;
256 TRACE("(%x%08x)\n", (ULONG
)(tStart
>> 32), (ULONG
)tStart
);
257 return qcap_driver_run(This
->driver_info
, &This
->filter
.state
);
260 /** IBaseFilter methods **/
261 static HRESULT WINAPI
VfwCapture_FindPin(IBaseFilter
* iface
, LPCWSTR Id
, IPin
**ppPin
)
263 FIXME("(%s, %p) - stub\n", debugstr_w(Id
), ppPin
);
267 static const IBaseFilterVtbl VfwCapture_Vtbl
=
269 VfwCapture_QueryInterface
,
270 BaseFilterImpl_AddRef
,
272 BaseFilterImpl_GetClassID
,
276 BaseFilterImpl_GetState
,
277 BaseFilterImpl_SetSyncSource
,
278 BaseFilterImpl_GetSyncSource
,
279 BaseFilterImpl_EnumPins
,
281 BaseFilterImpl_QueryFilterInfo
,
282 BaseFilterImpl_JoinFilterGraph
,
283 BaseFilterImpl_QueryVendorInfo
286 /* AMStreamConfig interface, we only need to implement {G,S}etFormat */
287 static HRESULT WINAPI
288 AMStreamConfig_QueryInterface( IAMStreamConfig
* iface
, REFIID riid
, LPVOID
* ppv
)
290 VfwCapture
*This
= impl_from_IAMStreamConfig(iface
);
292 TRACE("%p --> %s\n", This
, debugstr_guid(riid
));
294 if (IsEqualIID(riid
, &IID_IUnknown
) ||
295 IsEqualIID(riid
, &IID_IAMStreamConfig
))
297 IAMStreamConfig_AddRef(iface
);
302 FIXME("No interface for iid %s\n", debugstr_guid(riid
));
303 return E_NOINTERFACE
;
306 static ULONG WINAPI
AMStreamConfig_AddRef( IAMStreamConfig
* iface
)
308 VfwCapture
*This
= impl_from_IAMStreamConfig(iface
);
310 TRACE("%p --> Forwarding to VfwCapture (%p)\n", iface
, This
);
311 return IUnknown_AddRef((IUnknown
*)This
);
314 static ULONG WINAPI
AMStreamConfig_Release( IAMStreamConfig
* iface
)
316 VfwCapture
*This
= impl_from_IAMStreamConfig(iface
);
318 TRACE("%p --> Forwarding to VfwCapture (%p)\n", iface
, This
);
319 return IUnknown_Release((IUnknown
*)This
);
322 static HRESULT WINAPI
323 AMStreamConfig_SetFormat(IAMStreamConfig
*iface
, AM_MEDIA_TYPE
*pmt
)
326 VfwCapture
*This
= impl_from_IAMStreamConfig(iface
);
329 TRACE("(%p): %p->%p\n", iface
, pmt
, pmt
? pmt
->pbFormat
: NULL
);
331 if (This
->filter
.state
!= State_Stopped
)
333 TRACE("Returning not stopped error\n");
334 return VFW_E_NOT_STOPPED
;
339 TRACE("pmt is NULL\n");
343 dump_AM_MEDIA_TYPE(pmt
);
345 pin
= (BasePin
*)This
->pOutputPin
;
346 if (pin
->pConnectedTo
!= NULL
)
348 hr
= IPin_QueryAccept(pin
->pConnectedTo
, pmt
);
349 TRACE("Would accept: %d\n", hr
);
351 return VFW_E_INVALIDMEDIATYPE
;
354 hr
= qcap_driver_set_format(This
->driver_info
, pmt
);
355 if (SUCCEEDED(hr
) && This
->filter
.filterInfo
.pGraph
&& pin
->pConnectedTo
)
357 hr
= IFilterGraph_Reconnect(This
->filter
.filterInfo
.pGraph
, This
->pOutputPin
);
359 TRACE("Reconnection completed, with new media format..\n");
361 TRACE("Returning: %d\n", hr
);
365 static HRESULT WINAPI
366 AMStreamConfig_GetFormat( IAMStreamConfig
*iface
, AM_MEDIA_TYPE
**pmt
)
368 VfwCapture
*This
= impl_from_IAMStreamConfig(iface
);
370 TRACE("%p -> (%p)\n", iface
, pmt
);
371 return qcap_driver_get_format(This
->driver_info
, pmt
);
374 static HRESULT WINAPI
375 AMStreamConfig_GetNumberOfCapabilities( IAMStreamConfig
*iface
, int *piCount
,
378 FIXME("%p: %p %p - stub, intentional\n", iface
, piCount
, piSize
);
379 return E_NOTIMPL
; /* Not implemented for this interface */
382 static HRESULT WINAPI
383 AMStreamConfig_GetStreamCaps( IAMStreamConfig
*iface
, int iIndex
,
384 AM_MEDIA_TYPE
**pmt
, BYTE
*pSCC
)
386 FIXME("%p: %d %p %p - stub, intentional\n", iface
, iIndex
, pmt
, pSCC
);
387 return E_NOTIMPL
; /* Not implemented for this interface */
390 static const IAMStreamConfigVtbl IAMStreamConfig_VTable
=
392 AMStreamConfig_QueryInterface
,
393 AMStreamConfig_AddRef
,
394 AMStreamConfig_Release
,
395 AMStreamConfig_SetFormat
,
396 AMStreamConfig_GetFormat
,
397 AMStreamConfig_GetNumberOfCapabilities
,
398 AMStreamConfig_GetStreamCaps
401 static HRESULT WINAPI
402 AMVideoProcAmp_QueryInterface( IAMVideoProcAmp
* iface
, REFIID riid
,
405 if (IsEqualIID(riid
, &IID_IUnknown
) ||
406 IsEqualIID(riid
, &IID_IAMVideoProcAmp
))
409 IAMVideoProcAmp_AddRef( iface
);
413 FIXME("No interface for iid %s\n", debugstr_guid(riid
));
414 return E_NOINTERFACE
;
417 static ULONG WINAPI
AMVideoProcAmp_AddRef(IAMVideoProcAmp
* iface
)
419 VfwCapture
*This
= impl_from_IAMVideoProcAmp(iface
);
421 return IUnknown_AddRef((IUnknown
*)This
);
424 static ULONG WINAPI
AMVideoProcAmp_Release(IAMVideoProcAmp
* iface
)
426 VfwCapture
*This
= impl_from_IAMVideoProcAmp(iface
);
428 return IUnknown_Release((IUnknown
*)This
);
431 static HRESULT WINAPI
432 AMVideoProcAmp_GetRange( IAMVideoProcAmp
* iface
, LONG Property
, LONG
*pMin
,
433 LONG
*pMax
, LONG
*pSteppingDelta
, LONG
*pDefault
, LONG
*pCapsFlags
)
435 VfwCapture
*This
= impl_from_IAMVideoProcAmp(iface
);
437 return qcap_driver_get_prop_range( This
->driver_info
, Property
, pMin
, pMax
,
438 pSteppingDelta
, pDefault
, pCapsFlags
);
441 static HRESULT WINAPI
442 AMVideoProcAmp_Set( IAMVideoProcAmp
* iface
, LONG Property
, LONG lValue
,
445 VfwCapture
*This
= impl_from_IAMVideoProcAmp(iface
);
447 return qcap_driver_set_prop(This
->driver_info
, Property
, lValue
, Flags
);
450 static HRESULT WINAPI
451 AMVideoProcAmp_Get( IAMVideoProcAmp
* iface
, LONG Property
, LONG
*lValue
,
454 VfwCapture
*This
= impl_from_IAMVideoProcAmp(iface
);
456 return qcap_driver_get_prop(This
->driver_info
, Property
, lValue
, Flags
);
459 static const IAMVideoProcAmpVtbl IAMVideoProcAmp_VTable
=
461 AMVideoProcAmp_QueryInterface
,
462 AMVideoProcAmp_AddRef
,
463 AMVideoProcAmp_Release
,
464 AMVideoProcAmp_GetRange
,
469 static HRESULT WINAPI
470 PPB_QueryInterface( IPersistPropertyBag
* iface
, REFIID riid
, LPVOID
* ppv
)
472 if (IsEqualIID(riid
, &IID_IUnknown
) ||
473 IsEqualIID(riid
, &IID_IPersist
) ||
474 IsEqualIID(riid
, &IID_IPersistPropertyBag
))
476 IPersistPropertyBag_AddRef(iface
);
480 if (IsEqualIID(riid
, &IID_IBaseFilter
))
482 /* FIXME: native devenum asks for IBaseFilter, should we return it? */
483 IPersistPropertyBag_AddRef(iface
);
488 FIXME("No interface for iid %s\n", debugstr_guid(riid
));
489 return E_NOINTERFACE
;
492 static ULONG WINAPI
PPB_AddRef(IPersistPropertyBag
* iface
)
494 VfwCapture
*This
= impl_from_IPersistPropertyBag(iface
);
496 TRACE("%p --> Forwarding to VfwCapture (%p)\n", iface
, This
);
498 return IUnknown_AddRef((IUnknown
*)This
);
501 static ULONG WINAPI
PPB_Release(IPersistPropertyBag
* iface
)
503 VfwCapture
*This
= impl_from_IPersistPropertyBag(iface
);
505 TRACE("%p --> Forwarding to VfwCapture (%p)\n", iface
, This
);
507 return IUnknown_Release((IUnknown
*)This
);
510 static HRESULT WINAPI
511 PPB_GetClassID( IPersistPropertyBag
* iface
, CLSID
* pClassID
)
513 VfwCapture
*This
= impl_from_IPersistPropertyBag(iface
);
515 FIXME("%p - stub\n", This
);
520 static HRESULT WINAPI
PPB_InitNew(IPersistPropertyBag
* iface
)
522 VfwCapture
*This
= impl_from_IPersistPropertyBag(iface
);
524 FIXME("%p - stub\n", This
);
529 static HRESULT WINAPI
530 PPB_Load( IPersistPropertyBag
* iface
, IPropertyBag
*pPropBag
,
531 IErrorLog
*pErrorLog
)
533 VfwCapture
*This
= impl_from_IPersistPropertyBag(iface
);
536 const OLECHAR VFWIndex
[] = {'V','F','W','I','n','d','e','x',0};
538 TRACE("%p/%p-> (%p, %p)\n", iface
, This
, pPropBag
, pErrorLog
);
541 hr
= IPropertyBag_Read(pPropBag
, VFWIndex
, &var
, pErrorLog
);
547 This
->driver_info
= qcap_driver_init( This
->pOutputPin
,
548 var
.__VARIANT_NAME_1
.__VARIANT_NAME_2
.__VARIANT_NAME_3
.ulVal
);
549 if (This
->driver_info
)
551 pin
= (VfwPinImpl
*)This
->pOutputPin
;
552 pin
->driver_info
= This
->driver_info
;
564 static HRESULT WINAPI
565 PPB_Save( IPersistPropertyBag
* iface
, IPropertyBag
*pPropBag
,
566 BOOL fClearDirty
, BOOL fSaveAllProperties
)
568 VfwCapture
*This
= impl_from_IPersistPropertyBag(iface
);
569 FIXME("%p - stub\n", This
);
573 static const IPersistPropertyBagVtbl IPersistPropertyBag_VTable
=
584 /* IKsPropertySet interface */
585 static HRESULT WINAPI
586 KSP_QueryInterface( IKsPropertySet
* iface
, REFIID riid
, LPVOID
* ppv
)
588 if (IsEqualIID(riid
, &IID_IUnknown
) ||
589 IsEqualIID(riid
, &IID_IKsPropertySet
))
592 IKsPropertySet_AddRef( iface
);
596 FIXME("No interface for iid %s\n", debugstr_guid(riid
));
597 return E_NOINTERFACE
;
600 static ULONG WINAPI
KSP_AddRef(IKsPropertySet
* iface
)
602 ICOM_THIS_MULTI(VfwPinImpl
, KSP_VT
, iface
);
604 TRACE("%p --> Forwarding to VfwPin (%p)\n", iface
, This
);
606 return IUnknown_AddRef((IUnknown
*)This
);
609 static ULONG WINAPI
KSP_Release(IKsPropertySet
* iface
)
611 ICOM_THIS_MULTI(VfwPinImpl
, KSP_VT
, iface
);
613 TRACE("%p --> Forwarding to VfwPin (%p)\n", iface
, This
);
615 return IUnknown_Release((IUnknown
*)This
);
618 static HRESULT WINAPI
619 KSP_Set( IKsPropertySet
* iface
, REFGUID guidPropSet
, DWORD dwPropID
,
620 LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
,
623 FIXME("%p: stub\n", iface
);
627 static HRESULT WINAPI
628 KSP_Get( IKsPropertySet
* iface
, REFGUID guidPropSet
, DWORD dwPropID
,
629 LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
,
630 DWORD cbPropData
, DWORD
*pcbReturned
)
636 if (!IsEqualIID(guidPropSet
, &ROPSETID_Pin
))
637 return E_PROP_SET_UNSUPPORTED
;
638 if (pPropData
== NULL
&& pcbReturned
== NULL
)
641 *pcbReturned
= sizeof(GUID
);
642 if (pPropData
== NULL
)
644 if (cbPropData
< sizeof(GUID
))
647 *pGuid
= PIN_CATEGORY_PREVIEW
;
648 FIXME("() Not adding a pin with PIN_CATEGORY_CAPTURE\n");
652 static HRESULT WINAPI
653 KSP_QuerySupported( IKsPropertySet
* iface
, REFGUID guidPropSet
,
654 DWORD dwPropID
, DWORD
*pTypeSupport
)
656 FIXME("%p: stub\n", iface
);
660 static const IKsPropertySetVtbl KSP_VTable
=
670 static HRESULT WINAPI
VfwPin_GetMediaType(BasePin
*iface
, int iPosition
, AM_MEDIA_TYPE
*pmt
)
672 VfwPinImpl
*This
= (VfwPinImpl
*)iface
;
673 AM_MEDIA_TYPE
*vfw_pmt
;
679 return VFW_S_NO_MORE_ITEMS
;
681 hr
= qcap_driver_get_format(This
->driver_info
, &vfw_pmt
);
683 CopyMediaType(pmt
, vfw_pmt
);
684 DeleteMediaType(vfw_pmt
);
689 static LONG WINAPI
VfwPin_GetMediaTypeVersion(BasePin
*iface
)
694 static HRESULT WINAPI
VfwPin_DecideBufferSize(BaseOutputPin
*iface
, IMemAllocator
*pAlloc
, ALLOCATOR_PROPERTIES
*ppropInputRequest
)
696 ALLOCATOR_PROPERTIES actual
;
698 /* What we put here doesn't matter, the
699 driver function should override it then commit */
700 if (!ppropInputRequest
->cBuffers
)
701 ppropInputRequest
->cBuffers
= 3;
702 if (!ppropInputRequest
->cbBuffer
)
703 ppropInputRequest
->cbBuffer
= 230400;
704 if (!ppropInputRequest
->cbAlign
)
705 ppropInputRequest
->cbAlign
= 1;
707 return IMemAllocator_SetProperties(pAlloc
, ppropInputRequest
, &actual
);
710 static const BaseOutputPinFuncTable output_BaseOutputFuncTable
= {
713 BaseOutputPinImpl_AttemptConnection
,
714 VfwPin_GetMediaTypeVersion
,
717 VfwPin_DecideBufferSize
,
718 BaseOutputPinImpl_DecideAllocator
,
719 BaseOutputPinImpl_BreakConnect
723 VfwPin_Construct( IBaseFilter
* pBaseFilter
, LPCRITICAL_SECTION pCritSec
,
726 static const WCHAR wszOutputPinName
[] = { 'O','u','t','p','u','t',0 };
732 piOutput
.dir
= PINDIR_OUTPUT
;
733 piOutput
.pFilter
= pBaseFilter
;
734 lstrcpyW(piOutput
.achName
, wszOutputPinName
);
736 hr
= BaseOutputPin_Construct(&VfwPin_Vtbl
, sizeof(VfwPinImpl
), &piOutput
, &output_BaseOutputFuncTable
, pCritSec
, ppPin
);
740 VfwPinImpl
*pPinImpl
= (VfwPinImpl
*)*ppPin
;
741 pPinImpl
->KSP_VT
= &KSP_VTable
;
742 ObjectRefCount(TRUE
);
748 static HRESULT WINAPI
VfwPin_QueryInterface(IPin
* iface
, REFIID riid
, LPVOID
* ppv
)
750 VfwPinImpl
*This
= (VfwPinImpl
*)iface
;
752 TRACE("%s %p\n", debugstr_guid(riid
), ppv
);
755 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IPin
))
757 else if (IsEqualIID(riid
, &IID_IKsPropertySet
))
758 *ppv
= &(This
->KSP_VT
);
759 else if (IsEqualIID(riid
, &IID_IAMStreamConfig
))
760 return IUnknown_QueryInterface((IUnknown
*)This
->parent
, riid
, ppv
);
764 IUnknown_AddRef((IUnknown
*)(*ppv
));
768 FIXME("No interface for %s!\n", debugstr_guid(riid
));
769 return E_NOINTERFACE
;
773 VfwPin_Release(IPin
* iface
)
775 VfwPinImpl
*This
= (VfwPinImpl
*)iface
;
776 ULONG refCount
= InterlockedDecrement(&This
->pin
.pin
.refCount
);
778 TRACE("() -> new refcount: %u\n", refCount
);
782 BaseOutputPin_Destroy(&This
->pin
);
783 ObjectRefCount(FALSE
);
788 static HRESULT WINAPI
789 VfwPin_EnumMediaTypes(IPin
* iface
, IEnumMediaTypes
** ppEnum
)
794 VfwPinImpl
*This
= (VfwPinImpl
*)iface
;
795 hr
= qcap_driver_get_format(This
->driver_info
, &pmt
);
797 hr
= BasePinImpl_EnumMediaTypes(iface
, ppEnum
);
798 DeleteMediaType(pmt
);
800 TRACE("%p -- %x\n", This
, hr
);
804 static HRESULT WINAPI
805 VfwPin_QueryInternalConnections(IPin
* iface
, IPin
** apPin
, ULONG
* cPin
)
807 TRACE("(%p)->(%p, %p)\n", iface
, apPin
, cPin
);
811 static const IPinVtbl VfwPin_Vtbl
=
813 VfwPin_QueryInterface
,
816 BaseOutputPinImpl_Connect
,
817 BaseOutputPinImpl_ReceiveConnection
,
818 BaseOutputPinImpl_Disconnect
,
819 BasePinImpl_ConnectedTo
,
820 BasePinImpl_ConnectionMediaType
,
821 BasePinImpl_QueryPinInfo
,
822 BasePinImpl_QueryDirection
,
824 BasePinImpl_QueryAccept
,
825 VfwPin_EnumMediaTypes
,
826 VfwPin_QueryInternalConnections
,
827 BaseOutputPinImpl_EndOfStream
,
828 BaseOutputPinImpl_BeginFlush
,
829 BaseOutputPinImpl_EndFlush
,
830 BasePinImpl_NewSegment