ReactOS  0.4.15-dev-1070-ge1a01de
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 
38 typedef 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 
68 static 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 {
77  if (IsEqualIID(riid, &IID_IUnknown)) {
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 
123 static 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 
203 static 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 
269 static const IPinVtbl SmartTeeFilterInputVtbl = {
288 };
289 
291 {
293  TRACE("(%p, AM_MEDIA_TYPE(%p))\n", This, pmt);
294  dump_AM_MEDIA_TYPE(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 
324 static HRESULT copy_sample(IMediaSample *inputSample, IMemAllocator *allocator, IMediaSample **pOutputSample)
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 
391 end:
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 
481 static 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 
574 static 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) {
652  hr = E_OUTOFMEMORY;
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 
685 end:
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 }
const GUID IID_IBaseFilter
static const IBaseFilterVtbl SmartTeeFilterVtbl
HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter *iface, IReferenceClock *pClock)
Definition: filter.c:101
#define REFIID
Definition: guiddef.h:118
static HRESULT WINAPI SmartTeeFilter_Pause(IBaseFilter *iface)
#define E_NOINTERFACE
Definition: winerror.h:2364
static const IPinVtbl SmartTeeFilterPreviewVtbl
static LONG WINAPI SmartTeeFilterPreview_GetMediaTypeVersion(BasePin *base)
HRESULT WINAPI BaseInputPinImpl_QueryInterface(IPin *iface, REFIID riid, LPVOID *ppv)
Definition: pin.c:838
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define TRUE
Definition: types.h:120
REFIID riid
Definition: precomp.h:44
HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
Definition: filter.c:87
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static ULONGLONG startTime
Definition: main.c:113
const GUID IID_IPersist
Definition: proxy.cpp:14
HRESULT WINAPI BaseInputPinImpl_Connect(IPin *iface, IPin *pConnector, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:881
HRESULT WINAPI BaseInputPinImpl_EndFlush(IPin *iface)
Definition: pin.c:988
static HRESULT WINAPI SmartTeeFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv)
static SmartTeeFilter * impl_from_IUnknown(IUnknown *iface)
REFIID LPVOID * ppv
Definition: atlbase.h:39
HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin *iface)
Definition: pin.c:527
static HRESULT copy_sample(IMediaSample *inputSample, IMemAllocator *allocator, IMediaSample **pOutputSample)
static SmartTeeFilter * impl_from_IBaseFilter(IBaseFilter *iface)
static ULONG WINAPI SmartTeeFilterCapture_AddRef(IPin *iface)
GLuint GLuint end
Definition: gl.h:1545
static ULONG WINAPI SmartTeeFilterInput_Release(IPin *iface)
static HRESULT WINAPI SmartTeeFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
#define VFW_E_SAMPLE_TIME_NOT_SET
Definition: vfwmsgs.h:104
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
BaseInputPin * input
WINE_DEFAULT_DEBUG_CHANNEL(qcap)
static const BaseInputPinFuncTable SmartTeeFilterInputFuncs
static const IPinVtbl SmartTeeFilterInputVtbl
Definition: send.c:48
HRESULT WINAPI BaseOutputPinImpl_QueryInterface(IPin *iface, REFIID riid, LPVOID *ppv)
Definition: pin.c:363
DWORD Id
Definition: regsvr.c:103
static void DeleteMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: filtergraph.c:741
static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
ULONG WINAPI BaseFilterImpl_Release(IBaseFilter *iface)
Definition: filter.c:64
static HRESULT WINAPI SmartTeeFilterCapture_BreakConnect(BaseOutputPin *base)
static ULONG WINAPI SmartTeeFilter_AddRef(IBaseFilter *iface)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter *iface, CLSID *pClsid)
Definition: filter.c:77
BaseOutputPin * capture
#define debugstr_w
Definition: kernel32.h:32
GLenum GLint ref
Definition: glext.h:6028
HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin *iface)
Definition: pin.c:545
#define FIXME(fmt,...)
Definition: debug.h:111
HRESULT WINAPI BasePinImpl_Disconnect(IPin *iface)
Definition: pin.c:197
#define S_FALSE
Definition: winerror.h:2357
HRESULT WINAPI BasePinImpl_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:311
static const IPinVtbl SmartTeeFilterCaptureVtbl
BaseOutputPin * preview
smooth NULL
Definition: ftsmooth.c:416
static SmartTeeFilter * impl_from_IPin(IPin *iface)
HRESULT WINAPI BasePinImpl_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
Definition: pin.c:285
#define VFW_E_NOT_FOUND
Definition: vfwmsgs.h:61
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin *iface, IPin **ppPin)
Definition: pin.c:222
HRESULT WINAPI BasePinImpl_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
Definition: pin.c:318
ULONG WINAPI BaseInputPinImpl_Release(IPin *iface)
Definition: pin.c:868
static HRESULT WINAPI SmartTeeFilterInput_CheckMediaType(BasePin *base, const AM_MEDIA_TYPE *pmt)
#define VFW_E_NOT_CONNECTED
Definition: vfwmsgs.h:48
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
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
void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *pmt)
Definition: enummedia.c:38
static HRESULT WINAPI SmartTeeFilterCapture_DecideAllocator(BaseOutputPin *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
static LONG WINAPI SmartTeeFilterInput_GetMediaTypeVersion(BasePin *base)
HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo)
Definition: filter.c:178
#define TRACE(s)
Definition: solgame.cpp:4
static const BaseOutputPinFuncTable SmartTeeFilterPreviewFuncs
HRESULT WINAPI BasePinImpl_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
Definition: pin.c:338
HRESULT WINAPI BaseInputPinImpl_BeginFlush(IPin *iface)
Definition: pin.c:968
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
static ULONG WINAPI SmartTeeFilterCapture_Release(IPin *iface)
HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin *iface)
Definition: pin.c:536
LONG HRESULT
Definition: typedefs.h:79
ULONG WINAPI BaseOutputPinImpl_Release(IPin *iface)
Definition: pin.c:392
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:6
static HRESULT WINAPI SmartTeeFilterPreview_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt)
static ULONG WINAPI SmartTeeFilter_Release(IBaseFilter *iface)
static HRESULT WINAPI SmartTeeFilter_Stop(IBaseFilter *iface)
static ULONG WINAPI Unknown_Release(IUnknown *iface)
static HRESULT CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
Definition: filtergraph.c:706
static HRESULT WINAPI SmartTeeFilterPreview_BreakConnect(BaseOutputPin *base)
HRESULT WINAPI BasePinImpl_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
Definition: pin.c:273
static LONG WINAPI SmartTeeFilter_GetPinCount(BaseFilter *iface)
static HRESULT WINAPI SmartTeeFilterCapture_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt)
int ret
static HRESULT WINAPI SmartTeeFilterInput_GetMediaType(BasePin *base, int iPosition, AM_MEDIA_TYPE *amt)
#define VFW_E_BUFFER_OVERFLOW
Definition: vfwmsgs.h:52
IUnknown IUnknown_iface
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
static const IUnknownVtbl UnknownVtbl
static HRESULT WINAPI SmartTeeFilterCapture_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
HRESULT WINAPI BasePinImpl_QueryId(IPin *iface, LPWSTR *Id)
Definition: pin.c:296
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HRESULT WINAPI BasePinImpl_QueryInternalConnections(IPin *iface, IPin **apPin, ULONG *cPin)
Definition: pin.c:329
HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
Definition: filter.c:135
uint32_t DWORD_PTR
Definition: typedefs.h:65
static const BaseOutputPinFuncTable SmartTeeFilterCaptureFuncs
static const BaseFilterFuncTable SmartTeeFilterFuncs
IUnknown *WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
unsigned char BYTE
Definition: xxhash.c:193
HRESULT WINAPI BaseOutputPinImpl_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:405
static LONG WINAPI SmartTeeFilterCapture_GetMediaTypeVersion(BasePin *base)
static ULONG WINAPI SmartTeeFilterPreview_AddRef(IPin *iface)
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
#define ERR(fmt,...)
Definition: debug.h:110
#define VFW_E_MEDIA_TIME_NOT_SET
Definition: vfwmsgs.h:105
HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:490
BaseFilter filter
#define S_OK
Definition: intsafe.h:51
static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
static ULONG WINAPI SmartTeeFilterPreview_Release(IPin *iface)
IUnknown * outerUnknown
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(BasePin *This, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:712
static HRESULT WINAPI SmartTeeFilterPreview_DecideAllocator(BaseOutputPin *base, IMemInputPin *pPin, IMemAllocator **pAlloc)
Definition: axcore.idl:91
static ULONG WINAPI SmartTeeFilterInput_AddRef(IPin *iface)
#define E_NOTIMPL
Definition: ddrawi.h:99
static SmartTeeFilter * impl_from_BasePin(BasePin *pin)
static SmartTeeFilter * impl_from_BaseFilter(BaseFilter *filter)
HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
Definition: filter.c:145
ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter *iface)
Definition: filter.c:54
HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
Definition: filter.c:119
PIN_INFO pinInfo
Definition: strmbase.h:38
HRESULT WINAPI BaseOutputPinImpl_Deliver(BaseOutputPin *This, IMediaSample *pSample)
Definition: pin.c:574
HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:889
HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, LPCWSTR pName)
Definition: filter.c:159
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
unsigned int ULONG
Definition: retypes.h:1
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define VFW_S_NO_STOP_TIME
Definition: vfwmsgs.h:34
HRESULT WINAPI BaseFilter_Init(BaseFilter *This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid, DWORD_PTR DebugInfo, const BaseFilterFuncTable *pBaseFuncsTable)
Definition: filter.c:196
static IPin *WINAPI SmartTeeFilter_GetPin(BaseFilter *iface, int pos)
static HRESULT WINAPI SmartTeeFilterPreview_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
static HRESULT WINAPI SmartTeeFilterInput_Receive(BaseInputPin *base, IMediaSample *inputSample)
HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
Definition: pin.c:1015
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
HRESULT WINAPI BasePinImpl_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
Definition: pin.c:248
#define memset(x, y, z)
Definition: compat.h:39
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin *iface)
Definition: pin.c:497
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define SUCCEEDED(hr)
Definition: intsafe.h:49
static HRESULT WINAPI SmartTeeFilter_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin)
HRESULT WINAPI BaseInputPinImpl_EndOfStream(IPin *iface)
Definition: pin.c:944