ReactOS 0.4.17-dev-966-gf06eace
capturegraph.c
Go to the documentation of this file.
1/* Capture Graph Builder, Minimal edition
2 *
3 * Copyright 2005 Maarten Lankhorst
4 * Copyright 2005 Rolf Kalbermatter
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include "qcap_private.h"
22
24
25/***********************************************************************
26* ICaptureGraphBuilder & ICaptureGraphBuilder2 implementation
27*/
28typedef struct CaptureGraphImpl
29{
36
37static const ICaptureGraphBuilderVtbl builder_Vtbl;
38static const ICaptureGraphBuilder2Vtbl builder2_Vtbl;
39
41{
42 return CONTAINING_RECORD(iface, CaptureGraphImpl, ICaptureGraphBuilder_iface);
43}
44
46{
47 return CONTAINING_RECORD(iface, CaptureGraphImpl, ICaptureGraphBuilder2_iface);
48}
49
50
52{
54
55 if (outer)
57
58 if (!(object = calloc(1, sizeof(*object))))
59 return E_OUTOFMEMORY;
60
61 object->ICaptureGraphBuilder2_iface.lpVtbl = &builder2_Vtbl;
62 object->ICaptureGraphBuilder_iface.lpVtbl = &builder_Vtbl;
63 object->ref = 1;
64 object->mygraph = NULL;
66 object->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CaptureGraphImpl.csFilter");
67
68 TRACE("Created capture graph builder %p.\n", object);
69 *out = (IUnknown *)&object->ICaptureGraphBuilder_iface;
70 return S_OK;
71}
72
73static HRESULT WINAPI
76 LPVOID * ppv)
77{
79
80 TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppv);
81
82 *ppv = NULL;
84 *ppv = &This->ICaptureGraphBuilder2_iface;
85 else if (IsEqualIID(riid, &IID_ICaptureGraphBuilder))
86 *ppv = &This->ICaptureGraphBuilder_iface;
87 else if (IsEqualIID(riid, &IID_ICaptureGraphBuilder2))
88 *ppv = &This->ICaptureGraphBuilder2_iface;
89
90 if (*ppv)
91 {
92 IUnknown_AddRef((IUnknown *)(*ppv));
93 TRACE ("-- Interface = %p\n", *ppv);
94 return S_OK;
95 }
96
97 TRACE ("-- Interface: E_NOINTERFACE\n");
98 return E_NOINTERFACE;
99}
100
101static ULONG WINAPI
103{
106
107 TRACE("%p increasing refcount to %lu.\n", This, ref);
108
109 return ref;
110}
111
113{
116
117 TRACE("%p decreasing refcount to %lu.\n", This, ref);
118
119 if (!ref)
120 {
121 This->csFilter.DebugInfo->Spare[0] = 0;
122 DeleteCriticalSection(&This->csFilter);
123 if (This->mygraph)
124 IGraphBuilder_Release(This->mygraph);
125 free(This);
126 }
127 return ref;
128}
129
130static HRESULT WINAPI
132 IGraphBuilder *pfg)
133{
134/* The graph builder will automatically create a filter graph if you don't call
135 this method. If you call this method after the graph builder has created its
136 own filter graph, the call will fail. */
137 IMediaEvent *pmev;
139
140 TRACE("(%p/%p)->(%p)\n", This, iface, pfg);
141
142 if (This->mygraph)
143 return E_UNEXPECTED;
144
145 if (!pfg)
146 return E_POINTER;
147
148 This->mygraph = pfg;
149 IGraphBuilder_AddRef(This->mygraph);
150 if (SUCCEEDED(IGraphBuilder_QueryInterface(This->mygraph,
151 &IID_IMediaEvent, (LPVOID *)&pmev)))
152 {
153 IMediaEvent_CancelDefaultHandling(pmev, EC_REPAINT);
154 IMediaEvent_Release(pmev);
155 }
156 return S_OK;
157}
158
159static HRESULT WINAPI
161 IGraphBuilder **pfg)
162{
164
165 TRACE("(%p/%p)->(%p)\n", This, iface, pfg);
166
167 if (!pfg)
168 return E_POINTER;
169
170 *pfg = This->mygraph;
171 if (!This->mygraph)
172 {
173 TRACE("(%p) Getting NULL filtergraph\n", iface);
174 return E_UNEXPECTED;
175 }
176
177 IGraphBuilder_AddRef(This->mygraph);
178
179 TRACE("(%p) return filtergraph %p\n", iface, *pfg);
180 return S_OK;
181}
182
183static HRESULT WINAPI
185 const GUID *pType,
186 LPCOLESTR lpstrFile,
187 IBaseFilter **ppf,
188 IFileSinkFilter **ppSink)
189{
191
192 FIXME("(%p/%p)->(%s, %s, %p, %p) Stub!\n", This, iface,
193 debugstr_guid(pType), debugstr_w(lpstrFile), ppf, ppSink);
194
195 return E_NOTIMPL;
196}
197
198static BOOL pin_has_majortype(IPin *pin, const GUID *majortype)
199{
200 IEnumMediaTypes *enummt;
201 AM_MEDIA_TYPE *mt;
202
203 if (FAILED(IPin_EnumMediaTypes(pin, &enummt)))
204 return FALSE;
205
206 while (IEnumMediaTypes_Next(enummt, 1, &mt, NULL) == S_OK)
207 {
208 if (IsEqualGUID(&mt->majortype, majortype))
209 {
210 DeleteMediaType(mt);
211 IEnumMediaTypes_Release(enummt);
212 return TRUE;
213 }
214 DeleteMediaType(mt);
215 }
216 IEnumMediaTypes_Release(enummt);
217 return FALSE;
218}
219
221 const GUID *majortype, BOOL unconnected)
222{
223 PIN_DIRECTION candidate_dir;
224 HRESULT hr;
225 IPin *peer;
226
227 if (FAILED(hr = IPin_QueryDirection(pin, &candidate_dir)))
228 ERR("Failed to query direction, hr %#lx.\n", hr);
229
230 if (dir != candidate_dir)
231 return FALSE;
232
233 if (unconnected && IPin_ConnectedTo(pin, &peer) == S_OK && peer)
234 {
235 IPin_Release(peer);
236 return FALSE;
237 }
238
239 if (category)
240 {
243 DWORD size;
244
245 if (FAILED(IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **)&set)))
246 return FALSE;
247
249 NULL, 0, &property, sizeof(property), &size);
252 return FALSE;
253 }
254
255 if (majortype && !pin_has_majortype(pin, majortype))
256 return FALSE;
257
258 return TRUE;
259}
260
262 const GUID *majortype, IBaseFilter *filter, REFIID iid, void **out)
263{
264 BOOL found_category = FALSE;
265 IEnumPins *enumpins;
266 IPin *pin, *peer;
268 HRESULT hr;
269
270 TRACE("Looking for %s pins, category %s, majortype %s from filter %p.\n",
271 dir == PINDIR_INPUT ? "sink" : "source", debugstr_guid(category),
272 debugstr_guid(majortype), filter);
273
274 if (FAILED(hr = IBaseFilter_EnumPins(filter, &enumpins)))
275 {
276 ERR("Failed to enumerate pins, hr %#lx.\n", hr);
277 return hr;
278 }
279
280 while (IEnumPins_Next(enumpins, 1, &pin, NULL) == S_OK)
281 {
282 if (!pin_matches(pin, dir, category, majortype, FALSE))
283 {
284 IPin_Release(pin);
285 continue;
286 }
287
288 if (category)
289 found_category = TRUE;
290
291 if (IPin_QueryInterface(pin, iid, out) == S_OK)
292 {
293 IPin_Release(pin);
294 IEnumPins_Release(enumpins);
295 return S_OK;
296 }
297
298 hr = IPin_ConnectedTo(pin, &peer);
299 IPin_Release(pin);
300 if (hr == S_OK)
301 {
302 if (IPin_QueryInterface(peer, iid, out) == S_OK)
303 {
304 IPin_Release(peer);
305 IEnumPins_Release(enumpins);
306 return S_OK;
307 }
308
309 IPin_QueryPinInfo(peer, &info);
310 IPin_Release(peer);
311
312 if (IBaseFilter_QueryInterface(info.pFilter, iid, out) == S_OK)
313 {
314 IBaseFilter_Release(info.pFilter);
315 IEnumPins_Release(enumpins);
316 return S_OK;
317 }
318
319 hr = find_interface_recurse(dir, NULL, NULL, info.pFilter, iid, out);
320 IBaseFilter_Release(info.pFilter);
321 if (hr == S_OK)
322 {
323 IEnumPins_Release(enumpins);
324 return S_OK;
325 }
326 }
327 }
328 IEnumPins_Release(enumpins);
329
330 if (category && !found_category)
331 return E_NOINTERFACE;
332
333 return E_FAIL;
334}
335
337 const GUID *category, const GUID *majortype, IBaseFilter *filter, REFIID iid, void **out)
338{
340 HRESULT hr;
341
342 TRACE("graph %p, category %s, majortype %s, filter %p, iid %s, out %p.\n",
344
345 if (!filter)
346 return E_POINTER;
347
348 if (category && IsEqualGUID(category, &LOOK_DOWNSTREAM_ONLY))
350
351 if (category && IsEqualGUID(category, &LOOK_UPSTREAM_ONLY))
353
354 if (IBaseFilter_QueryInterface(filter, iid, out) == S_OK)
355 return S_OK;
356
357 if (!category)
358 majortype = NULL;
359
361 if (hr == S_OK || hr == E_NOINTERFACE)
362 return hr;
363
365}
366
368 const GUID *pCategory,
369 const GUID *pType,
370 IUnknown *pSource,
371 IPin **source_out)
372{
373 IPin *capture = NULL;
374 IPin *preview = NULL;
375 IPin *peer = NULL;
376 IBaseFilter *smartTee = NULL;
377 BOOL needSmartTee = FALSE;
378 HRESULT hr;
379
380 TRACE("(%p, %s, %s, %p, %p)\n", This, debugstr_guid(pCategory), debugstr_guid(pType), pSource, source_out);
381 hr = ICaptureGraphBuilder2_FindPin(&This->ICaptureGraphBuilder2_iface, pSource,
382 PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, pType, FALSE, 0, &capture);
383 if (SUCCEEDED(hr)) {
384 hr = ICaptureGraphBuilder2_FindPin(&This->ICaptureGraphBuilder2_iface, pSource,
385 PINDIR_OUTPUT, &PIN_CATEGORY_PREVIEW, pType, FALSE, 0, &preview);
386 if (FAILED(hr))
387 needSmartTee = TRUE;
388 } else {
390 goto end;
391 }
392 if (!needSmartTee) {
393 if (IsEqualIID(pCategory, &PIN_CATEGORY_CAPTURE)) {
394 hr = IPin_ConnectedTo(capture, &peer);
395 if (hr == VFW_E_NOT_CONNECTED) {
396 *source_out = capture;
397 IPin_AddRef(*source_out);
398 hr = S_OK;
399 } else
401 } else {
402 hr = IPin_ConnectedTo(preview, &peer);
403 if (hr == VFW_E_NOT_CONNECTED) {
404 *source_out = preview;
405 IPin_AddRef(*source_out);
406 hr = S_OK;
407 } else
409 }
410 goto end;
411 }
412 hr = IPin_ConnectedTo(capture, &peer);
413 if (SUCCEEDED(hr)) {
414 PIN_INFO pinInfo;
415 GUID classID;
416 hr = IPin_QueryPinInfo(peer, &pinInfo);
417 if (SUCCEEDED(hr)) {
418 hr = IBaseFilter_GetClassID(pinInfo.pFilter, &classID);
419 if (SUCCEEDED(hr)) {
420 if (IsEqualIID(&classID, &CLSID_SmartTee)) {
421 smartTee = pinInfo.pFilter;
422 IBaseFilter_AddRef(smartTee);
423 }
424 }
425 IBaseFilter_Release(pinInfo.pFilter);
426 }
427 if (!smartTee) {
429 goto end;
430 }
431 } else if (hr == VFW_E_NOT_CONNECTED) {
432 hr = CoCreateInstance(&CLSID_SmartTee, NULL, CLSCTX_INPROC_SERVER,
433 &IID_IBaseFilter, (LPVOID*)&smartTee);
434 if (SUCCEEDED(hr)) {
435 hr = IGraphBuilder_AddFilter(This->mygraph, smartTee, NULL);
436 if (SUCCEEDED(hr)) {
437 IPin *smartTeeInput = NULL;
438 hr = IBaseFilter_FindPin(smartTee, L"Input", &smartTeeInput);
439 if (SUCCEEDED(hr)) {
440 hr = IGraphBuilder_ConnectDirect(This->mygraph, capture, smartTeeInput, NULL);
441 IPin_Release(smartTeeInput);
442 }
443 }
444 }
445 if (FAILED(hr)) {
446 TRACE("adding SmartTee failed with hr=0x%08lx\n", hr);
448 goto end;
449 }
450 } else {
452 goto end;
453 }
454 if (IsEqualIID(pCategory, &PIN_CATEGORY_CAPTURE))
455 hr = IBaseFilter_FindPin(smartTee, L"Capture", source_out);
456 else {
457 hr = IBaseFilter_FindPin(smartTee, L"Preview", source_out);
458 if (SUCCEEDED(hr))
460 }
461
462end:
463 if (capture)
464 IPin_Release(capture);
465 if (preview)
466 IPin_Release(preview);
467 if (peer)
468 IPin_Release(peer);
469 if (smartTee)
470 IBaseFilter_Release(smartTee);
471 TRACE("for %s returning hr=0x%08lx, *source_out=%p\n", IsEqualIID(pCategory, &PIN_CATEGORY_CAPTURE) ? "capture" : "preview", hr, source_out ? *source_out : 0);
472 return hr;
473}
474
476 const GUID *category, const GUID *majortype, IBaseFilter *filter, IPin **ret);
477
479 const GUID *category, const GUID *majortype, IPin *pin, IPin **ret)
480{
483 HRESULT hr;
484 IPin *peer;
485
486 IPin_QueryDirection(pin, &dir);
487 if (dir != PINDIR_OUTPUT)
489
490 if (category && (IsEqualGUID(category, &PIN_CATEGORY_CAPTURE)
491 || IsEqualGUID(category, &PIN_CATEGORY_PREVIEW)))
492 {
493 if (FAILED(hr = match_smart_tee_pin(capture_graph, category, majortype, (IUnknown *)pin, &pin)))
494 return hr;
495
496 if (FAILED(IPin_ConnectedTo(pin, &peer)))
497 {
498 *ret = pin;
499 return S_OK;
500 }
501 }
502 else
503 {
504 if (FAILED(IPin_ConnectedTo(pin, &peer)))
505 {
506 if (!pin_matches(pin, PINDIR_OUTPUT, category, majortype, FALSE))
507 return E_FAIL;
508
509 IPin_AddRef(*ret = pin);
510 return S_OK;
511 }
512 IPin_AddRef(pin);
513 }
514
515 IPin_QueryPinInfo(peer, &info);
516 hr = find_unconnected_source_from_filter(capture_graph, category, majortype, info.pFilter, ret);
517 IBaseFilter_Release(info.pFilter);
518 IPin_Release(peer);
519 IPin_Release(pin);
520 return hr;
521}
522
524 const GUID *category, const GUID *majortype, IBaseFilter *filter, IPin **ret)
525{
526 IEnumPins *enumpins;
527 IPin *pin, *peer;
528 HRESULT hr;
529
530 if (category && (IsEqualGUID(category, &PIN_CATEGORY_CAPTURE)
531 || IsEqualGUID(category, &PIN_CATEGORY_PREVIEW)))
532 {
533 if (FAILED(hr = match_smart_tee_pin(capture_graph, category, majortype, (IUnknown *)filter, &pin)))
534 return hr;
535
536 if (FAILED(IPin_ConnectedTo(pin, &peer)))
537 {
538 *ret = pin;
539 return hr;
540 }
541
542 IPin_Release(peer);
543 IPin_Release(pin);
544 return E_INVALIDARG;
545 }
546
547 if (FAILED(hr = IBaseFilter_EnumPins(filter, &enumpins)))
548 return hr;
549
550 while (IEnumPins_Next(enumpins, 1, &pin, NULL) == S_OK)
551 {
552 if (SUCCEEDED(hr = find_unconnected_source_from_pin(capture_graph, category, majortype, pin, ret)))
553 {
554 IEnumPins_Release(enumpins);
555 IPin_Release(pin);
556 return hr;
557 }
558 IPin_Release(pin);
559 }
560 IEnumPins_Release(enumpins);
561
562 return E_INVALIDARG;
563}
564
566 const GUID *category, const GUID *majortype, IUnknown *source,
567 IBaseFilter *pfCompressor, IBaseFilter *pfRenderer)
568{
570 IPin *source_out = NULL, *renderer_in;
571 BOOL rendererNeedsRelease = FALSE;
572 HRESULT hr, return_hr = S_OK;
574 IPin *pin;
575
576 TRACE("graph %p, category %s, majortype %s, source %p, intermediate %p, sink %p.\n",
577 This, debugstr_guid(category), debugstr_guid(majortype), source, pfCompressor, pfRenderer);
578
579 if (!This->mygraph)
580 {
581 FIXME("Need a capture graph\n");
582 return E_UNEXPECTED;
583 }
584
585 if (category && IsEqualGUID(category, &PIN_CATEGORY_VBI))
586 {
587 FIXME("Tee/Sink-to-Sink filter not supported\n");
588 return E_NOTIMPL;
589 }
590
591 if (IUnknown_QueryInterface(source, &IID_IPin, (void **)&pin) == S_OK)
592 {
593 hr = find_unconnected_source_from_pin(This, category, majortype, pin, &source_out);
594 IPin_Release(pin);
595 }
596 else if (IUnknown_QueryInterface(source, &IID_IBaseFilter, (void **)&filter) == S_OK)
597 {
598 hr = find_unconnected_source_from_filter(This, category, majortype, filter, &source_out);
599 IBaseFilter_Release(filter);
600 }
601 else
602 {
603 WARN("Source object does not expose IBaseFilter or IPin.\n");
604 return E_INVALIDARG;
605 }
606 if (FAILED(hr))
607 return hr;
608 return_hr = hr;
609
610 if (!pfRenderer)
611 {
612 IEnumMediaTypes *enumMedia = NULL;
613 hr = IPin_EnumMediaTypes(source_out, &enumMedia);
614 if (SUCCEEDED(hr)) {
615 AM_MEDIA_TYPE *mediaType;
616 hr = IEnumMediaTypes_Next(enumMedia, 1, &mediaType, NULL);
617 if (SUCCEEDED(hr)) {
618 if (IsEqualIID(&mediaType->majortype, &MEDIATYPE_Video)) {
619 hr = CoCreateInstance(&CLSID_VideoRenderer, NULL, CLSCTX_INPROC_SERVER,
620 &IID_IBaseFilter, (void**)&pfRenderer);
621 } else if (IsEqualIID(&mediaType->majortype, &MEDIATYPE_Audio)) {
622 hr = CoCreateInstance(&CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER,
623 &IID_IBaseFilter, (void**)&pfRenderer);
624 } else {
625 FIXME("cannot automatically load renderer for majortype %s\n", debugstr_guid(&mediaType->majortype));
626 hr = E_FAIL;
627 }
628 if (SUCCEEDED(hr)) {
629 rendererNeedsRelease = TRUE;
630 hr = IGraphBuilder_AddFilter(This->mygraph, pfRenderer, NULL);
631 }
632 DeleteMediaType(mediaType);
633 }
634 IEnumMediaTypes_Release(enumMedia);
635 }
636 if (FAILED(hr)) {
637 if (rendererNeedsRelease)
638 IBaseFilter_Release(pfRenderer);
639 IPin_Release(source_out);
640 return hr;
641 }
642 }
643
644 hr = ICaptureGraphBuilder2_FindPin(iface, (IUnknown*)pfRenderer, PINDIR_INPUT, NULL, NULL, TRUE, 0, &renderer_in);
645 if (FAILED(hr))
646 {
647 if (rendererNeedsRelease)
648 IBaseFilter_Release(pfRenderer);
649 IPin_Release(source_out);
650 return hr;
651 }
652
653 if (!pfCompressor)
654 hr = IGraphBuilder_Connect(This->mygraph, source_out, renderer_in);
655 else
656 {
657 IPin *compressor_in, *compressor_out;
658
659 hr = ICaptureGraphBuilder2_FindPin(iface, (IUnknown*)pfCompressor,
660 PINDIR_INPUT, NULL, NULL, TRUE, 0, &compressor_in);
661 if (SUCCEEDED(hr))
662 {
663 hr = IGraphBuilder_Connect(This->mygraph, source_out, compressor_in);
664 IPin_Release(compressor_in);
665 }
666
667 if (SUCCEEDED(hr))
668 {
669 hr = ICaptureGraphBuilder2_FindPin(iface, (IUnknown*)pfCompressor,
670 PINDIR_OUTPUT, NULL, NULL, TRUE, 0, &compressor_out);
671 if (SUCCEEDED(hr))
672 {
673 hr = IGraphBuilder_Connect(This->mygraph, compressor_out, renderer_in);
674 IPin_Release(compressor_out);
675 }
676 }
677 }
678
679 IPin_Release(source_out);
680 IPin_Release(renderer_in);
681 if (rendererNeedsRelease)
682 IBaseFilter_Release(pfRenderer);
683 if (SUCCEEDED(hr))
684 return return_hr;
685 return hr;
686}
687
688static HRESULT WINAPI
690 const GUID *pCategory,
691 const GUID *pType,
692 IBaseFilter *pFilter,
693 REFERENCE_TIME *pstart,
694 REFERENCE_TIME *pstop,
695 WORD wStartCookie,
696 WORD wStopCookie)
697{
699
700 FIXME("(%p/%p)->(%s, %s, %p, %p, %p, %i, %i) Stub!\n", This, iface,
701 debugstr_guid(pCategory), debugstr_guid(pType),
702 pFilter, pstart, pstop, wStartCookie, wStopCookie);
703
704 return E_NOTIMPL;
705}
706
707static HRESULT WINAPI
709 LPCOLESTR lpwstr,
710 DWORDLONG dwlSize)
711{
713
714 FIXME("(%p/%p)->(%s, 0x%s) Stub!\n", This, iface,
715 debugstr_w(lpwstr), wine_dbgstr_longlong(dwlSize));
716
717 return E_NOTIMPL;
718}
719
720static HRESULT WINAPI
722 LPOLESTR lpwstrOld,
723 LPOLESTR lpwstrNew,
724 int fAllowEscAbort,
726{
728
729 FIXME("(%p/%p)->(%s, %s, %i, %p) Stub!\n", This, iface,
730 debugstr_w(lpwstrOld), debugstr_w(lpwstrNew),
731 fAllowEscAbort, pCallback);
732
733 return E_NOTIMPL;
734}
735
736static HRESULT WINAPI
738 IUnknown *pSource,
739 PIN_DIRECTION pindir,
740 const GUID *pCategory,
741 const GUID *pType,
742 BOOL fUnconnected,
743 INT num,
744 IPin **ppPin)
745{
746 HRESULT hr;
747 IEnumPins *enumpins = NULL;
748 IPin *pin;
750
751 TRACE("(%p/%p)->(%p, %x, %s, %s, %d, %i, %p)\n", This, iface,
752 pSource, pindir, debugstr_guid(pCategory), debugstr_guid(pType),
753 fUnconnected, num, ppPin);
754
755 pin = NULL;
756
757 hr = IUnknown_QueryInterface(pSource, &IID_IPin, (void**)&pin);
758 if (hr == E_NOINTERFACE)
759 {
761 int numcurrent = 0;
762
763 hr = IUnknown_QueryInterface(pSource, &IID_IBaseFilter, (void**)&filter);
764 if (hr == E_NOINTERFACE)
765 {
766 WARN("Input not filter or pin?!\n");
767 return E_NOINTERFACE;
768 }
769
770 hr = IBaseFilter_EnumPins(filter, &enumpins);
771 if (FAILED(hr))
772 {
773 WARN("Could not enumerate\n");
774 IBaseFilter_Release(filter);
775 return hr;
776 }
777
778 while (1)
779 {
780 ULONG fetched;
781
782 hr = IEnumPins_Next(enumpins, 1, &pin, &fetched);
784 {
785 numcurrent = 0;
786 IEnumPins_Reset(enumpins);
787 pin = NULL;
788 continue;
789 }
790 if (hr != S_OK)
791 break;
792 if (fetched != 1)
793 {
794 hr = E_FAIL;
795 break;
796 }
797
798 TRACE("Testing match\n");
799 if (pin_matches(pin, pindir, pCategory, pType, fUnconnected) && numcurrent++ == num)
800 break;
801 IPin_Release(pin);
802 pin = NULL;
803 }
804 IEnumPins_Release(enumpins);
805 IBaseFilter_Release(filter);
806
807 if (hr != S_OK)
808 {
809 WARN("Could not find %s pin # %d\n", (pindir == PINDIR_OUTPUT ? "output" : "input"), numcurrent);
810 return E_FAIL;
811 }
812 }
813 else if (!pin_matches(pin, pindir, pCategory, pType, fUnconnected))
814 {
815 IPin_Release(pin);
816 return E_FAIL;
817 }
818
819 *ppPin = pin;
820 return S_OK;
821}
822
823static const ICaptureGraphBuilder2Vtbl builder2_Vtbl =
824{
837};
838
839
840static HRESULT WINAPI
843{
845 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
846 return ICaptureGraphBuilder2_QueryInterface(&This->ICaptureGraphBuilder2_iface, riid, ppv);
847}
848
849static ULONG WINAPI
851{
853 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
854 return ICaptureGraphBuilder2_AddRef(&This->ICaptureGraphBuilder2_iface);
855}
856
857static ULONG WINAPI
859{
861 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
862 return ICaptureGraphBuilder2_Release(&This->ICaptureGraphBuilder2_iface);
863}
864
865static HRESULT WINAPI
867 IGraphBuilder *pfg)
868{
870 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
871 return ICaptureGraphBuilder2_SetFiltergraph(&This->ICaptureGraphBuilder2_iface, pfg);
872}
873
874static HRESULT WINAPI
876 IGraphBuilder **pfg)
877{
879 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
880 return ICaptureGraphBuilder2_GetFiltergraph(&This->ICaptureGraphBuilder2_iface, pfg);
881}
882
883static HRESULT WINAPI
885 const GUID *pType, LPCOLESTR lpstrFile,
886 IBaseFilter **ppf, IFileSinkFilter **ppSink)
887{
889 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
890 return ICaptureGraphBuilder2_SetOutputFileName(&This->ICaptureGraphBuilder2_iface, pType,
891 lpstrFile, ppf, ppSink);
892}
893
894static HRESULT WINAPI
896 const GUID *pCategory, IBaseFilter *pf,
897 REFIID riid, void **ppint)
898{
900 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
901 return ICaptureGraphBuilder2_FindInterface(&This->ICaptureGraphBuilder2_iface, pCategory, NULL,
902 pf, riid, ppint);
903}
904
905static HRESULT WINAPI
907 const GUID *pCategory, IUnknown *pSource,
908 IBaseFilter *pfCompressor, IBaseFilter *pfRenderer)
909{
911 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
912 return ICaptureGraphBuilder2_RenderStream(&This->ICaptureGraphBuilder2_iface, pCategory, NULL,
913 pSource, pfCompressor, pfRenderer);
914}
915
916static HRESULT WINAPI
918 const GUID *pCategory, IBaseFilter *pFilter,
919 REFERENCE_TIME *pstart, REFERENCE_TIME *pstop,
920 WORD wStartCookie, WORD wStopCookie)
921{
923 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
924 return ICaptureGraphBuilder2_ControlStream(&This->ICaptureGraphBuilder2_iface, pCategory, NULL,
925 pFilter, pstart, pstop, wStartCookie, wStopCookie);
926}
927
928static HRESULT WINAPI
930 LPCOLESTR lpstr, DWORDLONG dwlSize)
931{
933 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
934 return ICaptureGraphBuilder2_AllocCapFile(&This->ICaptureGraphBuilder2_iface, lpstr, dwlSize);
935}
936
937static HRESULT WINAPI
939 LPOLESTR lpwstrOld, LPOLESTR lpwstrNew,
940 int fAllowEscAbort,
942{
944 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
945 return ICaptureGraphBuilder2_CopyCaptureFile(&This->ICaptureGraphBuilder2_iface, lpwstrOld,
946 lpwstrNew, fAllowEscAbort, pCallback);
947}
948
949static const ICaptureGraphBuilderVtbl builder_Vtbl =
950{
962};
unsigned int dir
Definition: maze.c:112
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
enum _PinDirection PIN_DIRECTION
@ PINDIR_OUTPUT
Definition: axcore.idl:42
@ PINDIR_INPUT
Definition: axcore.idl:41
@ AMPROPERTY_PIN_CATEGORY
Definition: axextend.idl:1160
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static previewinfo preview
Definition: print.c:56
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
static HRESULT find_interface_recurse(PIN_DIRECTION dir, const GUID *category, const GUID *majortype, IBaseFilter *filter, REFIID iid, void **out)
Definition: capturegraph.c:261
static HRESULT WINAPI fnCaptureGraphBuilder_CopyCaptureFile(ICaptureGraphBuilder *iface, LPOLESTR lpwstrOld, LPOLESTR lpwstrNew, int fAllowEscAbort, IAMCopyCaptureFileProgress *pCallback)
Definition: capturegraph.c:938
static BOOL pin_has_majortype(IPin *pin, const GUID *majortype)
Definition: capturegraph.c:198
static HRESULT WINAPI fnCaptureGraphBuilder2_FindInterface(ICaptureGraphBuilder2 *iface, const GUID *category, const GUID *majortype, IBaseFilter *filter, REFIID iid, void **out)
Definition: capturegraph.c:336
static HRESULT WINAPI fnCaptureGraphBuilder_RenderStream(ICaptureGraphBuilder *iface, const GUID *pCategory, IUnknown *pSource, IBaseFilter *pfCompressor, IBaseFilter *pfRenderer)
Definition: capturegraph.c:906
static ULONG WINAPI fnCaptureGraphBuilder_Release(ICaptureGraphBuilder *iface)
Definition: capturegraph.c:858
static HRESULT WINAPI fnCaptureGraphBuilder_QueryInterface(ICaptureGraphBuilder *iface, REFIID riid, LPVOID *ppv)
Definition: capturegraph.c:841
static HRESULT find_unconnected_source_from_filter(CaptureGraphImpl *capture_graph, const GUID *category, const GUID *majortype, IBaseFilter *filter, IPin **ret)
Definition: capturegraph.c:523
static HRESULT WINAPI fnCaptureGraphBuilder_FindInterface(ICaptureGraphBuilder *iface, const GUID *pCategory, IBaseFilter *pf, REFIID riid, void **ppint)
Definition: capturegraph.c:895
static CaptureGraphImpl * impl_from_ICaptureGraphBuilder(ICaptureGraphBuilder *iface)
Definition: capturegraph.c:40
static HRESULT match_smart_tee_pin(CaptureGraphImpl *This, const GUID *pCategory, const GUID *pType, IUnknown *pSource, IPin **source_out)
Definition: capturegraph.c:367
static CaptureGraphImpl * impl_from_ICaptureGraphBuilder2(ICaptureGraphBuilder2 *iface)
Definition: capturegraph.c:45
static HRESULT WINAPI fnCaptureGraphBuilder2_ControlStream(ICaptureGraphBuilder2 *iface, const GUID *pCategory, const GUID *pType, IBaseFilter *pFilter, REFERENCE_TIME *pstart, REFERENCE_TIME *pstop, WORD wStartCookie, WORD wStopCookie)
Definition: capturegraph.c:689
static const ICaptureGraphBuilder2Vtbl builder2_Vtbl
Definition: capturegraph.c:38
static ULONG WINAPI fnCaptureGraphBuilder2_Release(ICaptureGraphBuilder2 *iface)
Definition: capturegraph.c:112
static HRESULT WINAPI fnCaptureGraphBuilder_SetOutputFileName(ICaptureGraphBuilder *iface, const GUID *pType, LPCOLESTR lpstrFile, IBaseFilter **ppf, IFileSinkFilter **ppSink)
Definition: capturegraph.c:884
static HRESULT WINAPI fnCaptureGraphBuilder2_SetFilterGraph(ICaptureGraphBuilder2 *iface, IGraphBuilder *pfg)
Definition: capturegraph.c:131
static ULONG WINAPI fnCaptureGraphBuilder_AddRef(ICaptureGraphBuilder *iface)
Definition: capturegraph.c:850
static HRESULT WINAPI fnCaptureGraphBuilder2_SetOutputFileName(ICaptureGraphBuilder2 *iface, const GUID *pType, LPCOLESTR lpstrFile, IBaseFilter **ppf, IFileSinkFilter **ppSink)
Definition: capturegraph.c:184
static HRESULT WINAPI fnCaptureGraphBuilder2_FindPin(ICaptureGraphBuilder2 *iface, IUnknown *pSource, PIN_DIRECTION pindir, const GUID *pCategory, const GUID *pType, BOOL fUnconnected, INT num, IPin **ppPin)
Definition: capturegraph.c:737
static HRESULT WINAPI fnCaptureGraphBuilder_ControlStream(ICaptureGraphBuilder *iface, const GUID *pCategory, IBaseFilter *pFilter, REFERENCE_TIME *pstart, REFERENCE_TIME *pstop, WORD wStartCookie, WORD wStopCookie)
Definition: capturegraph.c:917
static HRESULT WINAPI fnCaptureGraphBuilder2_QueryInterface(ICaptureGraphBuilder2 *iface, REFIID riid, LPVOID *ppv)
Definition: capturegraph.c:74
static HRESULT WINAPI fnCaptureGraphBuilder_AllocCapFile(ICaptureGraphBuilder *iface, LPCOLESTR lpstr, DWORDLONG dwlSize)
Definition: capturegraph.c:929
static HRESULT WINAPI fnCaptureGraphBuilder2_GetFilterGraph(ICaptureGraphBuilder2 *iface, IGraphBuilder **pfg)
Definition: capturegraph.c:160
static HRESULT find_unconnected_source_from_pin(CaptureGraphImpl *capture_graph, const GUID *category, const GUID *majortype, IPin *pin, IPin **ret)
Definition: capturegraph.c:478
static ULONG WINAPI fnCaptureGraphBuilder2_AddRef(ICaptureGraphBuilder2 *iface)
Definition: capturegraph.c:102
static HRESULT WINAPI fnCaptureGraphBuilder_SetFiltergraph(ICaptureGraphBuilder *iface, IGraphBuilder *pfg)
Definition: capturegraph.c:866
static HRESULT WINAPI fnCaptureGraphBuilder2_AllocCapFile(ICaptureGraphBuilder2 *iface, LPCOLESTR lpwstr, DWORDLONG dwlSize)
Definition: capturegraph.c:708
static const ICaptureGraphBuilderVtbl builder_Vtbl
Definition: capturegraph.c:37
static HRESULT WINAPI fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 *iface, const GUID *category, const GUID *majortype, IUnknown *source, IBaseFilter *pfCompressor, IBaseFilter *pfRenderer)
Definition: capturegraph.c:565
static HRESULT WINAPI fnCaptureGraphBuilder_GetFiltergraph(ICaptureGraphBuilder *iface, IGraphBuilder **pfg)
Definition: capturegraph.c:875
HRESULT capture_graph_create(IUnknown *outer, IUnknown **out)
Definition: capturegraph.c:51
static BOOL pin_matches(IPin *pin, PIN_DIRECTION dir, const GUID *category, const GUID *majortype, BOOL unconnected)
Definition: capturegraph.c:220
static HRESULT WINAPI fnCaptureGraphBuilder2_CopyCaptureFile(ICaptureGraphBuilder2 *iface, LPOLESTR lpwstrOld, LPOLESTR lpwstrNew, int fAllowEscAbort, IAMCopyCaptureFileProgress *pCallback)
Definition: capturegraph.c:721
Definition: _set.h:50
const GUID IID_IKsPropertySet
Definition: controlnode.cpp:13
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define free
Definition: debug_ros.c:5
HRESULT hr
Definition: delayimp.cpp:582
const GUID IID_IBaseFilter
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
#define IKsPropertySet_Release(p)
Definition: dsound.h:1152
#define IKsPropertySet_Get(p, a, b, c, d, e, f, g)
Definition: dsound.h:1154
#define EC_REPAINT
Definition: evcode.h:36
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxPnpStateCallbackInfo * pCallback
GLuint GLuint end
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint GLuint num
Definition: glext.h:9618
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
Definition: axcore.idl:92
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
unsigned long long DWORDLONG
Definition: intsafe.h:93
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
static IUnknown * outer
Definition: compobj.c:82
long LONG
Definition: pedump.c:60
const GUID IID_IPin
Definition: pincontrol.cpp:15
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define calloc
Definition: rosglue.h:14
#define TRACE(s)
Definition: solgame.cpp:4
void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: mediatype.c:193
CRITICAL_SECTION csFilter
Definition: capturegraph.c:34
ICaptureGraphBuilder ICaptureGraphBuilder_iface
Definition: capturegraph.c:31
ICaptureGraphBuilder2 ICaptureGraphBuilder2_iface
Definition: capturegraph.c:30
IGraphBuilder * mygraph
Definition: capturegraph.c:33
Definition: filter.c:165
Definition: graph.c:32
Definition: send.c:48
#define DWORD_PTR
Definition: treelist.c:76
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define VFW_E_INVALID_DIRECTION
Definition: vfwmsgs.h:47
#define VFW_E_ENUM_OUT_OF_SYNC
Definition: vfwmsgs.h:42
#define VFW_E_NOT_CONNECTED
Definition: vfwmsgs.h:48
#define VFW_S_NOPREVIEWPIN
Definition: vfwmsgs.h:35
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:3479
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:3771
#define E_UNEXPECTED
Definition: winerror.h:3528
#define E_POINTER
Definition: winerror.h:3480
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156