2 * Modified for use with MPlayer, detailed changelog at
3 * http://svn.mplayerhq.hu/mplayer/trunk/
8 #include "wine/winerror.h"
13 static inline int unimplemented(const char* s
, void* p
)
15 Debug
printf("%s(%p) called (UNIMPLEMENTED)", s
, p
);
34 * \brief IEnumPins:Next (retrives a specified number of pins )
36 * \param[in] This pointer to CEnumPins object
37 * \param[in] cMediaTypes number of pins to retrive
38 * \param[out] ppMediaTypes array of IPin interface pointers of size cMediaTypes
39 * \param[out] pcFetched address of variables that receives number of returned pins
41 * \return S_OK - success
42 * \return S_FALSE - did not return as meny pins as requested
43 * \return E_INVALIDARG Invalid argument
44 * \return E_POINTER Null pointer
45 * \return VFW_E_ENUM_OUT_OF_SYNC - filter's state has changed and is now inconsistent with enumerator
48 static long STDCALL
CEnumPins_Next(IEnumPins
* This
,
49 /* [in] */ unsigned long cMediaTypes
,
50 /* [size_is][out] */ IPin
** ppMediaTypes
,
51 /* [out] */ unsigned long* pcFetched
)
53 CEnumPins
* pin
= (CEnumPins
*)This
;
55 Debug
printf("CEnumPins_Next(%p) called\n", This
);
58 if (!pcFetched
&& (cMediaTypes
!=1))
63 //lcounter = ((CEnumPins*)This)->counter;
64 //lpin1 = ((CEnumPins*)This)->pin1;
65 //lpin2 = ((CEnumPins*)This)->pin2;
66 if (((pin
->counter
== 2) && pin
->pin2
)
67 || ((pin
->counter
== 1) && !pin
->pin2
))
78 *ppMediaTypes
= pin
->pin1
;
79 pin
->pin1
->vt
->AddRef((IUnknown
*)pin
->pin1
);
83 *ppMediaTypes
= pin
->pin2
;
84 pin
->pin2
->vt
->AddRef((IUnknown
*)pin
->pin2
);
93 * \brief IEnumPins::Skip (skips over a specified number of pins)
95 * \param[in] This pointer to CEnumPinss object
96 * \param[in] cMediaTypes number of pins to skip
98 * \return S_OK - success
99 * \return S_FALSE - skipped past the end of the sequence
100 * \return VFW_E_ENUM_OUT_OF_SYNC - filter's state has changed and is now inconsistent with enumerator
103 static long STDCALL
CEnumPins_Skip(IEnumPins
* This
,
104 /* [in] */ unsigned long cMediaTypes
)
106 Debug
unimplemented("CEnumPins_Skip", This
);
111 * \brief IEnumPins::Reset (resets enumeration sequence to beginning)
113 * \param[in] This pointer to CEnumPins object
115 * \return S_OK - success
118 static long STDCALL
CEnumPins_Reset(IEnumPins
* This
)
120 Debug
printf("CEnumPins_Reset(%p) called\n", This
);
121 ((CEnumPins
*)This
)->counter
= 0;
126 * \brief IEnumPins::Clone (makes a copy of enumerator, returned object
127 * starts at the same position as original)
129 * \param[in] This pointer to CEnumPins object
130 * \param[out] ppEnum address of variable that receives pointer to IEnumPins interface
132 * \return S_OK - success
133 * \return E_OUTOFMEMRY - Insufficient memory
134 * \return E_POINTER - Null pointer
135 * \return VFW_E_ENUM_OUT_OF_SYNC - filter's state has changed and is now inconsistent with enumerator
138 static long STDCALL
CEnumPins_Clone(IEnumPins
* This
,
139 /* [out] */ IEnumPins
** ppEnum
)
141 Debug
unimplemented("CEnumPins_Clone", This
);
146 * \brief CEnumPins destructor
148 * \param[in] This pointer to CEnumPins object
151 static void CEnumPins_Destroy(CEnumPins
* This
)
157 IMPLEMENT_IUNKNOWN(CEnumPins
)
160 * \brief CEnumPins constructor
162 * \param[in] p first pin for enumerator
163 * \param[in] pp second pin for enumerator
165 * \return pointer to CEnumPins object or NULL if error occured
168 static CEnumPins
* CEnumPinsCreate(IPin
* p
, IPin
* pp
)
170 CEnumPins
* This
= (CEnumPins
*) malloc(sizeof(CEnumPins
));
180 This
->vt
= (IEnumPins_vt
*) malloc(sizeof(IEnumPins_vt
));
186 This
->vt
->QueryInterface
= CEnumPins_QueryInterface
;
187 This
->vt
->AddRef
= CEnumPins_AddRef
;
188 This
->vt
->Release
= CEnumPins_Release
;
189 This
->vt
->Next
= CEnumPins_Next
;
190 This
->vt
->Skip
= CEnumPins_Skip
;
191 This
->vt
->Reset
= CEnumPins_Reset
;
192 This
->vt
->Clone
= CEnumPins_Clone
;
194 This
->interfaces
[0] = IID_IUnknown
;
195 This
->interfaces
[1] = IID_IEnumPins
;
206 * This is implementation of OUTPUT pin in DirectShow's terms
211 * \brief IPin::Connect (connects pin to another pin)
213 * \param[in] This pointer to IPin interface
214 * \param[in] pReceivePin pointer to IPin interface of remote pin
215 * \param[in] pmt suggested media type for link. Can be NULL (any media type)
217 * \return S_OK - success.
218 * \return VFW_E_ALREADY_CONNECTED - pin already connected
219 * \return VFW_E_NOT_STOPPED - filter is active
220 * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable
221 * \return Apropriate error code otherwise.
224 static long STDCALL
CInputPin_Connect(IPin
* This
,
225 /* [in] */ IPin
* pReceivePin
,
226 /* [in] */ AM_MEDIA_TYPE
* pmt
)
228 Debug
unimplemented("CInputPin_Connect", This
);
233 * \brief IPin::ReceiveConnection (accepts a connection from another pin)
235 * \param[in] This pointer to IPin interface
236 * \param[in] pConnector connecting pin's IPin interface
237 * \param[in] pmt suggested media type for connection
239 * \return S_OK - success
240 * \return E_POINTER - Null pointer
241 * \return VFW_E_ALREADY_CONNECTED - pin already connected
242 * \return VFW_E_NOT_STOPPED - filter is active
243 * \return VFW_E_TYPE_NOT_ACCEPT - type is not acceptable
246 * When returning S_OK method should also do the following:
247 * - store media type and return the same type in IPin::ConnectionMediaType
248 * - store pConnector and return it in IPin::ConnectedTo
251 static long STDCALL
CInputPin_ReceiveConnection(IPin
* This
,
252 /* [in] */ IPin
* pConnector
,
253 /* [in] */ const AM_MEDIA_TYPE
*pmt
)
255 Debug
unimplemented("CInputPin_ReceiveConnection", This
);
260 * \brief IPin::Disconnect (accepts a connection from another pin)
262 * \param[in] This pointer to IPin interface
264 * \return S_OK - success
265 * \return S_FALSE - pin was not connected
266 * \return VFW_E_NOT_STOPPED - filter is active
269 * To break connection you have to also call Disconnect on other pin
271 static long STDCALL
CInputPin_Disconnect(IPin
* This
)
273 Debug
unimplemented("CInputPin_Disconnect", This
);
278 * \brief IPin::ConnectedTo (retrieves pointer to the connected pin, if such exist)
280 * \param[in] This pointer to IPin interface
281 * \param[out] pPin pointer to remote pin's IPin interface
283 * \return S_OK - success
284 * \return E_POINTER - Null pointer
285 * \return VFW_E_NOT_CONNECTED - pin is not connected
288 * Caller must call Release on received IPin, when done
290 static long STDCALL
CInputPin_ConnectedTo(IPin
* This
,
291 /* [out] */ IPin
** pPin
)
293 Debug
unimplemented("CInputPin_ConnectedTo", This
);
298 * \brief IPin::ConnectionMediaType (retrieves media type for connection, if such exist)
300 * \param[in] This pointer to IPin interface
301 * \param[out] pmt pointer to AM_MEDIA_TYPE, that receives connection media type
303 * \return S_OK - success
304 * \return E_POINTER - Null pointer
305 * \return VFW_E_NOT_CONNECTED - pin is not connected
308 static long STDCALL
CInputPin_ConnectionMediaType(IPin
* This
,
309 /* [out] */ AM_MEDIA_TYPE
*pmt
)
311 Debug
printf("CInputPin_ConnectionMediaType(%p) called\n", This
);
314 CopyMediaType(pmt
,&(((CInputPin
*)This
)->type
));
319 * \brief IPin::QueryPinInfo (retrieves information about the pin)
321 * \param[in] This pointer to IPin interface
322 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info
324 * \return S_OK - success
325 * \return E_POINTER - Null pointer
328 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done
331 static long STDCALL
CInputPin_QueryPinInfo(IPin
* This
,
332 /* [out] */ PIN_INFO
*pInfo
)
334 CBaseFilter
* lparent
=((CInputPin
*)This
)->parent
;
335 Debug
printf("CInputPin_QueryPinInfo(%p) called\n", This
);
336 pInfo
->dir
= PINDIR_OUTPUT
;
337 pInfo
->pFilter
= (IBaseFilter
*) lparent
;
338 lparent
->vt
->AddRef((IUnknown
*)lparent
);
339 pInfo
->achName
[0] = 0;
344 * \brief IPin::QueryDirection (retrieves pin direction)
346 * \param[in] This pointer to IPin interface
347 * \param[out] pPinDir pointer to variable, that receives pin direction (PINDIR_INPUT,PINDIR_OUTPUT)
349 * \return S_OK - success
350 * \return E_POINTER - Null pointer
353 static long STDCALL
CInputPin_QueryDirection(IPin
* This
,
354 /* [out] */ PIN_DIRECTION
*pPinDir
)
356 *pPinDir
= PINDIR_OUTPUT
;
357 Debug
printf("CInputPin_QueryDirection(%p) called\n", This
);
362 * \brief IPin::QueryId (retrieves pin identificator)
364 * \param[in] This pointer to IPin interface
365 * \param[out] Id adress of variable, that receives string with pin's Id.
367 * \return S_OK - success
368 * \return E_OUTOFMEMORY - Insufficient memory
369 * \return E_POINTER - Null pointer
372 * Pin's Id is not the same as pin's name
375 static long STDCALL
CInputPin_QueryId(IPin
* This
,
376 /* [out] */ unsigned short* *Id
)
378 Debug
unimplemented("CInputPin_QueryId", This
);
383 * \brief IPin::QueryAccept (determines can media type be accepted or not)
385 * \param[in] This pointer to IPin interface
386 * \param[in] pmt Media type to check
388 * \return S_OK - success
389 * \return S_FALSE - pin rejects media type
392 static long STDCALL
CInputPin_QueryAccept(IPin
* This
,
393 /* [in] */ const AM_MEDIA_TYPE
* pmt
)
395 Debug
unimplemented("CInputPin_QueryAccept", This
);
400 * \brief IPin::EnumMediaTypes (enumerates the pin's preferred media types)
402 * \param[in] This pointer to IPin interface
403 * \param[out] ppEnum adress of variable that receives pointer to IEnumMEdiaTypes interface
405 * \return S_OK - success
406 * \return E_OUTOFMEMORY - Insufficient memory
407 * \return E_POINTER - Null pointer
410 * Caller must call Release on received interface when done
413 static long STDCALL
CInputPin_EnumMediaTypes(IPin
* This
,
414 /* [out] */ IEnumMediaTypes
** ppEnum
)
416 Debug
unimplemented("CInputPin_EnumMediaTypes", This
);
421 * \brief IPin::QueryInternalConnections (retries pin's internal connections)
423 * \param[in] This pointer to IPin interface
424 * \param[out] apPin Array that receives pins, internally connected to this
425 * \param[in,out] nPint Size of an array
427 * \return S_OK - success
428 * \return S_FALSE - pin rejects media type
429 * \return E_NOTIMPL - not implemented
432 static long STDCALL
CInputPin_QueryInternalConnections(IPin
* This
,
433 /* [out] */ IPin
** apPin
,
434 /* [out][in] */ unsigned long *nPin
)
436 Debug
unimplemented("CInputPin_QueryInternalConnections", This
);
441 * \brief IPin::EndOfStream (notifies pin, that no data is expected, until new run command)
443 * \param[in] This pointer to IPin interface
445 * \return S_OK - success
446 * \return E_UNEXPECTED - The pin is output pin
449 * IMemoryInputPin::Receive,IMemoryInputPin::ReceiveMultiple, IMemoryInputPin::EndOfStream,
450 * IMemAllocator::GetBuffer runs in different (streaming) thread then other
451 * methods (application thread).
452 * IMemoryInputPin::NewSegment runs either in streaming or application thread.
453 * Developer must use critical sections for thread-safing work.
456 static long STDCALL
CInputPin_EndOfStream(IPin
* This
)
458 Debug
unimplemented("CInputPin_EndOfStream", This
);
464 * \brief IPin::BeginFlush (begins a flush operation)
466 * \param[in] This pointer to IPin interface
468 * \return S_OK - success
469 * \return E_UNEXPECTED - The pin is output pin
472 static long STDCALL
CInputPin_BeginFlush(IPin
* This
)
474 Debug
unimplemented("CInputPin_BeginFlush", This
);
480 * \brief IPin::EndFlush (ends a flush operation)
482 * \param[in] This pointer to IPin interface
484 * \return S_OK - success
485 * \return E_UNEXPECTED - The pin is output pin
488 static long STDCALL
CInputPin_EndFlush(IPin
* This
)
490 Debug
unimplemented("CInputPin_EndFlush", This
);
495 * \brief IPin::NewSegment (media sample received after this call grouped as segment with common
496 * start,stop time and rate)
498 * \param[in] This pointer to IPin interface
499 * \param[in] tStart start time of new segment
500 * \param[in] tStop end time of new segment
501 * \param[in] dRate rate at wich segment should be processed
503 * \return S_OK - success
504 * \return E_UNEXPECTED - The pin is output pin
507 static long STDCALL
CInputPin_NewSegment(IPin
* This
,
508 /* [in] */ REFERENCE_TIME tStart
,
509 /* [in] */ REFERENCE_TIME tStop
,
510 /* [in] */ double dRate
)
512 Debug
unimplemented("CInputPin_NewSegment", This
);
517 * \brief CInputPin destructor
519 * \param[in] This pointer to CInputPin class
522 static void CInputPin_Destroy(CInputPin
* This
)
525 FreeMediaType(&(This
->type
));
529 IMPLEMENT_IUNKNOWN(CInputPin
)
532 * \brief CInputPin constructor
534 * \param[in] amt media type for pin
536 * \return pointer to CInputPin if success
537 * \return NULL if error occured
540 CInputPin
* CInputPinCreate(CBaseFilter
* p
, const AM_MEDIA_TYPE
* amt
)
542 CInputPin
* This
= (CInputPin
*) malloc(sizeof(CInputPin
));
549 CopyMediaType(&(This
->type
),amt
);
551 This
->vt
= (IPin_vt
*) malloc(sizeof(IPin_vt
));
559 This
->vt
->QueryInterface
= CInputPin_QueryInterface
;
560 This
->vt
->AddRef
= CInputPin_AddRef
;
561 This
->vt
->Release
= CInputPin_Release
;
562 This
->vt
->Connect
= CInputPin_Connect
;
563 This
->vt
->ReceiveConnection
= CInputPin_ReceiveConnection
;
564 This
->vt
->Disconnect
= CInputPin_Disconnect
;
565 This
->vt
->ConnectedTo
= CInputPin_ConnectedTo
;
566 This
->vt
->ConnectionMediaType
= CInputPin_ConnectionMediaType
;
567 This
->vt
->QueryPinInfo
= CInputPin_QueryPinInfo
;
568 This
->vt
->QueryDirection
= CInputPin_QueryDirection
;
569 This
->vt
->QueryId
= CInputPin_QueryId
;
570 This
->vt
->QueryAccept
= CInputPin_QueryAccept
;
571 This
->vt
->EnumMediaTypes
= CInputPin_EnumMediaTypes
;
572 This
->vt
->QueryInternalConnections
= CInputPin_QueryInternalConnections
;
573 This
->vt
->EndOfStream
= CInputPin_EndOfStream
;
574 This
->vt
->BeginFlush
= CInputPin_BeginFlush
;
575 This
->vt
->EndFlush
= CInputPin_EndFlush
;
576 This
->vt
->NewSegment
= CInputPin_NewSegment
;
578 This
->interfaces
[0]=IID_IUnknown
;
588 static long STDCALL
CBaseFilter_GetClassID(IBaseFilter
* This
,
589 /* [out] */ CLSID
*pClassID
)
591 Debug
unimplemented("CBaseFilter_GetClassID", This
);
596 * \brief IMediaFilter::Stop (stops the filter)
598 * \param[in] This pointer to IBaseFilter interface
600 * \return S_OK success
601 * \return S_FALSE transition is not complete
604 * When filter is stopped it does onot deliver or process any samples and rejects any samples
605 * from upstream filter.
606 * Transition may be asynchronous. In this case method should return S_FALSE.
607 * Method always sets filter's state to State_Stopped even if error occured.
610 static long STDCALL
CBaseFilter_Stop(IBaseFilter
* This
)
612 Debug
unimplemented("CBaseFilter_Stop", This
);
617 * \brief IMediaFilter::Pause (pauses filter)
619 * \param[in] This pointer to IBaseFilter interface
621 * \return S_OK success
622 * \return S_FALSE transition is not complete
625 * When filter is paused it can receive, process and deliver samples.
626 * Live source filters do not deliver any samples while paused.
627 * Transition may be asynchronous. In this case method should return S_FALSE.
628 * Method always sets filter's state to State_Stopped even if error occured.
631 static long STDCALL
CBaseFilter_Pause(IBaseFilter
* This
)
633 Debug
unimplemented("CBaseFilter_Pause", This
);
638 * \brief IMediaFilter::Run (runs the filter)
640 * \param[in] This pointer to IBaseFilter interface
641 * \param[in] tStart Reference time corresponding to stream time 0.
643 * \return S_OK success
644 * \return S_FALSE transition is not complete
647 * When filter is running it can receive, process and deliver samples. Source filters
648 * generatesnew samples, and renderers renders them.
649 * Stream time is calculated as the current reference time minus tStart.
650 * Graph Manager sets tStart slightly in the future according to graph latency.
653 static long STDCALL
CBaseFilter_Run(IBaseFilter
* This
, REFERENCE_TIME tStart
)
655 Debug
unimplemented("CBaseFilter_Run", This
);
660 * \brief IMediaFilter::GetState (retrieves the filter's state (running, stopped or paused))
662 * \param[in] This pointer to IBaseFilter interface
663 * \param[in] dwMilliSecsTimeout Timeout interval in milliseconds. To block indifinitely pass
665 * \param[out] State pointer to variable that receives a member of FILTER_STATE enumeration.
667 * \return S_OK success
668 * \return E_POINTER Null pointer
669 * \return VFW_S_STATE_INTERMEDATE Intermediate state
670 * \return VFW_S_CANT_CUE The filter is active, but cannot deliver data.
673 static long STDCALL
CBaseFilter_GetState(IBaseFilter
* This
,
674 /* [in] */ unsigned long dwMilliSecsTimeout
,
675 // /* [out] */ FILTER_STATE *State)
678 Debug
unimplemented("CBaseFilter_GetState", This
);
683 * \brief IMediaFilter::SetSyncSource (sets the reference clock)
685 * \param[in] This pointer to IBaseFilter interface
686 * \param[in] pClock IReferenceClock interface of reference clock
688 * \return S_OK success
689 * \return apripriate error otherwise
692 static long STDCALL
CBaseFilter_SetSyncSource(IBaseFilter
* This
,
693 /* [in] */ IReferenceClock
*pClock
)
695 Debug
unimplemented("CBaseFilter_SetSyncSource", This
);
700 * \brief IMediafilter::GetSyncSource (gets current reference clock)
702 * \param[in] This pointer to IBaseFilter interface
703 * \param[out] pClock address of variable that receives pointer to clock's
704 * IReferenceClock interface
706 * \return S_OK success
707 * \return E_POINTER Null pointer
710 static long STDCALL
CBaseFilter_GetSyncSource(IBaseFilter
* This
,
711 /* [out] */ IReferenceClock
**pClock
)
713 Debug
unimplemented("CBaseFilter_GetSyncSource", This
);
719 * \brief IBaseFilter::EnumPins (enumerates the pins of this filter)
721 * \param[in] This pointer to IBaseFilter interface
722 * \param[out] ppEnum address of variable that receives pointer to IEnumPins interface
724 * \return S_OK success
725 * \return E_OUTOFMEMORY Insufficient memory
726 * \return E_POINTER Null pointer
729 static long STDCALL
CBaseFilter_EnumPins(IBaseFilter
* This
,
730 /* [out] */ IEnumPins
**ppEnum
)
732 Debug
printf("CBaseFilter_EnumPins(%p) called\n", This
);
733 *ppEnum
= (IEnumPins
*) CEnumPinsCreate(((CBaseFilter
*)This
)->pin
, ((CBaseFilter
*)This
)->unused_pin
);
738 * \brief IBaseFilter::FindPin (retrieves the pin with specified id)
740 * \param[in] This pointer to IBaseFilter interface
741 * \param[in] Id constant wide string, containing pin id
742 * \param[out] ppPin address of variable that receives pointer to pin's IPin interface
744 * \return S_OK success
745 * \return E_POINTER Null pointer
746 * \return VFW_E_NOT_FOUND Could not find a pin with specified id
749 * Be sure to release the interface after use.
752 static long STDCALL
CBaseFilter_FindPin(IBaseFilter
* This
,
753 /* [string][in] */ const unsigned short* Id
,
754 /* [out] */ IPin
**ppPin
)
756 Debug
unimplemented("CBaseFilter_FindPin\n", This
);
761 * \brief IBaseFilter::QueryFilterInfo (retrieves information aboud the filter)
763 * \param[in] This pointer to IBaseFilter interface
764 * \param[out] pInfo pointer to FILTER_INFO structure
766 * \return S_OK success
767 * \return E_POINTER Null pointer
770 * If pGraph member of FILTER_INFO is not NULL, be sure to release IFilterGraph interface after use.
773 static long STDCALL
CBaseFilter_QueryFilterInfo(IBaseFilter
* This
,
774 // /* [out] */ FILTER_INFO *pInfo)
777 Debug
unimplemented("CBaseFilter_QueryFilterInfo", This
);
782 * \brief IBaseFilter::JoinFilterGraph (notifies the filter that it has joined of left filter graph)
784 * \param[in] This pointer to IBaseFilter interface
785 * \param[in] pInfo pointer to graph's IFilterGraph interface or NULL if filter is leaving graph
786 * \param[in] pName pointer to wide character string that specifies a name for the filter
788 * \return S_OK success
789 * \return apropriate error code otherwise
792 * Filter should not call to graph's AddRef method.
793 * The IFilterGraph is guaranteed to be valid until graph manager calls this method again with
797 static long STDCALL
CBaseFilter_JoinFilterGraph(IBaseFilter
* This
,
798 /* [in] */ IFilterGraph
* pGraph
,
799 /* [string][in] */ const unsigned short* pName
)
801 Debug
unimplemented("CBaseFilter_JoinFilterGraph", This
);
806 * \brief IBaseFilter::QueryVendorInfo (retrieves a string containing vendor info)
808 * \param[in] This pointer to IBaseFilter interface
809 * \param[out] address of variable that receives pointer to a string containing vendor info
811 * \return S_OK success
812 * \return E_POINTER Null pointer
813 * \return E_NOTIMPL Not implemented
816 * Call to CoTaskMemFree to free memory allocated for string
819 static long STDCALL
CBaseFilter_QueryVendorInfo(IBaseFilter
* This
,
820 /* [string][out] */ unsigned short** pVendorInfo
)
822 Debug
unimplemented("CBaseFilter_QueryVendorInfo", This
);
827 * \brief CBaseFilter::GetPin (gets used pin)
829 * \param[in] This pointer to CBaseFilter object
831 * \return pointer to used pin's IPin interface
834 static IPin
* CBaseFilter_GetPin(CBaseFilter
* This
)
840 * \brief CBaseFilter::GetUnusedPin (gets used pin)
842 * \param[in] This pointer to CBaseFilter object
844 * \return pointer to unused pin's IPin interface
847 static IPin
* CBaseFilter_GetUnusedPin(CBaseFilter
* This
)
849 return This
->unused_pin
;
853 * \brief CBaseFilter destructor
855 * \param[in] This pointer to CBaseFilter object
858 static void CBaseFilter_Destroy(CBaseFilter
* This
)
863 This
->pin
->vt
->Release((IUnknown
*)This
->pin
);
864 if (This
->unused_pin
)
865 This
->unused_pin
->vt
->Release((IUnknown
*)This
->unused_pin
);
869 IMPLEMENT_IUNKNOWN(CBaseFilter
)
872 * \brief CBaseFilter constructor
874 * \param[in] type Pointer to media type for connection
875 * \param[in] parent Pointer to parent CBaseFilter2 object
877 * \return pointer to CBaseFilter object or NULL if error occured
880 CBaseFilter
* CBaseFilterCreate(const AM_MEDIA_TYPE
* type
, CBaseFilter2
* parent
)
882 CBaseFilter
* This
= (CBaseFilter
*) malloc(sizeof(CBaseFilter
));
888 This
->pin
= (IPin
*) CInputPinCreate(This
, type
);
889 This
->unused_pin
= (IPin
*) CRemotePinCreate(This
, parent
->GetPin(parent
));
891 This
->vt
= (IBaseFilter_vt
*) malloc(sizeof(IBaseFilter_vt
));
892 if (!This
->vt
|| !This
->pin
|| !This
->unused_pin
)
894 CBaseFilter_Destroy(This
);
898 This
->vt
->QueryInterface
= CBaseFilter_QueryInterface
;
899 This
->vt
->AddRef
= CBaseFilter_AddRef
;
900 This
->vt
->Release
= CBaseFilter_Release
;
901 This
->vt
->GetClassID
= CBaseFilter_GetClassID
;
902 This
->vt
->Stop
= CBaseFilter_Stop
;
903 This
->vt
->Pause
= CBaseFilter_Pause
;
904 This
->vt
->Run
= CBaseFilter_Run
;
905 This
->vt
->GetState
= CBaseFilter_GetState
;
906 This
->vt
->SetSyncSource
= CBaseFilter_SetSyncSource
;
907 This
->vt
->GetSyncSource
= CBaseFilter_GetSyncSource
;
908 This
->vt
->EnumPins
= CBaseFilter_EnumPins
;
909 This
->vt
->FindPin
= CBaseFilter_FindPin
;
910 This
->vt
->QueryFilterInfo
= CBaseFilter_QueryFilterInfo
;
911 This
->vt
->JoinFilterGraph
= CBaseFilter_JoinFilterGraph
;
912 This
->vt
->QueryVendorInfo
= CBaseFilter_QueryVendorInfo
;
914 This
->interfaces
[0] = IID_IUnknown
;
915 This
->interfaces
[1] = IID_IBaseFilter
;
917 This
->GetPin
= CBaseFilter_GetPin
;
918 This
->GetUnusedPin
= CBaseFilter_GetUnusedPin
;
929 static long STDCALL
CBaseFilter2_GetClassID(IBaseFilter
* This
,
930 /* [out] */ CLSID
* pClassID
)
932 Debug
unimplemented("CBaseFilter2_GetClassID", This
);
937 * \brief IMediaFilter::Stop (stops the filter)
939 * \param[in] This pointer to IBaseFilter interface
941 * \return S_OK success
942 * \return S_FALSE transition is not complete
945 * When filter is stopped it does onot deliver or process any samples and rejects any samples
946 * from upstream filter.
947 * Transition may be asynchronous. In this case method should return S_FALSE.
948 * Method always sets filter's state to State_Stopped even if error occured.
951 static long STDCALL
CBaseFilter2_Stop(IBaseFilter
* This
)
953 Debug
unimplemented("CBaseFilter2_Stop", This
);
958 * \brief IMediaFilter::Pause (pauses filter)
960 * \param[in] This pointer to IBaseFilter interface
962 * \return S_OK success
963 * \return S_FALSE transition is not complete
966 * When filter is paused it can receive, process and deliver samples.
967 * Live source filters do not deliver any samples while paused.
968 * Transition may be asynchronous. In this case method should return S_FALSE.
969 * Method always sets filter's state to State_Stopped even if error occured.
972 static long STDCALL
CBaseFilter2_Pause(IBaseFilter
* This
)
974 Debug
unimplemented("CBaseFilter2_Pause", This
);
979 * \brief IMediaFilter::Run (runs the filter)
981 * \param[in] This pointer to IBaseFilter interface
982 * \param[in] tStart Reference time corresponding to stream time 0.
984 * \return S_OK success
985 * \return S_FALSE transition is not complete
988 * When filter is running it can receive, process and deliver samples. Source filters
989 * generatesnew samples, and renderers renders them.
990 * Stream time is calculated as the current reference time minus tStart.
991 * Graph Manager sets tStart slightly in the future according to graph latency.
994 static long STDCALL
CBaseFilter2_Run(IBaseFilter
* This
, REFERENCE_TIME tStart
)
996 Debug
unimplemented("CBaseFilter2_Run", This
);
1002 * \brief IMediaFilter::GetState (retrieves the filter's state (running, stopped or paused))
1004 * \param[in] This pointer to IBaseFilter interface
1005 * \param[in] dwMilliSecsTimeout Timeout interval in milliseconds. To block indifinitely pass
1007 * \param[out] State pointer to variable that receives a member of FILTER_STATE enumeration.
1009 * \return S_OK success
1010 * \return E_POINTER Null pointer
1011 * \return VFW_S_STATE_INTERMEDATE Intermediate state
1012 * \return VFW_S_CANT_CUE The filter is active, but cannot deliver data.
1015 static long STDCALL
CBaseFilter2_GetState(IBaseFilter
* This
,
1016 /* [in] */ unsigned long dwMilliSecsTimeout
,
1017 // /* [out] */ FILTER_STATE *State)
1020 Debug
unimplemented("CBaseFilter2_GetState", This
);
1025 * \brief IMediaFilter::SetSyncSource (sets the reference clock)
1027 * \param[in] This pointer to IBaseFilter interface
1028 * \param[in] pClock IReferenceClock interface of reference clock
1030 * \return S_OK success
1031 * \return apripriate error otherwise
1034 static long STDCALL
CBaseFilter2_SetSyncSource(IBaseFilter
* This
,
1035 /* [in] */ IReferenceClock
* pClock
)
1037 Debug
unimplemented("CBaseFilter2_SetSyncSource", This
);
1042 * \brief IMediafilter::GetSyncSource (gets current reference clock)
1044 * \param[in] This pointer to IBaseFilter interface
1045 * \param[out] pClock address of variable that receives pointer to clock's
1046 * IReferenceClock interface
1048 * \return S_OK success
1049 * \return E_POINTER Null pointer
1052 static long STDCALL
CBaseFilter2_GetSyncSource(IBaseFilter
* This
,
1053 /* [out] */ IReferenceClock
** pClock
)
1055 Debug
unimplemented("CBaseFilter2_GetSyncSource", This
);
1060 * \brief IBaseFilter::EnumPins (enumerates the pins of this filter)
1062 * \param[in] This pointer to IBaseFilter interface
1063 * \param[out] ppEnum address of variable that receives pointer to IEnumPins interface
1065 * \return S_OK success
1066 * \return E_OUTOFMEMORY Insufficient memory
1067 * \return E_POINTER Null pointer
1070 static long STDCALL
CBaseFilter2_EnumPins(IBaseFilter
* This
,
1071 /* [out] */ IEnumPins
** ppEnum
)
1073 Debug
printf("CBaseFilter2_EnumPins(%p) called\n", This
);
1074 *ppEnum
= (IEnumPins
*) CEnumPinsCreate(((CBaseFilter2
*)This
)->pin
, 0);
1079 * \brief IBaseFilter::FindPin (retrieves the pin with specified id)
1081 * \param[in] This pointer to IBaseFilter interface
1082 * \param[in] Id constant wide string, containing pin id
1083 * \param[out] ppPin address of variable that receives pointer to pin's IPin interface
1085 * \return S_OK success
1086 * \return E_POINTER Null pointer
1087 * \return VFW_E_NOT_FOUND Could not find a pin with specified id
1090 * Be sure to release the interface after use.
1093 static long STDCALL
CBaseFilter2_FindPin(IBaseFilter
* This
,
1094 /* [string][in] */ const unsigned short* Id
,
1095 /* [out] */ IPin
** ppPin
)
1097 Debug
unimplemented("CBaseFilter2_FindPin", This
);
1102 * \brief IBaseFilter::QueryFilterInfo (retrieves information aboud the filter)
1104 * \param[in] This pointer to IBaseFilter interface
1105 * \param[out] pInfo pointer to FILTER_INFO structure
1107 * \return S_OK success
1108 * \return E_POINTER Null pointer
1111 * If pGraph member of FILTER_INFO is not NULL, be sure to release IFilterGraph interface after use.
1114 static long STDCALL
CBaseFilter2_QueryFilterInfo(IBaseFilter
* This
,
1115 // /* [out] */ FILTER_INFO *pInfo)
1118 Debug
unimplemented("CBaseFilter2_QueryFilterInfo", This
);
1123 * \brief IBaseFilter::JoinFilterGraph (notifies the filter that it has joined of left filter graph)
1125 * \param[in] This pointer to IBaseFilter interface
1126 * \param[in] pInfo pointer to graph's IFilterGraph interface or NULL if filter is leaving graph
1127 * \param[in] pName pointer to wide character string that specifies a name for the filter
1129 * \return S_OK success
1130 * \return apropriate error code otherwise
1133 * Filter should not call to graph's AddRef method.
1134 * The IFilterGraph is guaranteed to be valid until graph manager calls this method again with
1138 static long STDCALL
CBaseFilter2_JoinFilterGraph(IBaseFilter
* This
,
1139 /* [in] */ IFilterGraph
* pGraph
,
1141 const unsigned short* pName
)
1143 Debug
unimplemented("CBaseFilter2_JoinFilterGraph", This
);
1148 * \brief IBaseFilter::QueryVendorInfo (retrieves a string containing vendor info)
1150 * \param[in] This pointer to IBaseFilter interface
1151 * \param[out] address of variable that receives pointer to a string containing vendor info
1153 * \return S_OK success
1154 * \return E_POINTER Null pointer
1155 * \return E_NOTIMPL Not implemented
1158 * Call to CoTaskMemFree to free memory allocated for string
1161 static long STDCALL
CBaseFilter2_QueryVendorInfo(IBaseFilter
* This
,
1163 unsigned short** pVendorInfo
)
1165 Debug
unimplemented("CBaseFilter2_QueryVendorInfo", This
);
1170 * \brief CBaseFilter2::GetPin (gets used pin)
1172 * \param[in] This pointer to CBaseFilter2 object
1174 * \return pointer to used pin's IPin interface
1177 static IPin
* CBaseFilter2_GetPin(CBaseFilter2
* This
)
1183 * \brief CBaseFilter2 destructor
1185 * \param[in] This pointer to CBaseFilter2 object
1188 static void CBaseFilter2_Destroy(CBaseFilter2
* This
)
1190 Debug
printf("CBaseFilter2_Destroy(%p) called\n", This
);
1192 This
->pin
->vt
->Release((IUnknown
*) This
->pin
);
1198 IMPLEMENT_IUNKNOWN(CBaseFilter2
)
1200 static GUID CBaseFilter2_interf1
=
1201 {0x76c61a30, 0xebe1, 0x11cf, {0x89, 0xf9, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb}};
1202 /// IID_IAMNetShowPreroll
1203 static GUID CBaseFilter2_interf2
=
1204 {0xaae7e4e2, 0x6388, 0x11d1, {0x8d, 0x93, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2}};
1206 static GUID CBaseFilter2_interf3
=
1207 {0x02ef04dd, 0x7580, 0x11d1, {0xbe, 0xce, 0x00, 0xc0, 0x4f, 0xb6, 0xe9, 0x37}};
1210 * \brief CBaseFilter2 constructor
1212 * \return pointer to CBaseFilter2 object or NULL if error occured
1215 CBaseFilter2
* CBaseFilter2Create()
1217 CBaseFilter2
* This
= (CBaseFilter2
*) malloc(sizeof(CBaseFilter2
));
1223 This
->pin
= (IPin
*) CRemotePin2Create(This
);
1225 This
->vt
= (IBaseFilter_vt
*) malloc(sizeof(IBaseFilter_vt
));
1227 if (!This
->pin
|| !This
->vt
)
1229 CBaseFilter2_Destroy(This
);
1233 memset(This
->vt
, 0, sizeof(IBaseFilter_vt
));
1234 This
->vt
->QueryInterface
= CBaseFilter2_QueryInterface
;
1235 This
->vt
->AddRef
= CBaseFilter2_AddRef
;
1236 This
->vt
->Release
= CBaseFilter2_Release
;
1237 This
->vt
->GetClassID
= CBaseFilter2_GetClassID
;
1238 This
->vt
->Stop
= CBaseFilter2_Stop
;
1239 This
->vt
->Pause
= CBaseFilter2_Pause
;
1240 This
->vt
->Run
= CBaseFilter2_Run
;
1241 This
->vt
->GetState
= CBaseFilter2_GetState
;
1242 This
->vt
->SetSyncSource
= CBaseFilter2_SetSyncSource
;
1243 This
->vt
->GetSyncSource
= CBaseFilter2_GetSyncSource
;
1244 This
->vt
->EnumPins
= CBaseFilter2_EnumPins
;
1245 This
->vt
->FindPin
= CBaseFilter2_FindPin
;
1246 This
->vt
->QueryFilterInfo
= CBaseFilter2_QueryFilterInfo
;
1247 This
->vt
->JoinFilterGraph
= CBaseFilter2_JoinFilterGraph
;
1248 This
->vt
->QueryVendorInfo
= CBaseFilter2_QueryVendorInfo
;
1250 This
->GetPin
= CBaseFilter2_GetPin
;
1252 This
->interfaces
[0] = IID_IUnknown
;
1253 This
->interfaces
[1] = IID_IBaseFilter
;
1254 This
->interfaces
[2] = CBaseFilter2_interf1
;
1255 This
->interfaces
[3] = CBaseFilter2_interf2
;
1256 This
->interfaces
[4] = CBaseFilter2_interf3
;
1268 * \brief IPin::ConnectedTo (retrieves pointer to the connected pin, if such exist)
1270 * \param[in] This pointer to IPin interface
1271 * \param[out] pPin pointer to remote pin's IPin interface
1273 * \return S_OK - success
1274 * \return E_POINTER - Null pointer
1275 * \return VFW_E_NOT_CONNECTED - pin is not connected
1278 * Caller must call Release on received IPin, when done
1280 static long STDCALL
CRemotePin_ConnectedTo(IPin
* This
, /* [out] */ IPin
** pPin
)
1282 Debug
printf("CRemotePin_ConnectedTo(%p) called\n", This
);
1284 return E_INVALIDARG
;
1285 *pPin
= ((CRemotePin
*)This
)->remote_pin
;
1286 (*pPin
)->vt
->AddRef((IUnknown
*)(*pPin
));
1291 * \brief IPin::QueryDirection (retrieves pin direction)
1293 * \param[in] This pointer to IPin interface
1294 * \param[out] pPinDir pointer to variable, that receives pin direction (PINDIR_INPUT,PINDIR_OUTPUT)
1296 * \return S_OK - success
1297 * \return E_POINTER - Null pointer
1300 static long STDCALL
CRemotePin_QueryDirection(IPin
* This
,
1301 /* [out] */ PIN_DIRECTION
* pPinDir
)
1303 Debug
printf("CRemotePin_QueryDirection(%p) called\n", This
);
1305 return E_INVALIDARG
;
1306 *pPinDir
=PINDIR_INPUT
;
1311 * \brief IPin::ConnectionMediaType (retrieves media type for connection, if such exist)
1313 * \param[in] This pointer to IPin interface
1314 * \param[out] pmt pointer to AM_MEDIA_TYPE, that receives connection media type
1316 * \return S_OK - success
1317 * \return E_POINTER - Null pointer
1318 * \return VFW_E_NOT_CONNECTED - pin is not connected
1321 static long STDCALL
CRemotePin_ConnectionMediaType(IPin
* This
, /* [out] */ AM_MEDIA_TYPE
* pmt
)
1323 Debug
unimplemented("CRemotePin_ConnectionMediaType", This
);
1328 * \brief IPin::QueryPinInfo (retrieves information about the pin)
1330 * \param[in] This pointer to IPin interface
1331 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info
1333 * \return S_OK - success
1334 * \return E_POINTER - Null pointer
1337 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done
1340 static long STDCALL
CRemotePin_QueryPinInfo(IPin
* This
, /* [out] */ PIN_INFO
* pInfo
)
1342 CBaseFilter
* lparent
= ((CRemotePin
*)This
)->parent
;
1343 Debug
printf("CRemotePin_QueryPinInfo(%p) called\n", This
);
1344 pInfo
->dir
= PINDIR_INPUT
;
1345 pInfo
->pFilter
= (IBaseFilter
*) lparent
;
1346 lparent
->vt
->AddRef((IUnknown
*)lparent
);
1347 pInfo
->achName
[0]=0;
1352 * \brief CRemotePin destructor
1354 * \param[in] This pointer to CRemotePin object
1357 static void CRemotePin_Destroy(CRemotePin
* This
)
1359 Debug
printf("CRemotePin_Destroy(%p) called\n", This
);
1364 IMPLEMENT_IUNKNOWN(CRemotePin
)
1367 * \brief CRemotePin constructor
1369 * \param[in] pt parent filter
1370 * \param[in] rpin remote pin
1372 * \return pointer to CRemotePin or NULL if error occured
1375 CRemotePin
* CRemotePinCreate(CBaseFilter
* pt
, IPin
* rpin
)
1377 CRemotePin
* This
= (CRemotePin
*) malloc(sizeof(CRemotePin
));
1382 Debug
printf("CRemotePinCreate() called -> %p\n", This
);
1385 This
->remote_pin
= rpin
;
1388 This
->vt
= (IPin_vt
*) malloc(sizeof(IPin_vt
));
1396 memset(This
->vt
, 0, sizeof(IPin_vt
));
1397 This
->vt
->QueryInterface
= CRemotePin_QueryInterface
;
1398 This
->vt
->AddRef
= CRemotePin_AddRef
;
1399 This
->vt
->Release
= CRemotePin_Release
;
1400 This
->vt
->QueryDirection
= CRemotePin_QueryDirection
;
1401 This
->vt
->ConnectedTo
= CRemotePin_ConnectedTo
;
1402 This
->vt
->ConnectionMediaType
= CRemotePin_ConnectionMediaType
;
1403 This
->vt
->QueryPinInfo
= CRemotePin_QueryPinInfo
;
1405 This
->interfaces
[0] = IID_IUnknown
;
1417 * \brief IPin::QueryPinInfo (retrieves information about the pin)
1419 * \param[in] This pointer to IPin interface
1420 * \param[out] pInfo pointer to PIN_INFO structure, that receives pin info
1422 * \return S_OK - success
1423 * \return E_POINTER - Null pointer
1426 * If pInfo->pFilter is not NULL, then caller must call Release on pInfo->pFilter when done
1429 static long STDCALL
CRemotePin2_QueryPinInfo(IPin
* This
,
1430 /* [out] */ PIN_INFO
* pInfo
)
1432 CBaseFilter2
* lparent
=((CRemotePin2
*)This
)->parent
;
1433 Debug
printf("CRemotePin2_QueryPinInfo(%p) called\n", This
);
1434 pInfo
->pFilter
=(IBaseFilter
*)lparent
;
1435 lparent
->vt
->AddRef((IUnknown
*)lparent
);
1436 pInfo
->dir
=PINDIR_OUTPUT
;
1437 pInfo
->achName
[0]=0;
1442 * \brief CremotePin2 destructor
1444 * \param This pointer to CRemotePin2 object
1446 * FIXME - not being released!
1448 static void CRemotePin2_Destroy(CRemotePin2
* This
)
1450 Debug
printf("CRemotePin2_Destroy(%p) called\n", This
);
1455 IMPLEMENT_IUNKNOWN(CRemotePin2
)
1458 * \brief CRemotePin2 contructor
1460 * \param[in] p pointer to parent CBaseFilter2 object
1462 * \return pointer to CRemotePin2 object or NULL if error occured
1465 CRemotePin2
* CRemotePin2Create(CBaseFilter2
* p
)
1467 CRemotePin2
* This
= (CRemotePin2
*) malloc(sizeof(CRemotePin2
));
1472 Debug
printf("CRemotePin2Create() called -> %p\n", This
);
1477 This
->vt
= (IPin_vt
*) malloc(sizeof(IPin_vt
));
1485 memset(This
->vt
, 0, sizeof(IPin_vt
));
1486 This
->vt
->QueryInterface
= CRemotePin2_QueryInterface
;
1487 This
->vt
->AddRef
= CRemotePin2_AddRef
;
1488 This
->vt
->Release
= CRemotePin2_Release
;
1489 This
->vt
->QueryPinInfo
= CRemotePin2_QueryPinInfo
;
1491 This
->interfaces
[0] = IID_IUnknown
;