ReactOS 0.4.15-dev-7906-g1b85a5f
smartteefilter.c
Go to the documentation of this file.
1/*
2 * Implementation of the SmartTee filter
3 *
4 * Copyright 2015 Damjan Jovanovic
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 <stdarg.h>
22
23#define COBJMACROS
24
25#include "windef.h"
26#include "winbase.h"
27#include "wtypes.h"
28#include "wingdi.h"
29#include "winuser.h"
30#include "dshow.h"
31
32#include "qcap_main.h"
33
34#include "wine/debug.h"
35
37
38typedef struct {
46
48{
49 return CONTAINING_RECORD(iface, SmartTeeFilter, IUnknown_iface);
50}
51
53{
55}
56
58{
59 BaseFilter *filter = CONTAINING_RECORD(iface, BaseFilter, IBaseFilter_iface);
61}
62
64{
65 return impl_from_IBaseFilter(pin->pinInfo.pFilter);
66}
67
68static inline SmartTeeFilter *impl_from_IPin(IPin *iface)
69{
70 BasePin *bp = CONTAINING_RECORD(iface, BasePin, IPin_iface);
71 return impl_from_IBaseFilter(bp->pinInfo.pFilter);
72}
73
75{
78 TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv);
79 *ppv = &This->IUnknown_iface;
80 } else if (IsEqualIID(riid, &IID_IPersist)) {
81 TRACE("(%p)->(IID_IPersist, %p)\n", This, ppv);
82 *ppv = &This->filter.IBaseFilter_iface;
83 } else if (IsEqualIID(riid, &IID_IMediaFilter)) {
84 TRACE("(%p)->(IID_IMediaFilter, %p)\n", This, ppv);
85 *ppv = &This->filter.IBaseFilter_iface;
86 } else if (IsEqualIID(riid, &IID_IBaseFilter)) {
87 TRACE("(%p)->(IID_IBaseFilter, %p)\n", This, ppv);
88 *ppv = &This->filter.IBaseFilter_iface;
89 } else {
90 FIXME("(%p): no interface for %s\n", This, debugstr_guid(riid));
91 *ppv = NULL;
92 return E_NOINTERFACE;
93 }
94 IUnknown_AddRef((IUnknown*)*ppv);
95 return S_OK;
96}
97
99{
101 return BaseFilterImpl_AddRef(&This->filter.IBaseFilter_iface);
102}
103
105{
107 ULONG ref = BaseFilterImpl_Release(&This->filter.IBaseFilter_iface);
108
109 TRACE("(%p)->() ref=%d\n", This, ref);
110
111 if (!ref) {
112 if(This->input)
113 BaseInputPinImpl_Release(&This->input->pin.IPin_iface);
114 if(This->capture)
115 BaseOutputPinImpl_Release(&This->capture->pin.IPin_iface);
116 if(This->preview)
117 BaseOutputPinImpl_Release(&This->preview->pin.IPin_iface);
119 }
120 return ref;
121}
122
123static const IUnknownVtbl UnknownVtbl = {
127};
128
130{
132 return IUnknown_QueryInterface(This->outerUnknown, riid, ppv);
133}
134
136{
138 return IUnknown_AddRef(This->outerUnknown);
139}
140
142{
144 return IUnknown_Release(This->outerUnknown);
145}
146
148{
150 TRACE("(%p)\n", This);
151 EnterCriticalSection(&This->filter.csFilter);
152 This->filter.state = State_Stopped;
153 LeaveCriticalSection(&This->filter.csFilter);
154 return S_OK;
155}
156
158{
160 FIXME("(%p): stub\n", This);
161 return E_NOTIMPL;
162}
163
165{
167 HRESULT hr = S_OK;
168 TRACE("(%p, %s)\n", This, wine_dbgstr_longlong(tStart));
169 EnterCriticalSection(&This->filter.csFilter);
170 if(This->filter.state != State_Running) {
171 /* We share an allocator among all pins, an allocator can only get committed
172 * once, state transitions occur in upstream order, and only output pins
173 * commit allocators, so let the filter attached to the input pin worry about it. */
174 if (This->input->pin.pConnectedTo)
175 This->filter.state = State_Running;
176 else
178 }
179 LeaveCriticalSection(&This->filter.csFilter);
180 return hr;
181}
182
184{
186 TRACE("(%p)->(%s, %p)\n", This, debugstr_w(Id), ppPin);
187 if (lstrcmpW(Id, This->input->pin.pinInfo.achName) == 0) {
188 *ppPin = &This->input->pin.IPin_iface;
189 IPin_AddRef(*ppPin);
190 return S_OK;
191 } else if (lstrcmpW(Id, This->capture->pin.pinInfo.achName) == 0) {
192 *ppPin = &This->capture->pin.IPin_iface;
193 IPin_AddRef(*ppPin);
194 return S_OK;
195 } else if (lstrcmpW(Id, This->preview->pin.pinInfo.achName) == 0) {
196 *ppPin = &This->preview->pin.IPin_iface;
197 IPin_AddRef(*ppPin);
198 return S_OK;
199 }
200 return VFW_E_NOT_FOUND;
201}
202
203static const IBaseFilterVtbl SmartTeeFilterVtbl = {
219};
220
222{
224 IPin *ret;
225
226 TRACE("(%p)->(%d)\n", This, pos);
227
228 switch(pos) {
229 case 0:
230 ret = &This->input->pin.IPin_iface;
231 break;
232 case 1:
233 ret = &This->capture->pin.IPin_iface;
234 break;
235 case 2:
236 ret = &This->preview->pin.IPin_iface;
237 break;
238 default:
239 TRACE("No pin %d\n", pos);
240 return NULL;
241 }
242
243 IPin_AddRef(ret);
244 return ret;
245}
246
248{
249 return 3;
250}
254};
255
257{
259 return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
260}
261
263{
265 return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
266}
267
268
269static const IPinVtbl SmartTeeFilterInputVtbl = {
288};
289
291{
293 TRACE("(%p, AM_MEDIA_TYPE(%p))\n", This, pmt);
295 if (!pmt)
297 /* We'll take any media type, but the output pins will later
298 * struggle to connect downstream. */
299 return S_OK;
300}
301
303{
304 return 0;
305}
306
308{
310 HRESULT hr;
311 TRACE("(%p)->(%d, %p)\n", This, iPosition, amt);
312 if (iPosition)
313 return S_FALSE;
314 EnterCriticalSection(&This->filter.csFilter);
315 if (This->input->pin.pConnectedTo) {
316 CopyMediaType(amt, &This->input->pin.mtCurrent);
317 hr = S_OK;
318 } else
319 hr = S_FALSE;
320 LeaveCriticalSection(&This->filter.csFilter);
321 return hr;
322}
323
325{
326 REFERENCE_TIME startTime, endTime;
327 BOOL haveStartTime = TRUE, haveEndTime = TRUE;
328 IMediaSample *outputSample = NULL;
329 BYTE *ptrIn, *ptrOut;
330 AM_MEDIA_TYPE *mediaType = NULL;
331 HRESULT hr;
332
333 hr = IMediaSample_GetTime(inputSample, &startTime, &endTime);
334 if (hr == S_OK)
335 ;
336 else if (hr == VFW_S_NO_STOP_TIME)
337 haveEndTime = FALSE;
338 else if (hr == VFW_E_SAMPLE_TIME_NOT_SET)
339 haveStartTime = haveEndTime = FALSE;
340 else
341 goto end;
342
343 hr = IMemAllocator_GetBuffer(allocator, &outputSample,
344 haveStartTime ? &startTime : NULL, haveEndTime ? &endTime : NULL, 0);
345 if (FAILED(hr)) goto end;
346 if (IMediaSample_GetSize(outputSample) < IMediaSample_GetActualDataLength(inputSample)) {
347 ERR("insufficient space in sample\n");
349 goto end;
350 }
351
352 hr = IMediaSample_SetTime(outputSample, haveStartTime ? &startTime : NULL, haveEndTime ? &endTime : NULL);
353 if (FAILED(hr)) goto end;
354
355 hr = IMediaSample_GetPointer(inputSample, &ptrIn);
356 if (FAILED(hr)) goto end;
357 hr = IMediaSample_GetPointer(outputSample, &ptrOut);
358 if (FAILED(hr)) goto end;
359 memcpy(ptrOut, ptrIn, IMediaSample_GetActualDataLength(inputSample));
360 IMediaSample_SetActualDataLength(outputSample, IMediaSample_GetActualDataLength(inputSample));
361
362 hr = IMediaSample_SetDiscontinuity(outputSample, IMediaSample_IsDiscontinuity(inputSample) == S_OK);
363 if (FAILED(hr)) goto end;
364
365 haveStartTime = haveEndTime = TRUE;
366 hr = IMediaSample_GetMediaTime(inputSample, &startTime, &endTime);
367 if (hr == S_OK)
368 ;
369 else if (hr == VFW_S_NO_STOP_TIME)
370 haveEndTime = FALSE;
371 else if (hr == VFW_E_MEDIA_TIME_NOT_SET)
372 haveStartTime = haveEndTime = FALSE;
373 else
374 goto end;
375 hr = IMediaSample_SetMediaTime(outputSample, haveStartTime ? &startTime : NULL, haveEndTime ? &endTime : NULL);
376 if (FAILED(hr)) goto end;
377
378 hr = IMediaSample_GetMediaType(inputSample, &mediaType);
379 if (FAILED(hr)) goto end;
380 if (hr == S_OK) {
381 hr = IMediaSample_SetMediaType(outputSample, mediaType);
382 if (FAILED(hr)) goto end;
383 }
384
385 hr = IMediaSample_SetPreroll(outputSample, IMediaSample_IsPreroll(inputSample) == S_OK);
386 if (FAILED(hr)) goto end;
387
388 hr = IMediaSample_SetSyncPoint(outputSample, IMediaSample_IsSyncPoint(inputSample) == S_OK);
389 if (FAILED(hr)) goto end;
390
391end:
392 if (mediaType)
393 DeleteMediaType(mediaType);
394 if (FAILED(hr) && outputSample) {
395 IMediaSample_Release(outputSample);
396 outputSample = NULL;
397 }
398 *pOutputSample = outputSample;
399 return hr;
400}
401
403{
405 IMediaSample *captureSample = NULL;
406 IMediaSample *previewSample = NULL;
407 HRESULT hrCapture = VFW_E_NOT_CONNECTED, hrPreview = VFW_E_NOT_CONNECTED;
408
409 TRACE("(%p)->(%p)\n", This, inputSample);
410
411 /* Modifying the image coming out of one pin doesn't modify the image
412 * coming out of the other. MSDN claims the filter doesn't copy,
413 * but unless it somehow uses copy-on-write, I just don't see how
414 * that's possible. */
415
416 /* FIXME: we should ideally do each of these in a separate thread */
417 EnterCriticalSection(&This->filter.csFilter);
418 if (This->capture->pin.pConnectedTo)
419 hrCapture = copy_sample(inputSample, This->capture->pAllocator, &captureSample);
420 LeaveCriticalSection(&This->filter.csFilter);
421 if (SUCCEEDED(hrCapture))
422 hrCapture = BaseOutputPinImpl_Deliver(This->capture, captureSample);
423 if (captureSample)
424 IMediaSample_Release(captureSample);
425
426 EnterCriticalSection(&This->filter.csFilter);
427 if (This->preview->pin.pConnectedTo)
428 hrPreview = copy_sample(inputSample, This->preview->pAllocator, &previewSample);
429 LeaveCriticalSection(&This->filter.csFilter);
430 /* No timestamps on preview stream: */
431 if (SUCCEEDED(hrPreview))
432 hrPreview = IMediaSample_SetTime(previewSample, NULL, NULL);
433 if (SUCCEEDED(hrPreview))
434 hrPreview = BaseOutputPinImpl_Deliver(This->preview, previewSample);
435 if (previewSample)
436 IMediaSample_Release(previewSample);
437
438 /* FIXME: how to merge the HRESULTs from the 2 pins? */
439 if (SUCCEEDED(hrCapture))
440 return hrCapture;
441 else
442 return hrPreview;
443}
444
446 {
448 NULL,
451 },
453};
454
456{
458 return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
459}
460
462{
464 return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
465}
466
468{
470 HRESULT hr;
471 TRACE("(%p)->(%p)\n", This, ppEnum);
472 EnterCriticalSection(&This->filter.csFilter);
473 if (This->input->pin.pConnectedTo) {
474 hr = BasePinImpl_EnumMediaTypes(iface, ppEnum);
475 } else
477 LeaveCriticalSection(&This->filter.csFilter);
478 return hr;
479}
480
481static const IPinVtbl SmartTeeFilterCaptureVtbl = {
500};
501
503{
505 TRACE("(%p)\n", This);
506 return 0;
507}
508
510{
512 TRACE("(%p, %d, %p)\n", This, iPosition, amt);
513 if (iPosition == 0) {
514 CopyMediaType(amt, &This->input->pin.mtCurrent);
515 return S_OK;
516 } else
517 return S_FALSE;
518}
519
521{
523 TRACE("(%p, %p, %p)\n", This, pPin, pAlloc);
524 *pAlloc = This->input->pAllocator;
525 IMemAllocator_AddRef(This->input->pAllocator);
526 return IMemInputPin_NotifyAllocator(pPin, This->input->pAllocator, TRUE);
527}
528
530{
532 FIXME("(%p): stub\n", This);
533 return E_NOTIMPL;
534}
535
537 {
538 NULL,
542 },
543 NULL,
546};
547
549{
551 return IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
552}
553
555{
557 return IBaseFilter_Release(&This->filter.IBaseFilter_iface);
558}
559
561{
563 HRESULT hr;
564 TRACE("(%p)->(%p)\n", This, ppEnum);
565 EnterCriticalSection(&This->filter.csFilter);
566 if (This->input->pin.pConnectedTo) {
567 hr = BasePinImpl_EnumMediaTypes(iface, ppEnum);
568 } else
570 LeaveCriticalSection(&This->filter.csFilter);
571 return hr;
572}
573
574static const IPinVtbl SmartTeeFilterPreviewVtbl = {
593};
594
596{
598 TRACE("(%p)\n", This);
599 return 0;
600}
601
603{
605 TRACE("(%p, %d, %p)\n", This, iPosition, amt);
606 if (iPosition == 0) {
607 CopyMediaType(amt, &This->input->pin.mtCurrent);
608 return S_OK;
609 } else
610 return S_FALSE;
611}
612
614{
616 TRACE("(%p, %p, %p)\n", This, pPin, pAlloc);
617 *pAlloc = This->input->pAllocator;
618 IMemAllocator_AddRef(This->input->pAllocator);
619 return IMemInputPin_NotifyAllocator(pPin, This->input->pAllocator, TRUE);
620}
621
623{
625 FIXME("(%p): stub\n", This);
626 return E_NOTIMPL;
627}
628
630 {
631 NULL,
635 },
636 NULL,
639};
641{
642 PIN_INFO inputPinInfo = {NULL, PINDIR_INPUT, {'I','n','p','u','t',0}};
643 PIN_INFO capturePinInfo = {NULL, PINDIR_OUTPUT, {'C','a','p','t','u','r','e',0}};
644 PIN_INFO previewPinInfo = {NULL, PINDIR_OUTPUT, {'P','r','e','v','i','e','w',0}};
645 HRESULT hr;
647
648 TRACE("(%p, %p)\n", outer, phr);
649
650 This = CoTaskMemAlloc(sizeof(*This));
651 if (This == NULL) {
653 goto end;
654 }
655 memset(This, 0, sizeof(*This));
656 This->IUnknown_iface.lpVtbl = &UnknownVtbl;
657 if (outer)
658 This->outerUnknown = outer;
659 else
660 This->outerUnknown = &This->IUnknown_iface;
661
662 BaseFilter_Init(&This->filter, &SmartTeeFilterVtbl, &CLSID_SmartTee,
663 (DWORD_PTR)(__FILE__ ": SmartTeeFilter.csFilter"), &SmartTeeFilterFuncs);
664
665 inputPinInfo.pFilter = &This->filter.IBaseFilter_iface;
667 &SmartTeeFilterInputFuncs, &This->filter.csFilter, NULL, (IPin**)&This->input);
668 if (FAILED(hr))
669 goto end;
670 hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
671 &IID_IMemAllocator, (void**)&This->input->pAllocator);
672 if (FAILED(hr))
673 goto end;
674
675 capturePinInfo.pFilter = &This->filter.IBaseFilter_iface;
677 &SmartTeeFilterCaptureFuncs, &This->filter.csFilter, (IPin**)&This->capture);
678 if (FAILED(hr))
679 goto end;
680
681 previewPinInfo.pFilter = &This->filter.IBaseFilter_iface;
683 &SmartTeeFilterPreviewFuncs, &This->filter.csFilter, (IPin**)&This->preview);
684
685end:
686 *phr = hr;
687 if (SUCCEEDED(hr)) {
688 if (outer)
689 return &This->IUnknown_iface;
690 else
691 return (IUnknown*)&This->filter.IBaseFilter_iface;
692 } else {
693 if (This)
694 IBaseFilter_Release(&This->filter.IBaseFilter_iface);
695 return NULL;
696 }
697}
DWORD Id
@ PINDIR_OUTPUT
Definition: axcore.idl:42
@ PINDIR_INPUT
Definition: axcore.idl:41
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
const GUID IID_IBaseFilter
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
static ULONGLONG startTime
Definition: main.c:113
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint end
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
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
#define FAILED(hr)
Definition: intsafe.h:51
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_w
Definition: kernel32.h:32
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static void DeleteMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: filtergraph.c:741
static HRESULT CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
Definition: filtergraph.c:706
long LONG
Definition: pedump.c:60
const GUID IID_IPersist
Definition: proxy.cpp:14
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *pmt)
Definition: enummedia.c:38
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
static HRESULT WINAPI SmartTeeFilter_Pause(IBaseFilter *iface)
static SmartTeeFilter * impl_from_IBaseFilter(IBaseFilter *iface)
static IPin *WINAPI SmartTeeFilter_GetPin(BaseFilter *iface, int pos)
static HRESULT WINAPI SmartTeeFilterPreview_DecideAllocator(BaseOutputPin *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
static HRESULT WINAPI SmartTeeFilter_Stop(IBaseFilter *iface)
static LONG WINAPI SmartTeeFilterPreview_GetMediaTypeVersion(BasePin *base)
static const BaseOutputPinFuncTable SmartTeeFilterPreviewFuncs
static SmartTeeFilter * impl_from_BasePin(BasePin *pin)
static const IPinVtbl SmartTeeFilterCaptureVtbl
static SmartTeeFilter * impl_from_IUnknown(IUnknown *iface)
static HRESULT WINAPI SmartTeeFilter_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)
static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
static LONG WINAPI SmartTeeFilterCapture_GetMediaTypeVersion(BasePin *base)
static ULONG WINAPI SmartTeeFilterCapture_AddRef(IPin *iface)
static const IPinVtbl SmartTeeFilterInputVtbl
static SmartTeeFilter * impl_from_BaseFilter(BaseFilter *filter)
static ULONG WINAPI SmartTeeFilterCapture_Release(IPin *iface)
static HRESULT WINAPI SmartTeeFilterInput_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt)
static const IUnknownVtbl UnknownVtbl
static HRESULT WINAPI SmartTeeFilterCapture_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt)
static SmartTeeFilter * impl_from_IPin(IPin *iface)
static HRESULT WINAPI SmartTeeFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv)
static HRESULT WINAPI SmartTeeFilterCapture_DecideAllocator(BaseOutputPin *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
static const BaseOutputPinFuncTable SmartTeeFilterCaptureFuncs
static const BaseInputPinFuncTable SmartTeeFilterInputFuncs
static ULONG WINAPI SmartTeeFilter_Release(IBaseFilter *iface)
static ULONG WINAPI SmartTeeFilterInput_AddRef(IPin *iface)
IUnknown *WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
static ULONG WINAPI SmartTeeFilterPreview_Release(IPin *iface)
static HRESULT WINAPI SmartTeeFilterInput_Receive(BaseInputPin *base, IMediaSample *inputSample)
static HRESULT WINAPI SmartTeeFilterPreview_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt)
static HRESULT WINAPI SmartTeeFilterInput_CheckMediaType(BasePin *base, const AM_MEDIA_TYPE *pmt)
static HRESULT WINAPI SmartTeeFilterCapture_BreakConnect(BaseOutputPin *base)
static const BaseFilterFuncTable SmartTeeFilterFuncs
static const IBaseFilterVtbl SmartTeeFilterVtbl
static ULONG WINAPI SmartTeeFilter_AddRef(IBaseFilter *iface)
static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
static LONG WINAPI SmartTeeFilterInput_GetMediaTypeVersion(BasePin *base)
static ULONG WINAPI SmartTeeFilterPreview_AddRef(IPin *iface)
static HRESULT copy_sample(IMediaSample *inputSample, IMemAllocator *allocator, IMediaSample **pOutputSample)
static ULONG WINAPI SmartTeeFilterInput_Release(IPin *iface)
static const IPinVtbl SmartTeeFilterPreviewVtbl
static LONG WINAPI SmartTeeFilter_GetPinCount(BaseFilter *iface)
static ULONG WINAPI Unknown_Release(IUnknown *iface)
static HRESULT WINAPI SmartTeeFilterPreview_BreakConnect(BaseOutputPin *base)
static HRESULT WINAPI SmartTeeFilterPreview_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
static HRESULT WINAPI SmartTeeFilterCapture_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
static HRESULT WINAPI SmartTeeFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT WINAPI BasePinImpl_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
Definition: pin.c:248
HRESULT WINAPI BaseInputPinImpl_EndFlush(IPin *iface)
Definition: pin.c:988
HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock)
Definition: filter.c:101
ULONG WINAPI BaseInputPinImpl_Release(IPin *iface)
Definition: pin.c:868
HRESULT WINAPI BasePinImpl_QueryInternalConnections(IPin *iface, IPin **apPin, ULONG *cPin)
Definition: pin.c:329
HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin *iface)
Definition: pin.c:545
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin *iface, IPin **ppPin)
Definition: pin.c:222
HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
Definition: pin.c:1015
HRESULT WINAPI BasePinImpl_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
Definition: pin.c:338
HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter *iface, CLSID *pClsid)
Definition: filter.c:77
ULONG WINAPI BaseFilterImpl_Release(IBaseFilter *iface)
Definition: filter.c:64
HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
Definition: filter.c:145
HRESULT WINAPI BasePinImpl_QueryId(IPin *iface, LPWSTR *Id)
Definition: pin.c:296
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(BasePin *This, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:712
HRESULT BaseInputPin_Construct(const IPinVtbl *InputPin_Vtbl, LONG inputpin_size, const PIN_INFO *pPinInfo, const BaseInputPinFuncTable *pBaseInputFuncsTable, LPCRITICAL_SECTION pCritSec, IMemAllocator *, IPin **ppPin)
Definition: pin.c:1189
HRESULT WINAPI BasePinImpl_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
Definition: pin.c:273
HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin *iface)
Definition: pin.c:527
ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter *iface)
Definition: filter.c:54
HRESULT WINAPI BaseOutputPinImpl_QueryInterface(IPin *iface, REFIID riid, LPVOID *ppv)
Definition: pin.c:363
HRESULT WINAPI BaseOutputPinImpl_Deliver(BaseOutputPin *This, IMediaSample *pSample)
Definition: pin.c:574
HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin *iface)
Definition: pin.c:536
HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
Definition: filter.c:87
HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO *pPinInfo, const BaseOutputPinFuncTable *pBaseOutputFuncsTable, LPCRITICAL_SECTION pCritSec, IPin **ppPin)
Definition: pin.c:791
HRESULT WINAPI BaseInputPinImpl_QueryInterface(IPin *iface, REFIID riid, LPVOID *ppv)
Definition: pin.c:838
ULONG WINAPI BaseOutputPinImpl_Release(IPin *iface)
Definition: pin.c:392
HRESULT WINAPI BasePinImpl_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
Definition: pin.c:318
HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName)
Definition: filter.c:159
HRESULT WINAPI BaseInputPinImpl_BeginFlush(IPin *iface)
Definition: pin.c:968
HRESULT WINAPI BaseOutputPinImpl_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:405
HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo)
Definition: filter.c:178
HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
Definition: filter.c:119
HRESULT WINAPI BasePinImpl_Disconnect(IPin *iface)
Definition: pin.c:197
HRESULT WINAPI BasePinImpl_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
Definition: pin.c:285
HRESULT WINAPI BasePinImpl_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:311
HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:490
HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:889
HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin *iface)
Definition: pin.c:497
HRESULT WINAPI BaseInputPinImpl_Connect(IPin *iface, IPin *pConnector, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:881
HRESULT WINAPI BaseInputPinImpl_EndOfStream(IPin *iface)
Definition: pin.c:944
HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
Definition: filter.c:135
HRESULT WINAPI BaseFilter_Init(BaseFilter *This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid, DWORD_PTR DebugInfo, const BaseFilterFuncTable *pBaseFuncsTable)
Definition: filter.c:196
PIN_INFO pinInfo
Definition: strmbase.h:38
BaseOutputPin * preview
IUnknown * outerUnknown
BaseFilter filter
IUnknown IUnknown_iface
BaseInputPin * input
BaseOutputPin * capture
Definition: regsvr.c:104
Definition: send.c:48
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define VFW_E_SAMPLE_TIME_NOT_SET
Definition: vfwmsgs.h:104
#define VFW_E_MEDIA_TIME_NOT_SET
Definition: vfwmsgs.h:105
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
#define VFW_S_NO_STOP_TIME
Definition: vfwmsgs.h:34
#define VFW_E_BUFFER_OVERFLOW
Definition: vfwmsgs.h:52
#define VFW_E_NOT_FOUND
Definition: vfwmsgs.h:61
#define VFW_E_NOT_CONNECTED
Definition: vfwmsgs.h:48
int ret
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_NOINTERFACE
Definition: winerror.h:2364
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193