1 /* Capture Graph Builder, Minimal edition
3 * Copyright 2005 Maarten Lankhorst
4 * Copyright 2005 Rolf Kalbermatter
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
44 #include "qcap_main.h"
46 #include "wine/unicode.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(qcap
);
51 /***********************************************************************
52 * ICaptureGraphBuilder & ICaptureGraphBuilder2 implementation
54 typedef struct CaptureGraphImpl
56 ICaptureGraphBuilder2 ICaptureGraphBuilder2_iface
;
57 ICaptureGraphBuilder ICaptureGraphBuilder_iface
;
59 IGraphBuilder
*mygraph
;
60 CRITICAL_SECTION csFilter
;
63 static const ICaptureGraphBuilderVtbl builder_Vtbl
;
64 static const ICaptureGraphBuilder2Vtbl builder2_Vtbl
;
66 static inline CaptureGraphImpl
*impl_from_ICaptureGraphBuilder(ICaptureGraphBuilder
*iface
)
68 return CONTAINING_RECORD(iface
, CaptureGraphImpl
, ICaptureGraphBuilder_iface
);
71 static inline CaptureGraphImpl
*impl_from_ICaptureGraphBuilder2(ICaptureGraphBuilder2
*iface
)
73 return CONTAINING_RECORD(iface
, CaptureGraphImpl
, ICaptureGraphBuilder2_iface
);
77 IUnknown
* CALLBACK
QCAP_createCaptureGraphBuilder2(IUnknown
*pUnkOuter
,
80 CaptureGraphImpl
* pCapture
= NULL
;
82 TRACE("(%p, %p)\n", pUnkOuter
, phr
);
84 *phr
= CLASS_E_NOAGGREGATION
;
91 pCapture
= CoTaskMemAlloc(sizeof(CaptureGraphImpl
));
94 pCapture
->ICaptureGraphBuilder2_iface
.lpVtbl
= &builder2_Vtbl
;
95 pCapture
->ICaptureGraphBuilder_iface
.lpVtbl
= &builder_Vtbl
;
97 pCapture
->mygraph
= NULL
;
98 InitializeCriticalSection(&pCapture
->csFilter
);
99 pCapture
->csFilter
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": CaptureGraphImpl.csFilter");
101 ObjectRefCount(TRUE
);
103 return (IUnknown
*)&pCapture
->ICaptureGraphBuilder_iface
;
106 static HRESULT WINAPI
107 fnCaptureGraphBuilder2_QueryInterface(ICaptureGraphBuilder2
* iface
,
111 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
113 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, debugstr_guid(riid
), ppv
);
116 if (IsEqualIID(riid
, &IID_IUnknown
))
117 *ppv
= &This
->ICaptureGraphBuilder2_iface
;
118 else if (IsEqualIID(riid
, &IID_ICaptureGraphBuilder
))
119 *ppv
= &This
->ICaptureGraphBuilder_iface
;
120 else if (IsEqualIID(riid
, &IID_ICaptureGraphBuilder2
))
121 *ppv
= &This
->ICaptureGraphBuilder2_iface
;
125 IUnknown_AddRef((IUnknown
*)(*ppv
));
126 TRACE ("-- Interface = %p\n", *ppv
);
130 TRACE ("-- Interface: E_NOINTERFACE\n");
131 return E_NOINTERFACE
;
135 fnCaptureGraphBuilder2_AddRef(ICaptureGraphBuilder2
* iface
)
137 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
138 DWORD ref
= InterlockedIncrement(&This
->ref
);
140 TRACE("(%p/%p)->() AddRef from %d\n", This
, iface
, ref
- 1);
144 static ULONG WINAPI
fnCaptureGraphBuilder2_Release(ICaptureGraphBuilder2
* iface
)
146 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
147 DWORD ref
= InterlockedDecrement(&This
->ref
);
149 TRACE("(%p/%p)->() Release from %d\n", This
, iface
, ref
+ 1);
153 This
->csFilter
.DebugInfo
->Spare
[0] = 0;
154 DeleteCriticalSection(&This
->csFilter
);
156 IGraphBuilder_Release(This
->mygraph
);
158 ObjectRefCount(FALSE
);
163 static HRESULT WINAPI
164 fnCaptureGraphBuilder2_SetFilterGraph(ICaptureGraphBuilder2
* iface
,
167 /* The graph builder will automatically create a filter graph if you don't call
168 this method. If you call this method after the graph builder has created its
169 own filter graph, the call will fail. */
171 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
173 TRACE("(%p/%p)->(%p)\n", This
, iface
, pfg
);
182 IGraphBuilder_AddRef(This
->mygraph
);
183 if (SUCCEEDED(IGraphBuilder_QueryInterface(This
->mygraph
,
184 &IID_IMediaEvent
, (LPVOID
*)&pmev
)))
186 IMediaEvent_CancelDefaultHandling(pmev
, EC_REPAINT
);
187 IMediaEvent_Release(pmev
);
192 static HRESULT WINAPI
193 fnCaptureGraphBuilder2_GetFilterGraph(ICaptureGraphBuilder2
* iface
,
196 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
198 TRACE("(%p/%p)->(%p)\n", This
, iface
, pfg
);
203 *pfg
= This
->mygraph
;
206 TRACE("(%p) Getting NULL filtergraph\n", iface
);
210 IGraphBuilder_AddRef(This
->mygraph
);
212 TRACE("(%p) return filtergraph %p\n", iface
, *pfg
);
216 static HRESULT WINAPI
217 fnCaptureGraphBuilder2_SetOutputFileName(ICaptureGraphBuilder2
* iface
,
221 IFileSinkFilter
**ppSink
)
223 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
225 FIXME("(%p/%p)->(%s, %s, %p, %p) Stub!\n", This
, iface
,
226 debugstr_guid(pType
), debugstr_w(lpstrFile
), ppf
, ppSink
);
231 static HRESULT WINAPI
232 fnCaptureGraphBuilder2_FindInterface(ICaptureGraphBuilder2
* iface
,
233 const GUID
*pCategory
,
239 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
241 FIXME("(%p/%p)->(%s, %s, %p, %s, %p) - workaround stub!\n", This
, iface
,
242 debugstr_guid(pCategory
), debugstr_guid(pType
),
243 pf
, debugstr_guid(riid
), ppint
);
245 return IBaseFilter_QueryInterface(pf
, riid
, ppint
);
246 /* Looks for the specified interface on the filter, upstream and
247 * downstream from the filter, and, optionally, only on the output
248 * pin of the given category.
252 static HRESULT
match_smart_tee_pin(CaptureGraphImpl
*This
,
253 const GUID
*pCategory
,
258 static const WCHAR inputW
[] = {'I','n','p','u','t',0};
259 static const WCHAR captureW
[] = {'C','a','p','t','u','r','e',0};
260 static const WCHAR previewW
[] = {'P','r','e','v','i','e','w',0};
261 IPin
*capture
= NULL
;
262 IPin
*preview
= NULL
;
264 IBaseFilter
*smartTee
= NULL
;
265 BOOL needSmartTee
= FALSE
;
268 TRACE("(%p, %s, %s, %p, %p)\n", This
, debugstr_guid(pCategory
), debugstr_guid(pType
), pSource
, source_out
);
269 hr
= ICaptureGraphBuilder2_FindPin(&This
->ICaptureGraphBuilder2_iface
, pSource
,
270 PINDIR_OUTPUT
, &PIN_CATEGORY_CAPTURE
, pType
, FALSE
, 0, &capture
);
272 hr
= ICaptureGraphBuilder2_FindPin(&This
->ICaptureGraphBuilder2_iface
, pSource
,
273 PINDIR_OUTPUT
, &PIN_CATEGORY_PREVIEW
, pType
, FALSE
, 0, &preview
);
281 if (IsEqualIID(pCategory
, &PIN_CATEGORY_CAPTURE
)) {
282 hr
= IPin_ConnectedTo(capture
, &peer
);
283 if (hr
== VFW_E_NOT_CONNECTED
) {
284 *source_out
= capture
;
285 IPin_AddRef(*source_out
);
290 hr
= IPin_ConnectedTo(preview
, &peer
);
291 if (hr
== VFW_E_NOT_CONNECTED
) {
292 *source_out
= preview
;
293 IPin_AddRef(*source_out
);
300 hr
= IPin_ConnectedTo(capture
, &peer
);
304 hr
= IPin_QueryPinInfo(peer
, &pinInfo
);
306 hr
= IBaseFilter_GetClassID(pinInfo
.pFilter
, &classID
);
308 if (IsEqualIID(&classID
, &CLSID_SmartTee
)) {
309 smartTee
= pinInfo
.pFilter
;
310 IBaseFilter_AddRef(smartTee
);
313 IBaseFilter_Release(pinInfo
.pFilter
);
319 } else if (hr
== VFW_E_NOT_CONNECTED
) {
320 hr
= CoCreateInstance(&CLSID_SmartTee
, NULL
, CLSCTX_INPROC_SERVER
,
321 &IID_IBaseFilter
, (LPVOID
*)&smartTee
);
323 hr
= IGraphBuilder_AddFilter(This
->mygraph
, smartTee
, NULL
);
325 IPin
*smartTeeInput
= NULL
;
326 hr
= IBaseFilter_FindPin(smartTee
, inputW
, &smartTeeInput
);
328 hr
= IGraphBuilder_ConnectDirect(This
->mygraph
, capture
, smartTeeInput
, NULL
);
329 IPin_Release(smartTeeInput
);
334 TRACE("adding SmartTee failed with hr=0x%08x\n", hr
);
342 if (IsEqualIID(pCategory
, &PIN_CATEGORY_CAPTURE
))
343 hr
= IBaseFilter_FindPin(smartTee
, captureW
, source_out
);
345 hr
= IBaseFilter_FindPin(smartTee
, previewW
, source_out
);
347 hr
= VFW_S_NOPREVIEWPIN
;
352 IPin_Release(capture
);
354 IPin_Release(preview
);
358 IBaseFilter_Release(smartTee
);
359 TRACE("for %s returning hr=0x%08x, *source_out=%p\n", IsEqualIID(pCategory
, &PIN_CATEGORY_CAPTURE
) ? "capture" : "preview", hr
, source_out
? *source_out
: 0);
363 static HRESULT
find_unconnected_pin(CaptureGraphImpl
*This
,
364 const GUID
*pCategory
, const GUID
*pType
, IUnknown
*pSource
, IPin
**out_pin
)
369 BOOL usedSmartTeePreviewPin
= FALSE
;
371 /* depth-first search the graph for the first unconnected pin that matches
372 * the given category and type */
376 if (pCategory
&& (IsEqualIID(pCategory
, &PIN_CATEGORY_CAPTURE
) || IsEqualIID(pCategory
, &PIN_CATEGORY_PREVIEW
))){
377 IBaseFilter
*sourceFilter
= NULL
;
378 hr
= IUnknown_QueryInterface(pSource
, &IID_IBaseFilter
, (void**)&sourceFilter
);
380 hr
= match_smart_tee_pin(This
, pCategory
, pType
, pSource
, &source_out
);
381 if (hr
== VFW_S_NOPREVIEWPIN
)
382 usedSmartTeePreviewPin
= TRUE
;
383 IBaseFilter_Release(sourceFilter
);
385 hr
= ICaptureGraphBuilder2_FindPin(&This
->ICaptureGraphBuilder2_iface
, pSource
, PINDIR_OUTPUT
, pCategory
, pType
, FALSE
, index
, &source_out
);
390 hr
= ICaptureGraphBuilder2_FindPin(&This
->ICaptureGraphBuilder2_iface
, pSource
, PINDIR_OUTPUT
, pCategory
, pType
, FALSE
, index
, &source_out
);
395 hr
= IPin_ConnectedTo(source_out
, &nextpin
);
399 IPin_Release(source_out
);
401 hr
= IPin_QueryPinInfo(nextpin
, &info
);
402 if(FAILED(hr
) || !info
.pFilter
){
403 WARN("QueryPinInfo failed: %08x\n", hr
);
407 hr
= find_unconnected_pin(This
, pCategory
, pType
, (IUnknown
*)info
.pFilter
, out_pin
);
409 IBaseFilter_Release(info
.pFilter
);
414 *out_pin
= source_out
;
415 if(usedSmartTeePreviewPin
)
416 return VFW_S_NOPREVIEWPIN
;
424 static HRESULT WINAPI
425 fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2
* iface
,
426 const GUID
*pCategory
,
429 IBaseFilter
*pfCompressor
,
430 IBaseFilter
*pfRenderer
)
432 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
433 IPin
*source_out
= NULL
, *renderer_in
;
434 BOOL rendererNeedsRelease
= FALSE
;
435 HRESULT hr
, return_hr
= S_OK
;
437 FIXME("(%p/%p)->(%s, %s, %p, %p, %p) semi-stub!\n", This
, iface
,
438 debugstr_guid(pCategory
), debugstr_guid(pType
),
439 pSource
, pfCompressor
, pfRenderer
);
443 FIXME("Need a capture graph\n");
447 if (pCategory
&& IsEqualIID(pCategory
, &PIN_CATEGORY_VBI
)) {
448 FIXME("Tee/Sink-to-Sink filter not supported\n");
452 hr
= find_unconnected_pin(This
, pCategory
, pType
, pSource
, &source_out
);
459 IEnumMediaTypes
*enumMedia
= NULL
;
460 hr
= IPin_EnumMediaTypes(source_out
, &enumMedia
);
462 AM_MEDIA_TYPE
*mediaType
;
463 hr
= IEnumMediaTypes_Next(enumMedia
, 1, &mediaType
, NULL
);
465 if (IsEqualIID(&mediaType
->majortype
, &MEDIATYPE_Video
)) {
466 hr
= CoCreateInstance(&CLSID_VideoRenderer
, NULL
, CLSCTX_INPROC_SERVER
,
467 &IID_IBaseFilter
, (void**)&pfRenderer
);
468 } else if (IsEqualIID(&mediaType
->majortype
, &MEDIATYPE_Audio
)) {
469 hr
= CoCreateInstance(&CLSID_DSoundRender
, NULL
, CLSCTX_INPROC_SERVER
,
470 &IID_IBaseFilter
, (void**)&pfRenderer
);
472 FIXME("cannot automatically load renderer for majortype %s\n", debugstr_guid(&mediaType
->majortype
));
476 rendererNeedsRelease
= TRUE
;
477 hr
= IGraphBuilder_AddFilter(This
->mygraph
, pfRenderer
, NULL
);
479 DeleteMediaType(mediaType
);
481 IEnumMediaTypes_Release(enumMedia
);
484 if (rendererNeedsRelease
)
485 IBaseFilter_Release(pfRenderer
);
486 IPin_Release(source_out
);
491 hr
= ICaptureGraphBuilder2_FindPin(iface
, (IUnknown
*)pfRenderer
, PINDIR_INPUT
, NULL
, NULL
, TRUE
, 0, &renderer_in
);
494 if (rendererNeedsRelease
)
495 IBaseFilter_Release(pfRenderer
);
496 IPin_Release(source_out
);
501 hr
= IGraphBuilder_Connect(This
->mygraph
, source_out
, renderer_in
);
504 IPin
*compressor_in
, *compressor_out
;
506 hr
= ICaptureGraphBuilder2_FindPin(iface
, (IUnknown
*)pfCompressor
,
507 PINDIR_INPUT
, NULL
, NULL
, TRUE
, 0, &compressor_in
);
510 hr
= IGraphBuilder_Connect(This
->mygraph
, source_out
, compressor_in
);
511 IPin_Release(compressor_in
);
516 hr
= ICaptureGraphBuilder2_FindPin(iface
, (IUnknown
*)pfCompressor
,
517 PINDIR_OUTPUT
, NULL
, NULL
, TRUE
, 0, &compressor_out
);
520 hr
= IGraphBuilder_Connect(This
->mygraph
, compressor_out
, renderer_in
);
521 IPin_Release(compressor_out
);
526 IPin_Release(source_out
);
527 IPin_Release(renderer_in
);
528 if (rendererNeedsRelease
)
529 IBaseFilter_Release(pfRenderer
);
535 static HRESULT WINAPI
536 fnCaptureGraphBuilder2_ControlStream(ICaptureGraphBuilder2
* iface
,
537 const GUID
*pCategory
,
539 IBaseFilter
*pFilter
,
540 REFERENCE_TIME
*pstart
,
541 REFERENCE_TIME
*pstop
,
545 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
547 FIXME("(%p/%p)->(%s, %s, %p, %p, %p, %i, %i) Stub!\n", This
, iface
,
548 debugstr_guid(pCategory
), debugstr_guid(pType
),
549 pFilter
, pstart
, pstop
, wStartCookie
, wStopCookie
);
554 static HRESULT WINAPI
555 fnCaptureGraphBuilder2_AllocCapFile(ICaptureGraphBuilder2
* iface
,
559 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
561 FIXME("(%p/%p)->(%s, 0x%s) Stub!\n", This
, iface
,
562 debugstr_w(lpwstr
), wine_dbgstr_longlong(dwlSize
));
567 static HRESULT WINAPI
568 fnCaptureGraphBuilder2_CopyCaptureFile(ICaptureGraphBuilder2
* iface
,
572 IAMCopyCaptureFileProgress
*pCallback
)
574 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
576 FIXME("(%p/%p)->(%s, %s, %i, %p) Stub!\n", This
, iface
,
577 debugstr_w(lpwstrOld
), debugstr_w(lpwstrNew
),
578 fAllowEscAbort
, pCallback
);
583 static HRESULT
pin_matches(IPin
*pin
, PIN_DIRECTION direction
, const GUID
*cat
, const GUID
*type
, BOOL unconnected
)
586 PIN_DIRECTION pindir
;
589 hr
= IPin_QueryDirection(pin
, &pindir
);
591 if (unconnected
&& IPin_ConnectedTo(pin
, &partner
) == S_OK
&& partner
!=NULL
)
593 IPin_Release(partner
);
594 TRACE("No match, %p already connected to %p\n", pin
, partner
);
595 return FAILED(hr
) ? hr
: S_FALSE
;
600 if (SUCCEEDED(hr
) && pindir
!= direction
)
605 IKsPropertySet
*props
;
609 hr
= IPin_QueryInterface(pin
, &IID_IKsPropertySet
, (void**)&props
);
613 hr
= IKsPropertySet_Get(props
, &ROPSETID_Pin
, 0, NULL
,
614 0, &category
, sizeof(category
), &fetched
);
615 IKsPropertySet_Release(props
);
616 if (FAILED(hr
) || !IsEqualIID(&category
, cat
))
622 IEnumMediaTypes
*types
;
623 AM_MEDIA_TYPE
*media_type
;
626 hr
= IPin_EnumMediaTypes(pin
, &types
);
630 IEnumMediaTypes_Reset(types
);
632 if (IEnumMediaTypes_Next(types
, 1, &media_type
, &fetched
) != S_OK
|| fetched
!= 1)
634 IEnumMediaTypes_Release(types
);
638 if (IsEqualIID(&media_type
->majortype
, type
))
640 DeleteMediaType(media_type
);
643 DeleteMediaType(media_type
);
645 IEnumMediaTypes_Release(types
);
648 TRACE("Pin matched\n");
652 static HRESULT WINAPI
653 fnCaptureGraphBuilder2_FindPin(ICaptureGraphBuilder2
* iface
,
655 PIN_DIRECTION pindir
,
656 const GUID
*pCategory
,
663 IEnumPins
*enumpins
= NULL
;
665 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder2(iface
);
667 TRACE("(%p/%p)->(%p, %x, %s, %s, %d, %i, %p)\n", This
, iface
,
668 pSource
, pindir
, debugstr_guid(pCategory
), debugstr_guid(pType
),
669 fUnconnected
, num
, ppPin
);
673 hr
= IUnknown_QueryInterface(pSource
, &IID_IPin
, (void**)&pin
);
674 if (hr
== E_NOINTERFACE
)
676 IBaseFilter
*filter
= NULL
;
679 hr
= IUnknown_QueryInterface(pSource
, &IID_IBaseFilter
, (void**)&filter
);
680 if (hr
== E_NOINTERFACE
)
682 WARN("Input not filter or pin?!\n");
683 return E_NOINTERFACE
;
686 hr
= IBaseFilter_EnumPins(filter
, &enumpins
);
689 WARN("Could not enumerate\n");
690 IBaseFilter_Release(filter
);
698 hr
= IEnumPins_Next(enumpins
, 1, &pin
, &fetched
);
699 if (hr
== VFW_E_ENUM_OUT_OF_SYNC
)
702 IEnumPins_Reset(enumpins
);
714 TRACE("Testing match\n");
715 hr
= pin_matches(pin
, pindir
, pCategory
, pType
, fUnconnected
);
716 if (hr
== S_OK
&& numcurrent
++ == num
)
723 IEnumPins_Release(enumpins
);
724 IBaseFilter_Release(filter
);
728 WARN("Could not find %s pin # %d\n", (pindir
== PINDIR_OUTPUT
? "output" : "input"), numcurrent
);
732 else if (pin_matches(pin
, pindir
, pCategory
, pType
, fUnconnected
) != S_OK
)
742 static const ICaptureGraphBuilder2Vtbl builder2_Vtbl
=
744 fnCaptureGraphBuilder2_QueryInterface
,
745 fnCaptureGraphBuilder2_AddRef
,
746 fnCaptureGraphBuilder2_Release
,
747 fnCaptureGraphBuilder2_SetFilterGraph
,
748 fnCaptureGraphBuilder2_GetFilterGraph
,
749 fnCaptureGraphBuilder2_SetOutputFileName
,
750 fnCaptureGraphBuilder2_FindInterface
,
751 fnCaptureGraphBuilder2_RenderStream
,
752 fnCaptureGraphBuilder2_ControlStream
,
753 fnCaptureGraphBuilder2_AllocCapFile
,
754 fnCaptureGraphBuilder2_CopyCaptureFile
,
755 fnCaptureGraphBuilder2_FindPin
759 static HRESULT WINAPI
760 fnCaptureGraphBuilder_QueryInterface(ICaptureGraphBuilder
* iface
,
761 REFIID riid
, LPVOID
* ppv
)
763 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
764 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
765 return ICaptureGraphBuilder2_QueryInterface(&This
->ICaptureGraphBuilder2_iface
, riid
, ppv
);
769 fnCaptureGraphBuilder_AddRef(ICaptureGraphBuilder
* iface
)
771 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
772 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
773 return ICaptureGraphBuilder2_AddRef(&This
->ICaptureGraphBuilder2_iface
);
777 fnCaptureGraphBuilder_Release(ICaptureGraphBuilder
* iface
)
779 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
780 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
781 return ICaptureGraphBuilder2_Release(&This
->ICaptureGraphBuilder2_iface
);
784 static HRESULT WINAPI
785 fnCaptureGraphBuilder_SetFiltergraph(ICaptureGraphBuilder
* iface
,
788 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
789 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
790 return ICaptureGraphBuilder2_SetFiltergraph(&This
->ICaptureGraphBuilder2_iface
, pfg
);
793 static HRESULT WINAPI
794 fnCaptureGraphBuilder_GetFiltergraph(ICaptureGraphBuilder
* iface
,
797 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
798 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
799 return ICaptureGraphBuilder2_GetFiltergraph(&This
->ICaptureGraphBuilder2_iface
, pfg
);
802 static HRESULT WINAPI
803 fnCaptureGraphBuilder_SetOutputFileName(ICaptureGraphBuilder
* iface
,
804 const GUID
*pType
, LPCOLESTR lpstrFile
,
805 IBaseFilter
**ppf
, IFileSinkFilter
**ppSink
)
807 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
808 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
809 return ICaptureGraphBuilder2_SetOutputFileName(&This
->ICaptureGraphBuilder2_iface
, pType
,
810 lpstrFile
, ppf
, ppSink
);
813 static HRESULT WINAPI
814 fnCaptureGraphBuilder_FindInterface(ICaptureGraphBuilder
* iface
,
815 const GUID
*pCategory
, IBaseFilter
*pf
,
816 REFIID riid
, void **ppint
)
818 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
819 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
820 return ICaptureGraphBuilder2_FindInterface(&This
->ICaptureGraphBuilder2_iface
, pCategory
, NULL
,
824 static HRESULT WINAPI
825 fnCaptureGraphBuilder_RenderStream(ICaptureGraphBuilder
* iface
,
826 const GUID
*pCategory
, IUnknown
*pSource
,
827 IBaseFilter
*pfCompressor
, IBaseFilter
*pfRenderer
)
829 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
830 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
831 return ICaptureGraphBuilder2_RenderStream(&This
->ICaptureGraphBuilder2_iface
, pCategory
, NULL
,
832 pSource
, pfCompressor
, pfRenderer
);
835 static HRESULT WINAPI
836 fnCaptureGraphBuilder_ControlStream(ICaptureGraphBuilder
* iface
,
837 const GUID
*pCategory
, IBaseFilter
*pFilter
,
838 REFERENCE_TIME
*pstart
, REFERENCE_TIME
*pstop
,
839 WORD wStartCookie
, WORD wStopCookie
)
841 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
842 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
843 return ICaptureGraphBuilder2_ControlStream(&This
->ICaptureGraphBuilder2_iface
, pCategory
, NULL
,
844 pFilter
, pstart
, pstop
, wStartCookie
, wStopCookie
);
847 static HRESULT WINAPI
848 fnCaptureGraphBuilder_AllocCapFile(ICaptureGraphBuilder
* iface
,
849 LPCOLESTR lpstr
, DWORDLONG dwlSize
)
851 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
852 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
853 return ICaptureGraphBuilder2_AllocCapFile(&This
->ICaptureGraphBuilder2_iface
, lpstr
, dwlSize
);
856 static HRESULT WINAPI
857 fnCaptureGraphBuilder_CopyCaptureFile(ICaptureGraphBuilder
* iface
,
858 LPOLESTR lpwstrOld
, LPOLESTR lpwstrNew
,
860 IAMCopyCaptureFileProgress
*pCallback
)
862 CaptureGraphImpl
*This
= impl_from_ICaptureGraphBuilder(iface
);
863 TRACE("%p --> Forwarding to v2 (%p)\n", iface
, This
);
864 return ICaptureGraphBuilder2_CopyCaptureFile(&This
->ICaptureGraphBuilder2_iface
, lpwstrOld
,
865 lpwstrNew
, fAllowEscAbort
, pCallback
);
868 static const ICaptureGraphBuilderVtbl builder_Vtbl
=
870 fnCaptureGraphBuilder_QueryInterface
,
871 fnCaptureGraphBuilder_AddRef
,
872 fnCaptureGraphBuilder_Release
,
873 fnCaptureGraphBuilder_SetFiltergraph
,
874 fnCaptureGraphBuilder_GetFiltergraph
,
875 fnCaptureGraphBuilder_SetOutputFileName
,
876 fnCaptureGraphBuilder_FindInterface
,
877 fnCaptureGraphBuilder_RenderStream
,
878 fnCaptureGraphBuilder_ControlStream
,
879 fnCaptureGraphBuilder_AllocCapFile
,
880 fnCaptureGraphBuilder_CopyCaptureFile