ReactOS  0.4.13-dev-1148-g9b75b67
pin.c
Go to the documentation of this file.
1 /*
2  * Generic Implementation of IPin Interface
3  *
4  * Copyright 2003 Robert Shearman
5  * Copyright 2010 Aric Stewart, CodeWeavers
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #define COBJMACROS
23 
24 #include "dshow.h"
25 #include "wine/debug.h"
26 #include "wine/unicode.h"
27 #include "wine/strmbase.h"
28 #include "uuids.h"
29 #include "vfwmsgs.h"
30 #include <assert.h>
31 
33 
34 static const IMemInputPinVtbl MemInputPin_Vtbl;
35 
36 typedef HRESULT (*SendPinFunc)( IPin *to, LPVOID arg );
37 
38 static inline BasePin *impl_from_IPin( IPin *iface )
39 {
40  return CONTAINING_RECORD(iface, BasePin, IPin_iface);
41 }
42 
49 static HRESULT updatehres( HRESULT original, HRESULT new )
50 {
51  if (FAILED( original ) || new == E_NOTIMPL)
52  return original;
53 
54  if (FAILED( new ) || original == S_OK)
55  return new;
56 
57  return original;
58 }
59 
68 {
69  PIN_INFO pin_info;
70  ULONG amount = 0;
71  HRESULT hr = S_OK;
72  HRESULT hr_return = S_OK;
73  IEnumPins *enumpins = NULL;
74  BOOL foundend = TRUE;
75  PIN_DIRECTION from_dir;
76 
77  IPin_QueryDirection( from, &from_dir );
78 
79  hr = IPin_QueryInternalConnections( from, NULL, &amount );
80  if (hr != E_NOTIMPL && amount)
81  FIXME("Use QueryInternalConnections!\n");
82 
83  pin_info.pFilter = NULL;
84  hr = IPin_QueryPinInfo( from, &pin_info );
85  if (FAILED(hr))
86  goto out;
87 
88  hr = IBaseFilter_EnumPins( pin_info.pFilter, &enumpins );
89  if (FAILED(hr))
90  goto out;
91 
92  hr = IEnumPins_Reset( enumpins );
93  while (hr == S_OK) {
94  IPin *pin = NULL;
95  hr = IEnumPins_Next( enumpins, 1, &pin, NULL );
97  {
98  hr = IEnumPins_Reset( enumpins );
99  continue;
100  }
101  if (pin)
102  {
104 
105  IPin_QueryDirection( pin, &dir );
106  if (dir != from_dir)
107  {
108  IPin *connected = NULL;
109 
110  foundend = FALSE;
111  IPin_ConnectedTo( pin, &connected );
112  if (connected)
113  {
114  HRESULT hr_local;
115 
116  hr_local = fnMiddle( connected, arg );
117  hr_return = updatehres( hr_return, hr_local );
118  IPin_Release(connected);
119  }
120  }
121  IPin_Release( pin );
122  }
123  else
124  {
125  hr = S_OK;
126  break;
127  }
128  }
129 
130  if (!foundend)
131  hr = hr_return;
132  else if (fnEnd) {
133  HRESULT hr_local;
134 
135  hr_local = fnEnd( from, arg );
136  hr_return = updatehres( hr_return, hr_local );
137  }
138  IEnumPins_Release(enumpins);
139 
140 out:
141  if (pin_info.pFilter)
142  IBaseFilter_Release( pin_info.pFilter );
143  return hr;
144 }
145 
146 static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc)
147 {
148  /* Tempting to just do a memcpy, but the name field is
149  128 characters long! We will probably never exceed 10
150  most of the time, so we are better off copying
151  each field manually */
152  strcpyW(pDest->achName, pSrc->achName);
153  pDest->dir = pSrc->dir;
154  pDest->pFilter = pSrc->pFilter;
155 }
156 
157 static void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt)
158 {
159  if (!pmt)
160  return;
161  TRACE("\t%s\n\t%s\n\t...\n\t%s\n", debugstr_guid(&pmt->majortype), debugstr_guid(&pmt->subtype), debugstr_guid(&pmt->formattype));
162 }
163 
164 static BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards)
165 {
166  TRACE("pmt1: ");
167  dump_AM_MEDIA_TYPE(pmt1);
168  TRACE("pmt2: ");
169  dump_AM_MEDIA_TYPE(pmt2);
170  return (((bWildcards && (IsEqualGUID(&pmt1->majortype, &GUID_NULL) || IsEqualGUID(&pmt2->majortype, &GUID_NULL))) || IsEqualGUID(&pmt1->majortype, &pmt2->majortype)) &&
171  ((bWildcards && (IsEqualGUID(&pmt1->subtype, &GUID_NULL) || IsEqualGUID(&pmt2->subtype, &GUID_NULL))) || IsEqualGUID(&pmt1->subtype, &pmt2->subtype)));
172 }
173 
174 /*** Common Base Pin function */
176 {
177  if (iPosition < 0)
178  return E_INVALIDARG;
179  return VFW_S_NO_MORE_ITEMS;
180 }
181 
183 {
184  return 1;
185 }
186 
188 {
189  BasePin *This = impl_from_IPin(iface);
190  ULONG refCount = InterlockedIncrement(&This->refCount);
191 
192  TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
193 
194  return refCount;
195 }
196 
198 {
199  HRESULT hr;
200  BasePin *This = impl_from_IPin(iface);
201 
202  TRACE("()\n");
203 
204  EnterCriticalSection(This->pCritSec);
205  {
206  if (This->pConnectedTo)
207  {
208  IPin_Release(This->pConnectedTo);
209  This->pConnectedTo = NULL;
210  FreeMediaType(&This->mtCurrent);
211  ZeroMemory(&This->mtCurrent, sizeof(This->mtCurrent));
212  hr = S_OK;
213  }
214  else
215  hr = S_FALSE;
216  }
217  LeaveCriticalSection(This->pCritSec);
218 
219  return hr;
220 }
221 
223 {
224  HRESULT hr;
225  BasePin *This = impl_from_IPin(iface);
226 
227  TRACE("(%p)\n", ppPin);
228 
229  EnterCriticalSection(This->pCritSec);
230  {
231  if (This->pConnectedTo)
232  {
233  *ppPin = This->pConnectedTo;
234  IPin_AddRef(*ppPin);
235  hr = S_OK;
236  }
237  else
238  {
240  *ppPin = NULL;
241  }
242  }
243  LeaveCriticalSection(This->pCritSec);
244 
245  return hr;
246 }
247 
249 {
250  HRESULT hr;
251  BasePin *This = impl_from_IPin(iface);
252 
253  TRACE("(%p/%p)->(%p)\n", This, iface, pmt);
254 
255  EnterCriticalSection(This->pCritSec);
256  {
257  if (This->pConnectedTo)
258  {
259  CopyMediaType(pmt, &This->mtCurrent);
260  hr = S_OK;
261  }
262  else
263  {
264  ZeroMemory(pmt, sizeof(*pmt));
266  }
267  }
268  LeaveCriticalSection(This->pCritSec);
269 
270  return hr;
271 }
272 
274 {
275  BasePin *This = impl_from_IPin(iface);
276 
277  TRACE("(%p/%p)->(%p)\n", This, iface, pInfo);
278 
279  Copy_PinInfo(pInfo, &This->pinInfo);
280  IBaseFilter_AddRef(pInfo->pFilter);
281 
282  return S_OK;
283 }
284 
286 {
287  BasePin *This = impl_from_IPin(iface);
288 
289  TRACE("(%p/%p)->(%p)\n", This, iface, pPinDir);
290 
291  *pPinDir = This->pinInfo.dir;
292 
293  return S_OK;
294 }
295 
297 {
298  BasePin *This = impl_from_IPin(iface);
299 
300  TRACE("(%p/%p)->(%p)\n", This, iface, Id);
301 
302  *Id = CoTaskMemAlloc((strlenW(This->pinInfo.achName) + 1) * sizeof(WCHAR));
303  if (!*Id)
304  return E_OUTOFMEMORY;
305 
306  strcpyW(*Id, This->pinInfo.achName);
307 
308  return S_OK;
309 }
310 
312 {
313  TRACE("(%p)->(%p)\n", iface, pmt);
314 
315  return S_OK;
316 }
317 
319 {
320  BasePin *This = impl_from_IPin(iface);
321 
322  TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
323 
324  /* override this method to allow enumeration of your types */
325 
326  return EnumMediaTypes_Construct(This, This->pFuncsTable->pfnGetMediaType, This->pFuncsTable->pfnGetMediaTypeVersion , ppEnum);
327 }
328 
330 {
331  BasePin *This = impl_from_IPin(iface);
332 
333  TRACE("(%p/%p)->(%p, %p)\n", This, iface, apPin, cPin);
334 
335  return E_NOTIMPL; /* to tell caller that all input pins connected to all output pins */
336 }
337 
339 {
340  BasePin *This = impl_from_IPin(iface);
341 
342  TRACE("(%s, %s, %e)\n", wine_dbgstr_longlong(tStart), wine_dbgstr_longlong(tStop), dRate);
343 
344  This->tStart = tStart;
345  This->tStop = tStop;
346  This->dRate = dRate;
347 
348  return S_OK;
349 }
350 
351 /*** OutputPin implementation ***/
352 
354 {
355  return CONTAINING_RECORD(iface, BaseOutputPin, pin.IPin_iface);
356 }
357 
359 {
360  return CONTAINING_RECORD(iface, BaseOutputPin, pin);
361 }
362 
364 {
366 
367  TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppv);
368 
369  *ppv = NULL;
370 
372  *ppv = iface;
373  else if (IsEqualIID(riid, &IID_IPin))
374  *ppv = iface;
375  else if (IsEqualIID(riid, &IID_IMediaSeeking) ||
376  IsEqualIID(riid, &IID_IQualityControl))
377  {
378  return IBaseFilter_QueryInterface(This->pin.pinInfo.pFilter, riid, ppv);
379  }
380 
381  if (*ppv)
382  {
383  IUnknown_AddRef((IUnknown *)(*ppv));
384  return S_OK;
385  }
386 
387  FIXME("No interface for %s!\n", debugstr_guid(riid));
388 
389  return E_NOINTERFACE;
390 }
391 
393 {
395  ULONG refCount = InterlockedDecrement(&This->pin.refCount);
396 
397  TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
398 
399  if (!refCount)
401 
402  return refCount;
403 }
404 
405 HRESULT WINAPI BaseOutputPinImpl_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
406 {
407  HRESULT hr;
409 
410  TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt);
411  dump_AM_MEDIA_TYPE(pmt);
412 
413  if (!pReceivePin)
414  return E_POINTER;
415 
416  /* If we try to connect to ourselves, we will definitely deadlock.
417  * There are other cases where we could deadlock too, but this
418  * catches the obvious case */
419  assert(pReceivePin != iface);
420 
421  EnterCriticalSection(This->pin.pCritSec);
422  {
423  /* if we have been a specific type to connect with, then we can either connect
424  * with that or fail. We cannot choose different AM_MEDIA_TYPE */
425  if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL))
426  hr = This->pin.pFuncsTable->pfnAttemptConnection(&This->pin, pReceivePin, pmt);
427  else
428  {
429  /* negotiate media type */
430 
431  IEnumMediaTypes * pEnumCandidates;
432  AM_MEDIA_TYPE * pmtCandidate = NULL; /* Candidate media type */
433 
434  if (SUCCEEDED(hr = IPin_EnumMediaTypes(iface, &pEnumCandidates)))
435  {
436  hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */
437 
438  /* try this filter's media types first */
439  while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL))
440  {
441  assert(pmtCandidate);
442  dump_AM_MEDIA_TYPE(pmtCandidate);
443  if (!IsEqualGUID(&FORMAT_None, &pmtCandidate->formattype)
444  && !IsEqualGUID(&GUID_NULL, &pmtCandidate->formattype))
445  assert(pmtCandidate->pbFormat);
446  if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) &&
447  (This->pin.pFuncsTable->pfnAttemptConnection(&This->pin, pReceivePin, pmtCandidate) == S_OK))
448  {
449  hr = S_OK;
450  DeleteMediaType(pmtCandidate);
451  break;
452  }
453  DeleteMediaType(pmtCandidate);
454  pmtCandidate = NULL;
455  }
456  IEnumMediaTypes_Release(pEnumCandidates);
457  }
458 
459  /* then try receiver filter's media types */
460  if (hr != S_OK && SUCCEEDED(hr = IPin_EnumMediaTypes(pReceivePin, &pEnumCandidates))) /* if we haven't already connected successfully */
461  {
462  ULONG fetched;
463 
464  hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */
465 
466  while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, &fetched))
467  {
468  assert(pmtCandidate);
469  dump_AM_MEDIA_TYPE(pmtCandidate);
470  if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) &&
471  (This->pin.pFuncsTable->pfnAttemptConnection(&This->pin, pReceivePin, pmtCandidate) == S_OK))
472  {
473  hr = S_OK;
474  DeleteMediaType(pmtCandidate);
475  break;
476  }
477  DeleteMediaType(pmtCandidate);
478  pmtCandidate = NULL;
479  } /* while */
480  IEnumMediaTypes_Release(pEnumCandidates);
481  } /* if not found */
482  } /* if negotiate media type */
483  } /* if succeeded */
484  LeaveCriticalSection(This->pin.pCritSec);
485 
486  TRACE(" -- %x\n", hr);
487  return hr;
488 }
489 
491 {
492  ERR("Incoming connection on an output pin! (%p, %p)\n", pReceivePin, pmt);
493 
494  return E_UNEXPECTED;
495 }
496 
498 {
499  HRESULT hr;
501 
502  TRACE("()\n");
503 
504  EnterCriticalSection(This->pin.pCritSec);
505  {
506  if (This->pMemInputPin)
507  {
508  IMemInputPin_Release(This->pMemInputPin);
509  This->pMemInputPin = NULL;
510  }
511  if (This->pin.pConnectedTo)
512  {
513  IPin_Release(This->pin.pConnectedTo);
514  This->pin.pConnectedTo = NULL;
515  FreeMediaType(&This->pin.mtCurrent);
516  ZeroMemory(&This->pin.mtCurrent, sizeof(This->pin.mtCurrent));
517  hr = S_OK;
518  }
519  else
520  hr = S_FALSE;
521  }
522  LeaveCriticalSection(This->pin.pCritSec);
523 
524  return hr;
525 }
526 
528 {
529  TRACE("()\n");
530 
531  /* not supposed to do anything in an output pin */
532 
533  return E_UNEXPECTED;
534 }
535 
537 {
538  TRACE("(%p)->()\n", iface);
539 
540  /* not supposed to do anything in an output pin */
541 
542  return E_UNEXPECTED;
543 }
544 
546 {
547  TRACE("(%p)->()\n", iface);
548 
549  /* not supposed to do anything in an output pin */
550 
551  return E_UNEXPECTED;
552 }
553 
555 {
556  HRESULT hr;
557 
558  TRACE("(%p, %p, %p, %x)\n", ppSample, tStart, tStop, dwFlags);
559 
560  if (!This->pin.pConnectedTo)
562  else
563  {
564  hr = IMemAllocator_GetBuffer(This->pAllocator, ppSample, tStart, tStop, dwFlags);
565 
566  if (SUCCEEDED(hr))
567  hr = IMediaSample_SetTime(*ppSample, tStart, tStop);
568  }
569 
570  return hr;
571 }
572 
573 /* replaces OutputPin_SendSample */
575 {
576  IMemInputPin * pMemConnected = NULL;
577  PIN_INFO pinInfo;
578  HRESULT hr;
579 
580  EnterCriticalSection(This->pin.pCritSec);
581  {
582  if (!This->pin.pConnectedTo || !This->pMemInputPin)
584  else
585  {
586  /* we don't have the lock held when using This->pMemInputPin,
587  * so we need to AddRef it to stop it being deleted while we are
588  * using it. Same with its filter. */
589  pMemConnected = This->pMemInputPin;
590  IMemInputPin_AddRef(pMemConnected);
591  hr = IPin_QueryPinInfo(This->pin.pConnectedTo, &pinInfo);
592  }
593  }
594  LeaveCriticalSection(This->pin.pCritSec);
595 
596  if (SUCCEEDED(hr))
597  {
598  /* NOTE: if we are in a critical section when Receive is called
599  * then it causes some problems (most notably with the native Video
600  * Renderer) if we are re-entered for whatever reason */
601  hr = IMemInputPin_Receive(pMemConnected, pSample);
602 
603  /* If the filter's destroyed, tell upstream to stop sending data */
604  if(IBaseFilter_Release(pinInfo.pFilter) == 0 && SUCCEEDED(hr))
605  hr = S_FALSE;
606  }
607  if (pMemConnected)
608  IMemInputPin_Release(pMemConnected);
609 
610  return hr;
611 }
612 
613 /* replaces OutputPin_CommitAllocator */
615 {
616  HRESULT hr;
617 
618  TRACE("(%p)->()\n", This);
619 
620  EnterCriticalSection(This->pin.pCritSec);
621  {
622  if (!This->pin.pConnectedTo || !This->pMemInputPin)
624  else
625  hr = IMemAllocator_Commit(This->pAllocator);
626  }
627  LeaveCriticalSection(This->pin.pCritSec);
628 
629  TRACE("--> %08x\n", hr);
630  return hr;
631 }
632 
633 /* replaces OutputPin_DecommitAllocator */
635 {
636  HRESULT hr;
637 
638  TRACE("(%p)->()\n", This);
639 
640  EnterCriticalSection(This->pin.pCritSec);
641  {
642  if (!This->pin.pConnectedTo || !This->pMemInputPin)
644  else
645  hr = IMemAllocator_Decommit(This->pAllocator);
646  }
647  LeaveCriticalSection(This->pin.pCritSec);
648 
649  TRACE("--> %08x\n", hr);
650  return hr;
651 }
652 
653 /* replaces OutputPin_DeliverDisconnect */
655 {
656  HRESULT hr;
657 
658  TRACE("(%p)->()\n", This);
659 
660  EnterCriticalSection(This->pin.pCritSec);
661  {
662  if (!This->pin.pConnectedTo || !This->pMemInputPin)
664  else
665  {
666  hr = IMemAllocator_Decommit(This->pAllocator);
667 
668  if (SUCCEEDED(hr))
669  hr = IPin_Disconnect(This->pin.pConnectedTo);
670  }
671  IPin_Disconnect(&This->pin.IPin_iface);
672  }
673  LeaveCriticalSection(This->pin.pCritSec);
674 
675  return hr;
676 }
677 
679 {
680  return CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)pMemAlloc);
681 }
682 
684 {
685  HRESULT hr;
686 
687  hr = IMemInputPin_GetAllocator(pPin, pAlloc);
688 
689  if (hr == VFW_E_NO_ALLOCATOR)
690  /* Input pin provides no allocator, use standard memory allocator */
692 
693  if (SUCCEEDED(hr))
694  {
695  ALLOCATOR_PROPERTIES rProps;
696  ZeroMemory(&rProps, sizeof(ALLOCATOR_PROPERTIES));
697 
698  IMemInputPin_GetAllocatorRequirements(pPin, &rProps);
699  hr = This->pFuncsTable->pfnDecideBufferSize(This, *pAlloc, &rProps);
700  }
701 
702  if (SUCCEEDED(hr))
703  hr = IMemInputPin_NotifyAllocator(pPin, *pAlloc, FALSE);
704 
705  return hr;
706 }
707 
708 /*** The Construct functions ***/
709 
710 /* Function called as a helper to IPin_Connect */
711 /* specific AM_MEDIA_TYPE - it cannot be NULL */
713 {
715  HRESULT hr;
716  IMemAllocator * pMemAlloc = NULL;
717 
718  TRACE("(%p, %p)\n", pReceivePin, pmt);
719  dump_AM_MEDIA_TYPE(pmt);
720 
721  /* FIXME: call queryacceptproc */
722 
723  This->pin.pConnectedTo = pReceivePin;
724  IPin_AddRef(pReceivePin);
725  CopyMediaType(&This->pin.mtCurrent, pmt);
726 
727  hr = IPin_ReceiveConnection(pReceivePin, &iface->IPin_iface, pmt);
728 
729  /* get the IMemInputPin interface we will use to deliver samples to the
730  * connected pin */
731  if (SUCCEEDED(hr))
732  {
733  This->pMemInputPin = NULL;
734  hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (LPVOID)&This->pMemInputPin);
735 
736  if (SUCCEEDED(hr))
737  {
738  hr = This->pFuncsTable->pfnDecideAllocator(This, This->pMemInputPin, &pMemAlloc);
739  if (SUCCEEDED(hr))
740  This->pAllocator = pMemAlloc;
741  else if (pMemAlloc)
742  IMemAllocator_Release(pMemAlloc);
743  }
744 
745  /* break connection if we couldn't get the allocator */
746  if (FAILED(hr))
747  {
748  if (This->pMemInputPin)
749  IMemInputPin_Release(This->pMemInputPin);
750  This->pMemInputPin = NULL;
751 
752  IPin_Disconnect(pReceivePin);
753  }
754  }
755 
756  if (FAILED(hr))
757  {
758  IPin_Release(This->pin.pConnectedTo);
759  This->pin.pConnectedTo = NULL;
760  FreeMediaType(&This->pin.mtCurrent);
761  }
762 
763  TRACE(" -- %x\n", hr);
764  return hr;
765 }
766 
767 static HRESULT OutputPin_Init(const IPinVtbl *OutputPin_Vtbl, const PIN_INFO * pPinInfo, const BaseOutputPinFuncTable* vtbl, LPCRITICAL_SECTION pCritSec, BaseOutputPin * pPinImpl)
768 {
769  TRACE("\n");
770 
771  /* Common attributes */
772  pPinImpl->pin.IPin_iface.lpVtbl = OutputPin_Vtbl;
773  pPinImpl->pin.refCount = 1;
774  pPinImpl->pin.pConnectedTo = NULL;
775  pPinImpl->pin.pCritSec = pCritSec;
776  pPinImpl->pin.tStart = 0;
777  pPinImpl->pin.tStop = 0;
778  pPinImpl->pin.dRate = 1.0;
779  Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo);
780  pPinImpl->pin.pFuncsTable = &vtbl->base;
781  ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE));
782 
783  /* Output pin attributes */
784  pPinImpl->pMemInputPin = NULL;
785  pPinImpl->pAllocator = NULL;
786  pPinImpl->pFuncsTable = vtbl;
787 
788  return S_OK;
789 }
790 
791 HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, const BaseOutputPinFuncTable* vtbl, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
792 {
793  BaseOutputPin * pPinImpl;
794 
795  *ppPin = NULL;
796 
797  if (pPinInfo->dir != PINDIR_OUTPUT)
798  {
799  ERR("Pin direction(%x) != PINDIR_OUTPUT\n", pPinInfo->dir);
800  return E_INVALIDARG;
801  }
802 
803  assert(outputpin_size >= sizeof(BaseOutputPin));
805 
806  pPinImpl = CoTaskMemAlloc(outputpin_size);
807 
808  if (!pPinImpl)
809  return E_OUTOFMEMORY;
810 
811  if (SUCCEEDED(OutputPin_Init(OutputPin_Vtbl, pPinInfo, vtbl, pCritSec, pPinImpl)))
812  {
813  *ppPin = &pPinImpl->pin.IPin_iface;
814  return S_OK;
815  }
816 
817  CoTaskMemFree(pPinImpl);
818  return E_FAIL;
819 }
820 
822 {
823  FreeMediaType(&This->pin.mtCurrent);
824  if (This->pAllocator)
825  IMemAllocator_Release(This->pAllocator);
826  This->pAllocator = NULL;
828  return S_OK;
829 }
830 
831 /*** Input Pin implementation ***/
832 
834 {
835  return CONTAINING_RECORD(iface, BaseInputPin, pin.IPin_iface);
836 }
837 
839 {
841 
842  TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
843 
844  *ppv = NULL;
845 
847  *ppv = iface;
848  else if (IsEqualIID(riid, &IID_IPin))
849  *ppv = iface;
850  else if (IsEqualIID(riid, &IID_IMemInputPin))
851  *ppv = &This->IMemInputPin_iface;
852  else if (IsEqualIID(riid, &IID_IMediaSeeking))
853  {
854  return IBaseFilter_QueryInterface(This->pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv);
855  }
856 
857  if (*ppv)
858  {
859  IUnknown_AddRef((IUnknown *)(*ppv));
860  return S_OK;
861  }
862 
863  FIXME("No interface for %s!\n", debugstr_guid(riid));
864 
865  return E_NOINTERFACE;
866 }
867 
869 {
871  ULONG refCount = InterlockedDecrement(&This->pin.refCount);
872 
873  TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
874 
875  if (!refCount)
877 
878  return refCount;
879 }
880 
881 HRESULT WINAPI BaseInputPinImpl_Connect(IPin * iface, IPin * pConnector, const AM_MEDIA_TYPE * pmt)
882 {
883  ERR("Outgoing connection on an input pin! (%p, %p)\n", pConnector, pmt);
884 
885  return E_UNEXPECTED;
886 }
887 
888 
890 {
892  PIN_DIRECTION pindirReceive;
893  HRESULT hr = S_OK;
894 
895  TRACE("(%p, %p)\n", pReceivePin, pmt);
896  dump_AM_MEDIA_TYPE(pmt);
897 
898  EnterCriticalSection(This->pin.pCritSec);
899  {
900  if (This->pin.pConnectedTo)
902 
903  if (SUCCEEDED(hr) && This->pin.pFuncsTable->pfnCheckMediaType(&This->pin, pmt) != S_OK)
904  hr = VFW_E_TYPE_NOT_ACCEPTED; /* FIXME: shouldn't we just map common errors onto
905  * VFW_E_TYPE_NOT_ACCEPTED and pass the value on otherwise? */
906 
907  if (SUCCEEDED(hr))
908  {
909  IPin_QueryDirection(pReceivePin, &pindirReceive);
910 
911  if (pindirReceive != PINDIR_OUTPUT)
912  {
913  ERR("Can't connect from non-output pin\n");
915  }
916  }
917 
918  if (SUCCEEDED(hr))
919  {
920  CopyMediaType(&This->pin.mtCurrent, pmt);
921  This->pin.pConnectedTo = pReceivePin;
922  IPin_AddRef(pReceivePin);
923  }
924  }
925  LeaveCriticalSection(This->pin.pCritSec);
926 
927  return hr;
928 }
929 
931 {
932  return IPin_EndOfStream( pin );
933 }
934 
936 {
938 
939  TRACE("(%p/%p)->(%p)\n", This, iface, pmt);
940 
941  return (This->pin.pFuncsTable->pfnCheckMediaType(&This->pin, pmt) == S_OK ? S_OK : S_FALSE);
942 }
943 
945 {
946  HRESULT hr = S_OK;
948 
949  TRACE("(%p)\n", This);
950 
951  EnterCriticalSection(This->pin.pCritSec);
952  if (This->flushing)
953  hr = S_FALSE;
954  else
955  This->end_of_stream = TRUE;
956  LeaveCriticalSection(This->pin.pCritSec);
957 
958  if (hr == S_OK)
960  return hr;
961 }
962 
964 {
965  return IPin_BeginFlush( pin );
966 }
967 
969 {
971  HRESULT hr;
972  TRACE("() semi-stub\n");
973 
974  EnterCriticalSection(This->pin.pCritSec);
975  This->flushing = TRUE;
976 
977  hr = SendFurther( iface, deliver_beginflush, NULL, NULL );
978  LeaveCriticalSection(This->pin.pCritSec);
979 
980  return hr;
981 }
982 
984 {
985  return IPin_EndFlush( pin );
986 }
987 
989 {
991  HRESULT hr;
992  TRACE("(%p)\n", This);
993 
994  EnterCriticalSection(This->pin.pCritSec);
995  This->flushing = This->end_of_stream = FALSE;
996 
997  hr = SendFurther( iface, deliver_endflush, NULL, NULL );
998  LeaveCriticalSection(This->pin.pCritSec);
999 
1000  return hr;
1001 }
1002 
1003 typedef struct newsegmentargs
1004 {
1006  double rate;
1007 } newsegmentargs;
1008 
1010 {
1012  return IPin_NewSegment(pin, args->tStart, args->tStop, args->rate);
1013 }
1014 
1016 {
1019 
1020  TRACE("(%s, %s, %e)\n", wine_dbgstr_longlong(tStart), wine_dbgstr_longlong(tStop), dRate);
1021 
1022  args.tStart = This->pin.tStart = tStart;
1023  args.tStop = This->pin.tStop = tStop;
1024  args.rate = This->pin.dRate = dRate;
1025 
1026  return SendFurther( iface, deliver_newsegment, &args, NULL );
1027 }
1028 
1029 /*** IMemInputPin implementation ***/
1030 
1032 {
1033  return CONTAINING_RECORD(iface, BaseInputPin, IMemInputPin_iface);
1034 }
1035 
1037 {
1039 
1040  return IPin_QueryInterface(&This->pin.IPin_iface, riid, ppv);
1041 }
1042 
1044 {
1046 
1047  return IPin_AddRef(&This->pin.IPin_iface);
1048 }
1049 
1051 {
1053 
1054  return IPin_Release(&This->pin.IPin_iface);
1055 }
1056 
1058 {
1060 
1061  TRACE("(%p/%p)->(%p)\n", This, iface, ppAllocator);
1062 
1063  *ppAllocator = This->pAllocator;
1064  if (*ppAllocator)
1065  IMemAllocator_AddRef(*ppAllocator);
1066 
1067  return *ppAllocator ? S_OK : VFW_E_NO_ALLOCATOR;
1068 }
1069 
1071 {
1073 
1074  TRACE("(%p/%p)->(%p, %d)\n", This, iface, pAllocator, bReadOnly);
1075 
1076  if (bReadOnly)
1077  FIXME("Read only flag not handled yet!\n");
1078 
1079  /* FIXME: Should we release the allocator on disconnection? */
1080  if (!pAllocator)
1081  {
1082  WARN("Null allocator\n");
1083  return E_POINTER;
1084  }
1085 
1086  if (This->preferred_allocator && pAllocator != This->preferred_allocator)
1087  return E_FAIL;
1088 
1089  if (This->pAllocator)
1090  IMemAllocator_Release(This->pAllocator);
1091  This->pAllocator = pAllocator;
1092  if (This->pAllocator)
1093  IMemAllocator_AddRef(This->pAllocator);
1094 
1095  return S_OK;
1096 }
1097 
1099 {
1101 
1102  TRACE("(%p/%p)->(%p)\n", This, iface, pProps);
1103 
1104  /* override this method if you have any specific requirements */
1105 
1106  return E_NOTIMPL;
1107 }
1108 
1110 {
1112  HRESULT hr = S_FALSE;
1113 
1114  /* this trace commented out for performance reasons */
1115  /*TRACE("(%p/%p)->(%p)\n", This, iface, pSample);*/
1116  if (This->pFuncsTable->pfnReceive)
1117  hr = This->pFuncsTable->pfnReceive(This, pSample);
1118  return hr;
1119 }
1120 
1121 static HRESULT WINAPI MemInputPin_ReceiveMultiple(IMemInputPin * iface, IMediaSample ** pSamples, LONG nSamples, LONG *nSamplesProcessed)
1122 {
1123  HRESULT hr = S_OK;
1125 
1126  TRACE("(%p/%p)->(%p, %d, %p)\n", This, iface, pSamples, nSamples, nSamplesProcessed);
1127 
1128  for (*nSamplesProcessed = 0; *nSamplesProcessed < nSamples; (*nSamplesProcessed)++)
1129  {
1130  hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]);
1131  if (hr != S_OK)
1132  break;
1133  }
1134 
1135  return hr;
1136 }
1137 
1139 {
1141 
1142  TRACE("(%p/%p)->()\n", This, iface);
1143 
1144  return S_OK;
1145 }
1146 
1147 static const IMemInputPinVtbl MemInputPin_Vtbl =
1148 {
1158 };
1159 
1160 static HRESULT InputPin_Init(const IPinVtbl *InputPin_Vtbl, const PIN_INFO * pPinInfo,
1161  const BaseInputPinFuncTable* vtbl,
1162  LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, BaseInputPin * pPinImpl)
1163 {
1164  TRACE("\n");
1165 
1166  /* Common attributes */
1167  pPinImpl->pin.refCount = 1;
1168  pPinImpl->pin.pConnectedTo = NULL;
1169  pPinImpl->pin.pCritSec = pCritSec;
1170  pPinImpl->pin.tStart = 0;
1171  pPinImpl->pin.tStop = 0;
1172  pPinImpl->pin.dRate = 1.0;
1173  Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo);
1174  ZeroMemory(&pPinImpl->pin.mtCurrent, sizeof(AM_MEDIA_TYPE));
1175  pPinImpl->pin.pFuncsTable = &vtbl->base;
1176 
1177  /* Input pin attributes */
1178  pPinImpl->pFuncsTable = vtbl;
1179  pPinImpl->pAllocator = pPinImpl->preferred_allocator = allocator;
1180  if (pPinImpl->preferred_allocator)
1181  IMemAllocator_AddRef(pPinImpl->preferred_allocator);
1182  pPinImpl->pin.IPin_iface.lpVtbl = InputPin_Vtbl;
1183  pPinImpl->IMemInputPin_iface.lpVtbl = &MemInputPin_Vtbl;
1184  pPinImpl->flushing = pPinImpl->end_of_stream = FALSE;
1185 
1186  return S_OK;
1187 }
1188 
1189 HRESULT BaseInputPin_Construct(const IPinVtbl *InputPin_Vtbl, LONG inputpin_size, const PIN_INFO * pPinInfo,
1190  const BaseInputPinFuncTable* vtbl,
1191  LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, IPin ** ppPin)
1192 {
1193  BaseInputPin * pPinImpl;
1194 
1195  *ppPin = NULL;
1196 
1197  assert(inputpin_size >= sizeof(BaseInputPin));
1198  assert(vtbl->base.pfnCheckMediaType);
1199 
1200  if (pPinInfo->dir != PINDIR_INPUT)
1201  {
1202  ERR("Pin direction(%x) != PINDIR_INPUT\n", pPinInfo->dir);
1203  return E_INVALIDARG;
1204  }
1205 
1206  pPinImpl = CoTaskMemAlloc(inputpin_size);
1207 
1208  if (!pPinImpl)
1209  return E_OUTOFMEMORY;
1210 
1211  if (SUCCEEDED(InputPin_Init(InputPin_Vtbl, pPinInfo, vtbl, pCritSec, allocator, pPinImpl)))
1212  {
1213  *ppPin = &pPinImpl->pin.IPin_iface;
1214  return S_OK;
1215  }
1216 
1217  CoTaskMemFree(pPinImpl);
1218  return E_FAIL;
1219 }
1220 
1222 {
1223  FreeMediaType(&This->pin.mtCurrent);
1224  if (This->pAllocator)
1225  IMemAllocator_Release(This->pAllocator);
1226  This->pAllocator = NULL;
1227  This->pin.IPin_iface.lpVtbl = NULL;
1229  return S_OK;
1230 }
static HRESULT OutputPin_Init(const IPinVtbl *OutputPin_Vtbl, const PIN_INFO *pPinInfo, const BaseOutputPinFuncTable *vtbl, LPCRITICAL_SECTION pCritSec, BaseOutputPin *pPinImpl)
Definition: pin.c:767
static void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *pmt)
Definition: pin.c:157
#define VFW_S_NO_MORE_ITEMS
Definition: vfwmsgs.h:19
static HRESULT WINAPI MemInputPin_Receive(IMemInputPin *iface, IMediaSample *pSample)
Definition: pin.c:1109
static HRESULT WINAPI MemInputPin_ReceiveMultiple(IMemInputPin *iface, IMediaSample **pSamples, LONG nSamples, LONG *nSamplesProcessed)
Definition: pin.c:1121
#define HRESULT
Definition: msvc.h:9
const struct BaseInputPinFuncTable * pFuncsTable
Definition: strmbase.h:97
IMemInputPin IMemInputPin_iface
Definition: strmbase.h:92
static HRESULT WINAPI MemInputPin_QueryInterface(IMemInputPin *iface, REFIID riid, LPVOID *ppv)
Definition: pin.c:1036
HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:490
HRESULT WINAPI BaseInputPinImpl_BeginFlush(IPin *iface)
Definition: pin.c:968
struct newsegmentargs newsegmentargs
#define REFIID
Definition: guiddef.h:118
#define TRUE
Definition: types.h:120
static HRESULT InputPin_Init(const IPinVtbl *InputPin_Vtbl, const PIN_INFO *pPinInfo, const BaseInputPinFuncTable *vtbl, LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, BaseInputPin *pPinImpl)
Definition: pin.c:1160
#define E_NOINTERFACE
Definition: winerror.h:2364
REFERENCE_TIME tStop
Definition: pin.c:170
LONG refCount
Definition: strmbase.h:36
LPCRITICAL_SECTION pCritSec
Definition: strmbase.h:37
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:422
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
HRESULT hr
Definition: shlfolder.c:183
ULONG WINAPI BaseInputPinImpl_Release(IPin *iface)
Definition: pin.c:868
BasePinFuncTable base
Definition: strmbase.h:103
REFIID riid
Definition: precomp.h:44
IPin IPin_iface
Definition: strmbase.h:35
HRESULT WINAPI BaseOutputPinImpl_GetDeliveryBuffer(BaseOutputPin *This, IMediaSample **ppSample, REFERENCE_TIME *tStart, REFERENCE_TIME *tStop, DWORD dwFlags)
Definition: pin.c:554
HRESULT WINAPI BasePinImpl_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
Definition: pin.c:248
HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
Definition: pin.c:1015
const struct BaseOutputPinFuncTable * pFuncsTable
Definition: strmbase.h:70
static ULONG WINAPI MemInputPin_Release(IMemInputPin *iface)
Definition: pin.c:1050
#define WARN(fmt,...)
Definition: debug.h:111
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define assert(x)
Definition: debug.h:53
HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:889
#define ZeroMemory
Definition: winbase.h:1635
double rate
Definition: pin.c:171
static HRESULT updatehres(HRESULT original, HRESULT new)
Definition: pin.c:49
BasePin pin
Definition: strmbase.h:90
void * arg
Definition: msvc.h:12
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static HRESULT WINAPI MemInputPin_ReceiveCanBlock(IMemInputPin *iface)
Definition: pin.c:1138
#define E_FAIL
Definition: ddrawi.h:102
BasePin_AttemptConnection pfnAttemptConnection
Definition: strmbase.h:57
Definition: match.c:390
static ULONG WINAPI MemInputPin_AddRef(IMemInputPin *iface)
Definition: pin.c:1043
HRESULT WINAPI BaseOutputPinImpl_QueryInterface(IPin *iface, REFIID riid, LPVOID *ppv)
Definition: pin.c:363
HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin *iface)
Definition: pin.c:545
HRESULT WINAPI BaseInputPin_Destroy(BaseInputPin *This)
Definition: pin.c:1221
DWORD Id
#define VFW_E_ALREADY_CONNECTED
Definition: vfwmsgs.h:43
Definition: regsvr.c:103
HRESULT WINAPI BaseInputPinImpl_QueryInterface(IPin *iface, REFIID riid, LPVOID *ppv)
Definition: pin.c:838
static void DeleteMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: filtergraph.c:741
WORD unused[29]
Definition: crypt.c:1155
HRESULT(* SendPinFunc)(IPin *to, LPVOID arg)
Definition: pin.c:35
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
static BaseOutputPin * impl_BaseOutputPin_from_IPin(IPin *iface)
Definition: pin.c:353
BasePin_CheckMediaType pfnCheckMediaType
Definition: strmbase.h:55
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static void FreeMediaType(AM_MEDIA_TYPE *pMediaType)
Definition: filtergraph.c:692
#define FIXME(fmt,...)
Definition: debug.h:110
static BaseOutputPin * impl_BaseOutputPin_from_BasePin(BasePin *iface)
Definition: pin.c:358
HRESULT WINAPI BaseInputPinImpl_Connect(IPin *iface, IPin *pConnector, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:881
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
static HRESULT WINAPI MemInputPin_GetAllocatorRequirements(IMemInputPin *iface, ALLOCATOR_PROPERTIES *pProps)
Definition: pin.c:1098
smooth NULL
Definition: ftsmooth.c:416
REFERENCE_TIME tStop
Definition: strmbase.h:42
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(BasePin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:712
HRESULT WINAPI BasePinImpl_GetMediaType(BasePin *iface, int iPosition, AM_MEDIA_TYPE *pmt)
Definition: pin.c:175
const struct BasePinFuncTable * pFuncsTable
Definition: strmbase.h:45
HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin *iface)
Definition: pin.c:497
unsigned int dir
Definition: maze.c:112
#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
static void Copy_PinInfo(PIN_INFO *pDest, const PIN_INFO *pSrc)
Definition: pin.c:146
static BOOL CompareMediaTypes(const AM_MEDIA_TYPE *pmt1, const AM_MEDIA_TYPE *pmt2, BOOL bWildcards)
Definition: pin.c:164
ULONG WINAPI BasePinImpl_AddRef(IPin *iface)
Definition: pin.c:187
HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO *pPinInfo, const BaseOutputPinFuncTable *vtbl, LPCRITICAL_SECTION pCritSec, IPin **ppPin)
Definition: pin.c:791
HRESULT WINAPI BasePinImpl_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:311
BOOL end_of_stream
Definition: strmbase.h:94
REFERENCE_TIME tStart
Definition: pin.c:170
#define TRACE(s)
Definition: solgame.cpp:4
BOOL flushing
Definition: strmbase.h:94
LONGLONG REFERENCE_TIME
Definition: dmusicks.h:9
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
BasePin pin
Definition: strmbase.h:66
HRESULT WINAPI BaseOutputPin_Destroy(BaseOutputPin *This)
Definition: pin.c:821
HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin *iface)
Definition: pin.c:527
#define WINAPI
Definition: msvc.h:8
REFERENCE_TIME tStart
Definition: strmbase.h:41
static BaseInputPin * impl_from_IMemInputPin(IMemInputPin *iface)
Definition: pin.c:1031
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT WINAPI BasePinImpl_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
Definition: pin.c:273
IMemAllocator * preferred_allocator
Definition: strmbase.h:95
HRESULT WINAPI BaseOutputPinImpl_DecideAllocator(BaseOutputPin *This, IMemInputPin *pPin, IMemAllocator **pAlloc)
Definition: pin.c:683
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static HRESULT CopyMediaType(AM_MEDIA_TYPE *pDest, const AM_MEDIA_TYPE *pSrc)
Definition: filtergraph.c:706
HRESULT WINAPI BasePinImpl_Disconnect(IPin *iface)
Definition: pin.c:197
static HRESULT SendFurther(IPin *from, SendPinFunc fnMiddle, LPVOID arg, SendPinFunc fnEnd)
Definition: pin.c:67
IPin * pConnectedTo
Definition: strmbase.h:39
double dRate
Definition: strmbase.h:43
HRESULT BaseInputPin_Construct(const IPinVtbl *InputPin_Vtbl, LONG inputpin_size, const PIN_INFO *pPinInfo, const BaseInputPinFuncTable *vtbl, LPCRITICAL_SECTION pCritSec, IMemAllocator *allocator, IPin **ppPin)
Definition: pin.c:1189
#define InterlockedDecrement
Definition: armddk.h:52
ULONG WINAPI BaseOutputPinImpl_Release(IPin *iface)
Definition: pin.c:392
#define VFW_E_TYPE_NOT_ACCEPTED
Definition: vfwmsgs.h:81
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
HRESULT WINAPI BaseOutputPinImpl_BreakConnect(BaseOutputPin *This)
Definition: pin.c:654
HRESULT WINAPI BaseInputPinImpl_EndOfStream(IPin *iface)
Definition: pin.c:944
#define VFW_E_NO_ALLOCATOR
Definition: vfwmsgs.h:49
IMemAllocator * pAllocator
Definition: strmbase.h:93
#define GUID_NULL
Definition: ks.h:106
IMemInputPin * pMemInputPin
Definition: strmbase.h:67
HRESULT WINAPI BaseOutputPinImpl_Active(BaseOutputPin *This)
Definition: pin.c:614
HRESULT WINAPI BasePinImpl_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
Definition: pin.c:285
HRESULT WINAPI BaseOutputPinImpl_InitAllocator(BaseOutputPin *This, IMemAllocator **pMemAlloc)
Definition: pin.c:678
HRESULT WINAPI BaseInputPinImpl_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:935
static const IMemInputPinVtbl MemInputPin_Vtbl
Definition: pin.c:34
static BasePin * impl_from_IPin(IPin *iface)
Definition: pin.c:38
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3234
HRESULT WINAPI EnumMediaTypes_Construct(BasePin *iface, BasePin_GetMediaType enumFunc, BasePin_GetMediaTypeVersion versionFunc, IEnumMediaTypes **ppEnum)
Definition: mediatype.c:108
#define ERR(fmt,...)
Definition: debug.h:109
int connected
Definition: main.c:61
#define S_OK
Definition: intsafe.h:59
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
#define InterlockedIncrement
Definition: armddk.h:53
#define VFW_E_ENUM_OUT_OF_SYNC
Definition: vfwmsgs.h:42
Definition: axcore.idl:91
IMemAllocator * pAllocator
Definition: strmbase.h:68
#define E_NOTIMPL
Definition: ddrawi.h:99
static HRESULT WINAPI MemInputPin_NotifyAllocator(IMemInputPin *iface, IMemAllocator *pAllocator, BOOL bReadOnly)
Definition: pin.c:1070
WINE_DEFAULT_DEBUG_CHANNEL(quartz)
static HRESULT deliver_endofstream(IPin *pin, LPVOID unused)
Definition: pin.c:930
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin *iface, IPin **ppPin)
Definition: pin.c:222
HRESULT WINAPI BasePinImpl_QueryId(IPin *iface, LPWSTR *Id)
Definition: pin.c:296
HRESULT WINAPI BasePinImpl_EnumMediaTypes(IPin *iface, IEnumMediaTypes **ppEnum)
Definition: pin.c:318
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
LONG WINAPI BasePinImpl_GetMediaTypeVersion(BasePin *iface)
Definition: pin.c:182
enum _PinDirection PIN_DIRECTION
#define E_UNEXPECTED
Definition: winerror.h:2456
PIN_INFO pinInfo
Definition: strmbase.h:38
HRESULT WINAPI BaseOutputPinImpl_Inactive(BaseOutputPin *This)
Definition: pin.c:634
HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin *iface)
Definition: pin.c:536
HRESULT WINAPI BasePinImpl_NewSegment(IPin *iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
Definition: pin.c:338
HRESULT WINAPI BasePinImpl_QueryInternalConnections(IPin *iface, IPin **apPin, ULONG *cPin)
Definition: pin.c:329
unsigned int ULONG
Definition: retypes.h:1
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:41
#define VFW_E_INVALID_DIRECTION
Definition: vfwmsgs.h:47
HRESULT WINAPI BaseOutputPinImpl_Deliver(BaseOutputPin *This, IMediaSample *pSample)
Definition: pin.c:574
HRESULT WINAPI BaseOutputPinImpl_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
Definition: pin.c:405
BasePinFuncTable base
Definition: strmbase.h:78
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static HRESULT deliver_newsegment(IPin *pin, LPVOID data)
Definition: pin.c:1009
CardRegion * from
Definition: spigame.cpp:19
#define E_POINTER
Definition: winerror.h:2365
static HRESULT deliver_beginflush(IPin *pin, LPVOID unused)
Definition: pin.c:963
HRESULT WINAPI BaseInputPinImpl_EndFlush(IPin *iface)
Definition: pin.c:988
#define args
Definition: format.c:66
const GUID IID_IPin
Definition: pincontrol.cpp:15
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:406
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static HRESULT deliver_endflush(IPin *pin, LPVOID unused)
Definition: pin.c:983
static HRESULT WINAPI MemInputPin_GetAllocator(IMemInputPin *iface, IMemAllocator **ppAllocator)
Definition: pin.c:1057
AM_MEDIA_TYPE mtCurrent
Definition: strmbase.h:40
#define VFW_E_NO_ACCEPTABLE_TYPES
Definition: vfwmsgs.h:46
static BaseInputPin * impl_BaseInputPin_from_IPin(IPin *iface)
Definition: pin.c:833