2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/output_pin.cpp
5 * PURPOSE: OutputPin of Proxy Filter
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
11 class COutputPin
: public IPin
,
13 public IKsPropertySet
,
14 public IStreamBuilder
,
16 public ISpecifyPropertyPages
,
20 public IKsAggregateControl
,
21 public IQualityControl
,
23 public IAMBufferNegotiation
,
24 public IAMStreamConfig
,
25 public IMemAllocatorNotifyCallbackTemp
29 typedef std::vector
<IUnknown
*>ProxyPluginVector
;
31 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
33 STDMETHODIMP_(ULONG
) AddRef()
35 InterlockedIncrement(&m_Ref
);
38 STDMETHODIMP_(ULONG
) Release()
40 InterlockedDecrement(&m_Ref
);
50 HRESULT STDMETHODCALLTYPE
KsQueryMediums(PKSMULTIPLE_ITEM
* MediumList
);
51 HRESULT STDMETHODCALLTYPE
KsQueryInterfaces(PKSMULTIPLE_ITEM
* InterfaceList
);
52 HRESULT STDMETHODCALLTYPE
KsCreateSinkPinHandle(KSPIN_INTERFACE
& Interface
, KSPIN_MEDIUM
& Medium
);
53 HRESULT STDMETHODCALLTYPE
KsGetCurrentCommunication(KSPIN_COMMUNICATION
*Communication
, KSPIN_INTERFACE
*Interface
, KSPIN_MEDIUM
*Medium
);
54 HRESULT STDMETHODCALLTYPE
KsPropagateAcquire();
55 HRESULT STDMETHODCALLTYPE
KsDeliver(IMediaSample
* Sample
, ULONG Flags
);
56 HRESULT STDMETHODCALLTYPE
KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
);
57 IMemAllocator
* STDMETHODCALLTYPE
KsPeekAllocator(KSPEEKOPERATION Operation
);
58 HRESULT STDMETHODCALLTYPE
KsReceiveAllocator(IMemAllocator
*MemAllocator
);
59 HRESULT STDMETHODCALLTYPE
KsRenegotiateAllocator();
60 LONG STDMETHODCALLTYPE
KsIncrementPendingIoCount();
61 LONG STDMETHODCALLTYPE
KsDecrementPendingIoCount();
62 HRESULT STDMETHODCALLTYPE
KsQualityNotify(ULONG Proportion
, REFERENCE_TIME TimeDelta
);
64 VOID STDMETHODCALLTYPE
KsNotifyError(IMediaSample
* Sample
, HRESULT hr
);
67 HRESULT STDMETHODCALLTYPE
KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX
*FramingEx
, PFRAMING_PROP FramingProp
, FRAMING_CACHE_OPS Option
);
68 HRESULT STDMETHODCALLTYPE
KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx
, PFRAMING_PROP FramingProp
, FRAMING_CACHE_OPS Option
);
69 IPin
* STDMETHODCALLTYPE
KsGetConnectedPin();
70 IKsAllocatorEx
* STDMETHODCALLTYPE
KsGetPipe(KSPEEKOPERATION Operation
);
71 HRESULT STDMETHODCALLTYPE
KsSetPipe(IKsAllocatorEx
*KsAllocator
);
72 ULONG STDMETHODCALLTYPE
KsGetPipeAllocatorFlag();
73 HRESULT STDMETHODCALLTYPE
KsSetPipeAllocatorFlag(ULONG Flag
);
74 GUID STDMETHODCALLTYPE
KsGetPinBusCache();
75 HRESULT STDMETHODCALLTYPE
KsSetPinBusCache(GUID Bus
);
76 PWCHAR STDMETHODCALLTYPE
KsGetPinName();
77 PWCHAR STDMETHODCALLTYPE
KsGetFilterName();
80 HRESULT STDMETHODCALLTYPE
Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
);
81 HRESULT STDMETHODCALLTYPE
ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
);
82 HRESULT STDMETHODCALLTYPE
Disconnect();
83 HRESULT STDMETHODCALLTYPE
ConnectedTo(IPin
**pPin
);
84 HRESULT STDMETHODCALLTYPE
ConnectionMediaType(AM_MEDIA_TYPE
*pmt
);
85 HRESULT STDMETHODCALLTYPE
QueryPinInfo(PIN_INFO
*pInfo
);
86 HRESULT STDMETHODCALLTYPE
QueryDirection(PIN_DIRECTION
*pPinDir
);
87 HRESULT STDMETHODCALLTYPE
QueryId(LPWSTR
*Id
);
88 HRESULT STDMETHODCALLTYPE
QueryAccept(const AM_MEDIA_TYPE
*pmt
);
89 HRESULT STDMETHODCALLTYPE
EnumMediaTypes(IEnumMediaTypes
**ppEnum
);
90 HRESULT STDMETHODCALLTYPE
QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
);
91 HRESULT STDMETHODCALLTYPE
EndOfStream();
92 HRESULT STDMETHODCALLTYPE
BeginFlush();
93 HRESULT STDMETHODCALLTYPE
EndFlush();
94 HRESULT STDMETHODCALLTYPE
NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
);
96 // ISpecifyPropertyPages
97 HRESULT STDMETHODCALLTYPE
GetPages(CAUUID
*pPages
);
100 HANDLE STDMETHODCALLTYPE
KsGetObjectHandle();
103 HRESULT STDMETHODCALLTYPE
Set(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
);
104 HRESULT STDMETHODCALLTYPE
Get(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
, DWORD
*pcbReturned
);
105 HRESULT STDMETHODCALLTYPE
QuerySupported(REFGUID guidPropSet
, DWORD dwPropID
, DWORD
*pTypeSupport
);
108 HRESULT STDMETHODCALLTYPE
KsProperty(PKSPROPERTY Property
, ULONG PropertyLength
, LPVOID PropertyData
, ULONG DataLength
, ULONG
* BytesReturned
);
109 HRESULT STDMETHODCALLTYPE
KsMethod(PKSMETHOD Method
, ULONG MethodLength
, LPVOID MethodData
, ULONG DataLength
, ULONG
* BytesReturned
);
110 HRESULT STDMETHODCALLTYPE
KsEvent(PKSEVENT Event
, ULONG EventLength
, LPVOID EventData
, ULONG DataLength
, ULONG
* BytesReturned
);
113 HRESULT STDMETHODCALLTYPE
Render(IPin
*ppinOut
, IGraphBuilder
*pGraph
);
114 HRESULT STDMETHODCALLTYPE
Backout(IPin
*ppinOut
, IGraphBuilder
*pGraph
);
117 HRESULT STDMETHODCALLTYPE
KsPinFactory(ULONG
* PinFactory
);
119 //IKsAggregateControl
120 HRESULT STDMETHODCALLTYPE
KsAddAggregate(IN REFGUID AggregateClass
);
121 HRESULT STDMETHODCALLTYPE
KsRemoveAggregate(REFGUID AggregateClass
);
124 HRESULT STDMETHODCALLTYPE
Notify(IBaseFilter
*pSelf
, Quality q
);
125 HRESULT STDMETHODCALLTYPE
SetSink(IQualityControl
*piqc
);
128 HRESULT STDMETHODCALLTYPE
GetCapabilities(DWORD
*pCapabilities
);
129 HRESULT STDMETHODCALLTYPE
CheckCapabilities(DWORD
*pCapabilities
);
130 HRESULT STDMETHODCALLTYPE
IsFormatSupported(const GUID
*pFormat
);
131 HRESULT STDMETHODCALLTYPE
QueryPreferredFormat(GUID
*pFormat
);
132 HRESULT STDMETHODCALLTYPE
GetTimeFormat(GUID
*pFormat
);
133 HRESULT STDMETHODCALLTYPE
IsUsingTimeFormat(const GUID
*pFormat
);
134 HRESULT STDMETHODCALLTYPE
SetTimeFormat(const GUID
*pFormat
);
135 HRESULT STDMETHODCALLTYPE
GetDuration(LONGLONG
*pDuration
);
136 HRESULT STDMETHODCALLTYPE
GetStopPosition(LONGLONG
*pStop
);
137 HRESULT STDMETHODCALLTYPE
GetCurrentPosition(LONGLONG
*pCurrent
);
138 HRESULT STDMETHODCALLTYPE
ConvertTimeFormat(LONGLONG
*pTarget
, const GUID
*pTargetFormat
, LONGLONG Source
, const GUID
*pSourceFormat
);
139 HRESULT STDMETHODCALLTYPE
SetPositions(LONGLONG
*pCurrent
, DWORD dwCurrentFlags
, LONGLONG
*pStop
, DWORD dwStopFlags
);
140 HRESULT STDMETHODCALLTYPE
GetPositions(LONGLONG
*pCurrent
, LONGLONG
*pStop
);
141 HRESULT STDMETHODCALLTYPE
GetAvailable(LONGLONG
*pEarliest
, LONGLONG
*pLatest
);
142 HRESULT STDMETHODCALLTYPE
SetRate(double dRate
);
143 HRESULT STDMETHODCALLTYPE
GetRate(double *pdRate
);
144 HRESULT STDMETHODCALLTYPE
GetPreroll(LONGLONG
*pllPreroll
);
146 //IAMBufferNegotiation
147 HRESULT STDMETHODCALLTYPE
SuggestAllocatorProperties(const ALLOCATOR_PROPERTIES
*pprop
);
148 HRESULT STDMETHODCALLTYPE
GetAllocatorProperties(ALLOCATOR_PROPERTIES
*pprop
);
151 HRESULT STDMETHODCALLTYPE
SetFormat(AM_MEDIA_TYPE
*pmt
);
152 HRESULT STDMETHODCALLTYPE
GetFormat(AM_MEDIA_TYPE
**ppmt
);
153 HRESULT STDMETHODCALLTYPE
GetNumberOfCapabilities(int *piCount
, int *piSize
);
154 HRESULT STDMETHODCALLTYPE
GetStreamCaps(int iIndex
, AM_MEDIA_TYPE
**ppmt
, BYTE
*pSCC
);
156 //IMemAllocatorNotifyCallbackTemp
157 HRESULT STDMETHODCALLTYPE
NotifyRelease();
159 //---------------------------------------------------------------
160 COutputPin(IBaseFilter
* ParentFilter
, LPCWSTR PinName
, ULONG PinId
, KSPIN_COMMUNICATION Communication
);
161 virtual ~COutputPin();
162 HRESULT STDMETHODCALLTYPE
CheckFormat(const AM_MEDIA_TYPE
*pmt
);
163 HRESULT STDMETHODCALLTYPE
CreatePin(const AM_MEDIA_TYPE
*pmt
);
164 HRESULT STDMETHODCALLTYPE
CreatePinHandle(PKSPIN_MEDIUM Medium
, PKSPIN_INTERFACE Interface
, const AM_MEDIA_TYPE
*pmt
);
165 HRESULT WINAPI
IoProcessRoutine();
166 HRESULT WINAPI
InitializeIOThread();
167 HRESULT STDMETHODCALLTYPE
GetSupportedSets(LPGUID
* pOutGuid
, PULONG NumGuids
);
168 HRESULT STDMETHODCALLTYPE
LoadProxyPlugins(LPGUID pGuids
, ULONG NumGuids
);
170 friend DWORD WINAPI
COutputPin_IoThreadStartup(LPVOID lpParameter
);
171 friend HRESULT STDMETHODCALLTYPE
COutputPin_SetState(IPin
* Pin
, KSSTATE State
);
175 IBaseFilter
* m_ParentFilter
;
180 IKsAllocatorEx
* m_KsAllocatorEx
;
181 ULONG m_PipeAllocatorFlag
;
182 BOOL m_bPinBusCacheInitialized
;
185 FRAMING_PROP m_FramingProp
[4];
186 PKSALLOCATOR_FRAMING_EX m_FramingEx
[4];
188 IMemAllocator
* m_MemAllocator
;
189 IMemInputPin
* m_MemInputPin
;
191 KSPIN_COMMUNICATION m_Communication
;
192 KSPIN_INTERFACE m_Interface
;
193 KSPIN_MEDIUM m_Medium
;
194 AM_MEDIA_TYPE m_MediaFormat
;
195 ALLOCATOR_PROPERTIES m_Properties
;
196 IKsInterfaceHandler
* m_InterfaceHandler
;
198 HANDLE m_hStartEvent
;
199 HANDLE m_hBufferAvailable
;
201 BOOL m_StopInProgress
;
202 BOOL m_IoThreadStarted
;
205 CRITICAL_SECTION m_Lock
;
207 ProxyPluginVector m_Plugins
;
210 COutputPin::~COutputPin()
214 COutputPin::COutputPin(
215 IBaseFilter
* ParentFilter
,
218 KSPIN_COMMUNICATION Communication
) : m_Ref(0),
219 m_ParentFilter(ParentFilter
),
221 m_hPin(INVALID_HANDLE_VALUE
),
225 m_PipeAllocatorFlag(0),
226 m_bPinBusCacheInitialized(0),
231 m_Communication(Communication
),
232 m_InterfaceHandler(0),
234 m_hBufferAvailable(0),
237 m_IoThreadStarted(0),
238 m_State(KSSTATE_STOP
),
242 IKsObject
* KsObjectParent
;
244 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
247 ZeroMemory(m_FramingProp
, sizeof(m_FramingProp
));
248 ZeroMemory(m_FramingEx
, sizeof(m_FramingEx
));
250 hr
= KsGetMediaType(0, &m_MediaFormat
, KsObjectParent
->KsGetObjectHandle(), m_PinId
);
253 InitializeCriticalSection(&m_Lock
);
255 KsObjectParent
->Release();
260 COutputPin::QueryInterface(
265 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
266 IsEqualGUID(refiid
, IID_IPin
))
269 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IPin\n");
271 *Output
= PVOID(this);
272 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
275 else if (IsEqualGUID(refiid
, IID_IKsObject
))
277 if (m_hPin
== INVALID_HANDLE_VALUE
)
279 HRESULT hr
= CreatePin(&m_MediaFormat
);
284 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsObject\n");
286 *Output
= (IKsObject
*)(this);
287 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
290 else if (IsEqualGUID(refiid
, IID_IKsPin
) || IsEqualGUID(refiid
, IID_IKsPinEx
))
292 *Output
= (IKsPinEx
*)(this);
293 reinterpret_cast<IKsPinEx
*>(*Output
)->AddRef();
296 else if (IsEqualGUID(refiid
, IID_IKsPinPipe
))
298 *Output
= (IKsPinPipe
*)(this);
299 reinterpret_cast<IKsPinPipe
*>(*Output
)->AddRef();
302 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
304 *Output
= (IKsAggregateControl
*)(this);
305 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
308 else if (IsEqualGUID(refiid
, IID_IQualityControl
))
310 *Output
= (IQualityControl
*)(this);
311 reinterpret_cast<IQualityControl
*>(*Output
)->AddRef();
314 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
316 if (m_hPin
== INVALID_HANDLE_VALUE
)
318 HRESULT hr
= CreatePin(&m_MediaFormat
);
323 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPropertySet\n");
325 *Output
= (IKsPropertySet
*)(this);
326 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
329 else if (IsEqualGUID(refiid
, IID_IKsControl
))
332 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsControl\n");
334 *Output
= (IKsControl
*)(this);
335 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
339 else if (IsEqualGUID(refiid
, IID_IStreamBuilder
))
341 *Output
= (IStreamBuilder
*)(this);
342 reinterpret_cast<IStreamBuilder
*>(*Output
)->AddRef();
346 else if (IsEqualGUID(refiid
, IID_IKsPinFactory
))
349 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPinFactory\n");
351 *Output
= (IKsPinFactory
*)(this);
352 reinterpret_cast<IKsPinFactory
*>(*Output
)->AddRef();
355 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
358 OutputDebugStringW(L
"COutputPin::QueryInterface IID_ISpecifyPropertyPages\n");
360 *Output
= (ISpecifyPropertyPages
*)(this);
361 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
364 else if (IsEqualGUID(refiid
, IID_IMediaSeeking
))
366 *Output
= (IMediaSeeking
*)(this);
367 reinterpret_cast<IMediaSeeking
*>(*Output
)->AddRef();
370 else if (IsEqualGUID(refiid
, IID_IAMBufferNegotiation
))
372 *Output
= (IAMBufferNegotiation
*)(this);
373 reinterpret_cast<IAMBufferNegotiation
*>(*Output
)->AddRef();
376 else if (IsEqualGUID(refiid
, IID_IAMStreamConfig
))
378 *Output
= (IAMStreamConfig
*)(this);
379 reinterpret_cast<IAMStreamConfig
*>(*Output
)->AddRef();
382 else if (IsEqualGUID(refiid
, IID_IMemAllocatorNotifyCallbackTemp
))
384 *Output
= (IMemAllocatorNotifyCallbackTemp
*)(this);
385 reinterpret_cast<IMemAllocatorNotifyCallbackTemp
*>(*Output
)->AddRef();
390 WCHAR Buffer
[MAX_PATH
];
392 StringFromCLSID(refiid
, &lpstr
);
393 swprintf(Buffer
, L
"COutputPin::QueryInterface: NoInterface for %s PinId %u PinName %s\n", lpstr
, m_PinId
, m_PinName
);
394 OutputDebugStringW(Buffer
);
395 CoTaskMemFree(lpstr
);
398 return E_NOINTERFACE
;
401 //-------------------------------------------------------------------
402 // IAMBufferNegotiation interface
406 COutputPin::SuggestAllocatorProperties(
407 const ALLOCATOR_PROPERTIES
*pprop
)
410 OutputDebugStringW(L
"COutputPin::SuggestAllocatorProperties\n");
415 // pin is already connected
416 return VFW_E_ALREADY_CONNECTED
;
419 CopyMemory(&m_Properties
, pprop
, sizeof(ALLOCATOR_PROPERTIES
));
425 COutputPin::GetAllocatorProperties(
426 ALLOCATOR_PROPERTIES
*pprop
)
429 OutputDebugStringW(L
"COutputPin::GetAllocatorProperties\n");
434 // you should call this method AFTER you connected
438 if (!m_KsAllocatorEx
)
440 // something went wrong while creating the allocator
444 CopyMemory(pprop
, &m_Properties
, sizeof(ALLOCATOR_PROPERTIES
));
448 //-------------------------------------------------------------------
449 // IAMStreamConfig interface
453 COutputPin::SetFormat(
457 OutputDebugStringW(L
"COutputPin::SetFormat NotImplemented\n");
464 COutputPin::GetFormat(AM_MEDIA_TYPE
**ppmt
)
467 OutputDebugStringW(L
"COutputPin::GetFormat NotImplemented\n");
474 COutputPin::GetNumberOfCapabilities(
479 OutputDebugStringW(L
"COutputPin::GetNumberOfCapabilities NotImplemented\n");
486 COutputPin::GetStreamCaps(
488 AM_MEDIA_TYPE
**ppmt
,
492 OutputDebugStringW(L
"COutputPin::GetStreamCaps NotImplemented\n");
497 //-------------------------------------------------------------------
498 // IMemAllocatorNotifyCallbackTemp interface
502 COutputPin::NotifyRelease()
505 OutputDebugStringW(L
"COutputPin::NotifyRelease\n");
508 // notify thread of new available sample
509 SetEvent(m_hBufferAvailable
);
514 //-------------------------------------------------------------------
515 // IMediaSeeking interface
519 COutputPin::GetCapabilities(
520 DWORD
*pCapabilities
)
522 IMediaSeeking
* FilterMediaSeeking
;
525 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
529 hr
= FilterMediaSeeking
->GetCapabilities(pCapabilities
);
531 FilterMediaSeeking
->Release();
537 COutputPin::CheckCapabilities(
538 DWORD
*pCapabilities
)
540 IMediaSeeking
* FilterMediaSeeking
;
543 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
547 hr
= FilterMediaSeeking
->CheckCapabilities(pCapabilities
);
549 FilterMediaSeeking
->Release();
555 COutputPin::IsFormatSupported(
558 IMediaSeeking
* FilterMediaSeeking
;
561 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
565 hr
= FilterMediaSeeking
->IsFormatSupported(pFormat
);
567 FilterMediaSeeking
->Release();
573 COutputPin::QueryPreferredFormat(
576 IMediaSeeking
* FilterMediaSeeking
;
579 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
583 hr
= FilterMediaSeeking
->QueryPreferredFormat(pFormat
);
585 FilterMediaSeeking
->Release();
591 COutputPin::GetTimeFormat(
594 IMediaSeeking
* FilterMediaSeeking
;
597 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
601 hr
= FilterMediaSeeking
->GetTimeFormat(pFormat
);
603 FilterMediaSeeking
->Release();
609 COutputPin::IsUsingTimeFormat(
612 IMediaSeeking
* FilterMediaSeeking
;
615 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
619 hr
= FilterMediaSeeking
->IsUsingTimeFormat(pFormat
);
621 FilterMediaSeeking
->Release();
627 COutputPin::SetTimeFormat(
630 IMediaSeeking
* FilterMediaSeeking
;
633 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
637 hr
= FilterMediaSeeking
->SetTimeFormat(pFormat
);
639 FilterMediaSeeking
->Release();
645 COutputPin::GetDuration(
648 IMediaSeeking
* FilterMediaSeeking
;
651 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
655 hr
= FilterMediaSeeking
->GetDuration(pDuration
);
657 FilterMediaSeeking
->Release();
663 COutputPin::GetStopPosition(
666 IMediaSeeking
* FilterMediaSeeking
;
669 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
673 hr
= FilterMediaSeeking
->GetStopPosition(pStop
);
675 FilterMediaSeeking
->Release();
682 COutputPin::GetCurrentPosition(
685 IMediaSeeking
* FilterMediaSeeking
;
688 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
692 hr
= FilterMediaSeeking
->GetCurrentPosition(pCurrent
);
694 FilterMediaSeeking
->Release();
700 COutputPin::ConvertTimeFormat(
702 const GUID
*pTargetFormat
,
704 const GUID
*pSourceFormat
)
706 IMediaSeeking
* FilterMediaSeeking
;
709 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
713 hr
= FilterMediaSeeking
->ConvertTimeFormat(pTarget
, pTargetFormat
, Source
, pSourceFormat
);
715 FilterMediaSeeking
->Release();
721 COutputPin::SetPositions(
723 DWORD dwCurrentFlags
,
727 IMediaSeeking
* FilterMediaSeeking
;
730 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
734 hr
= FilterMediaSeeking
->SetPositions(pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
736 FilterMediaSeeking
->Release();
742 COutputPin::GetPositions(
746 IMediaSeeking
* FilterMediaSeeking
;
749 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
753 hr
= FilterMediaSeeking
->GetPositions(pCurrent
, pStop
);
755 FilterMediaSeeking
->Release();
761 COutputPin::GetAvailable(
765 IMediaSeeking
* FilterMediaSeeking
;
768 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
772 hr
= FilterMediaSeeking
->GetAvailable(pEarliest
, pLatest
);
774 FilterMediaSeeking
->Release();
783 IMediaSeeking
* FilterMediaSeeking
;
786 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
790 hr
= FilterMediaSeeking
->SetRate(dRate
);
792 FilterMediaSeeking
->Release();
801 IMediaSeeking
* FilterMediaSeeking
;
804 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
808 hr
= FilterMediaSeeking
->GetRate(pdRate
);
810 FilterMediaSeeking
->Release();
816 COutputPin::GetPreroll(
817 LONGLONG
*pllPreroll
)
819 IMediaSeeking
* FilterMediaSeeking
;
822 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
826 hr
= FilterMediaSeeking
->GetPreroll(pllPreroll
);
828 FilterMediaSeeking
->Release();
832 //-------------------------------------------------------------------
833 // IQualityControl interface
842 OutputDebugStringW(L
"COutputPin::Notify NotImplemented\n");
850 IQualityControl
*piqc
)
853 OutputDebugStringW(L
"COutputPin::SetSink NotImplemented\n");
859 //-------------------------------------------------------------------
860 // IKsAggregateControl interface
864 COutputPin::KsAddAggregate(
865 IN REFGUID AggregateClass
)
868 OutputDebugStringW(L
"COutputPin::KsAddAggregate NotImplemented\n");
875 COutputPin::KsRemoveAggregate(
876 REFGUID AggregateClass
)
879 OutputDebugStringW(L
"COutputPin::KsRemoveAggregate NotImplemented\n");
885 //-------------------------------------------------------------------
891 COutputPin::KsQueryMediums(
892 PKSMULTIPLE_ITEM
* MediumList
)
896 IKsObject
* KsObjectParent
;
898 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
900 return E_NOINTERFACE
;
902 hFilter
= KsObjectParent
->KsGetObjectHandle();
905 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_MEDIUMS
, (PVOID
*)MediumList
);
909 KsObjectParent
->Release();
916 COutputPin::KsQueryInterfaces(
917 PKSMULTIPLE_ITEM
* InterfaceList
)
921 IKsObject
* KsObjectParent
;
923 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
927 hFilter
= KsObjectParent
->KsGetObjectHandle();
930 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_INTERFACES
, (PVOID
*)InterfaceList
);
934 KsObjectParent
->Release();
941 COutputPin::KsCreateSinkPinHandle(
942 KSPIN_INTERFACE
& Interface
,
943 KSPIN_MEDIUM
& Medium
)
946 OutputDebugStringW(L
"COutputPin::KsCreateSinkPinHandle NotImplemented\n");
953 COutputPin::KsGetCurrentCommunication(
954 KSPIN_COMMUNICATION
*Communication
,
955 KSPIN_INTERFACE
*Interface
,
956 KSPIN_MEDIUM
*Medium
)
960 *Communication
= m_Communication
;
966 return VFW_E_NOT_CONNECTED
;
968 CopyMemory(Interface
, &m_Interface
, sizeof(KSPIN_INTERFACE
));
974 return VFW_E_NOT_CONNECTED
;
976 CopyMemory(Medium
, &m_Medium
, sizeof(KSPIN_MEDIUM
));
983 COutputPin::KsPropagateAcquire()
991 OutputDebugStringW(L
"COutputPin::KsPropagateAcquire\n");
994 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
996 Property
.Set
= KSPROPSETID_Connection
;
997 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
998 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1000 State
= KSSTATE_ACQUIRE
;
1002 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (LPVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
1009 //propagate to connected pin on the pipe
1016 COutputPin::KsDeliver(
1017 IMediaSample
* Sample
,
1025 COutputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
)
1032 COutputPin::KsPeekAllocator(KSPEEKOPERATION Operation
)
1034 if (Operation
== KsPeekOperation_AddRef
)
1036 // add reference on allocator
1037 m_MemAllocator
->AddRef();
1040 return m_MemAllocator
;
1045 COutputPin::KsReceiveAllocator(IMemAllocator
*MemAllocator
)
1049 MemAllocator
->AddRef();
1054 m_MemAllocator
->Release();
1057 m_MemAllocator
= MemAllocator
;
1063 COutputPin::KsRenegotiateAllocator()
1070 COutputPin::KsIncrementPendingIoCount()
1072 return InterlockedIncrement((volatile LONG
*)&m_IoCount
);
1077 COutputPin::KsDecrementPendingIoCount()
1079 return InterlockedDecrement((volatile LONG
*)&m_IoCount
);
1084 COutputPin::KsQualityNotify(
1086 REFERENCE_TIME TimeDelta
)
1088 #ifdef KSPROXY_TRACE
1089 OutputDebugStringW(L
"COutputPin::KsQualityNotify NotImplemented\n");
1094 //-------------------------------------------------------------------
1100 COutputPin::KsNotifyError(
1101 IMediaSample
* Sample
,
1104 #ifdef KSPROXY_TRACE
1105 OutputDebugStringW(L
"COutputPin::KsNotifyError NotImplemented\n");
1110 //-------------------------------------------------------------------
1116 COutputPin::KsGetPinFramingCache(
1117 PKSALLOCATOR_FRAMING_EX
*FramingEx
,
1118 PFRAMING_PROP FramingProp
,
1119 FRAMING_CACHE_OPS Option
)
1121 if (Option
> Framing_Cache_Write
|| Option
< Framing_Cache_ReadLast
)
1124 return E_INVALIDARG
;
1127 // get framing properties
1128 *FramingProp
= m_FramingProp
[Option
];
1129 *FramingEx
= m_FramingEx
[Option
];
1136 COutputPin::KsSetPinFramingCache(
1137 PKSALLOCATOR_FRAMING_EX FramingEx
,
1138 PFRAMING_PROP FramingProp
,
1139 FRAMING_CACHE_OPS Option
)
1144 if (m_FramingEx
[Option
])
1146 for(Index
= 1; Index
< 4; Index
++)
1148 if (m_FramingEx
[Index
] == m_FramingEx
[Option
])
1154 // existing framing is only used once
1155 CoTaskMemFree(m_FramingEx
[Option
]);
1160 m_FramingEx
[Option
] = FramingEx
;
1161 m_FramingProp
[Option
] = *FramingProp
;
1168 COutputPin::KsGetConnectedPin()
1175 COutputPin::KsGetPipe(
1176 KSPEEKOPERATION Operation
)
1178 if (Operation
== KsPeekOperation_AddRef
)
1180 if (m_KsAllocatorEx
)
1181 m_KsAllocatorEx
->AddRef();
1183 return m_KsAllocatorEx
;
1188 COutputPin::KsSetPipe(
1189 IKsAllocatorEx
*KsAllocator
)
1192 KsAllocator
->AddRef();
1194 if (m_KsAllocatorEx
)
1195 m_KsAllocatorEx
->Release();
1197 m_KsAllocatorEx
= KsAllocator
;
1203 COutputPin::KsGetPipeAllocatorFlag()
1205 return m_PipeAllocatorFlag
;
1211 COutputPin::KsSetPipeAllocatorFlag(
1214 m_PipeAllocatorFlag
= Flag
;
1220 COutputPin::KsGetPinBusCache()
1222 if (!m_bPinBusCacheInitialized
)
1224 CopyMemory(&m_PinBusCache
, &m_Medium
.Set
, sizeof(GUID
));
1225 m_bPinBusCacheInitialized
= TRUE
;
1228 return m_PinBusCache
;
1233 COutputPin::KsSetPinBusCache(
1236 CopyMemory(&m_PinBusCache
, &Bus
, sizeof(GUID
));
1242 COutputPin::KsGetPinName()
1244 return (PWCHAR
)m_PinName
;
1250 COutputPin::KsGetFilterName()
1252 return m_FilterName
;
1255 //-------------------------------------------------------------------
1256 // ISpecifyPropertyPages
1261 COutputPin::GetPages(CAUUID
*pPages
)
1263 #ifdef KSPROXY_TRACE
1264 OutputDebugStringW(L
"COutputPin::GetPages NotImplemented\n");
1271 pPages
->pElems
= NULL
;
1276 //-------------------------------------------------------------------
1282 COutputPin::KsPinFactory(
1285 #ifdef KSPROXY_TRACE
1286 OutputDebugStringW(L
"COutputPin::KsPinFactory\n");
1289 *PinFactory
= m_PinId
;
1294 //-------------------------------------------------------------------
1302 IGraphBuilder
*pGraph
)
1304 #ifdef KSPROXY_TRACE
1305 OutputDebugStringW(L
"COutputPin::Render\n");
1312 COutputPin::Backout(
1314 IGraphBuilder
*pGraph
)
1316 #ifdef KSPROXY_TRACE
1317 OutputDebugStringW(L
"COutputPin::Backout\n");
1322 //-------------------------------------------------------------------
1327 COutputPin::KsGetObjectHandle()
1329 #ifdef KSPROXY_TRACE
1330 OutputDebugStringW(L
"COutputPin::KsGetObjectHandle\n");
1333 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1337 //-------------------------------------------------------------------
1342 COutputPin::KsProperty(
1343 PKSPROPERTY Property
,
1344 ULONG PropertyLength
,
1345 LPVOID PropertyData
,
1347 ULONG
* BytesReturned
)
1351 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1353 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
1354 #ifdef KSPROXY_TRACE
1357 StringFromCLSID(Property
->Set
, &pstr
);
1358 swprintf(Buffer
, L
"COutputPin::KsProperty Set %s Id %lu Flags %x hr %x\n", pstr
, Property
->Id
, Property
->Flags
, hr
);
1359 OutputDebugStringW(Buffer
);
1367 COutputPin::KsMethod(
1372 ULONG
* BytesReturned
)
1374 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1375 #ifdef KSPROXY_TRACE
1376 OutputDebugStringW(L
"COutputPin::KsMethod\n");
1378 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
1383 COutputPin::KsEvent(
1388 ULONG
* BytesReturned
)
1390 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1392 #ifdef KSPROXY_TRACE
1393 OutputDebugStringW(L
"COutputPin::KsEvent\n");
1397 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
1399 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
1403 //-------------------------------------------------------------------
1409 REFGUID guidPropSet
,
1411 LPVOID pInstanceData
,
1412 DWORD cbInstanceData
,
1416 ULONG BytesReturned
;
1420 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1422 return E_OUTOFMEMORY
;
1424 Property
->Set
= guidPropSet
;
1425 Property
->Id
= dwPropID
;
1426 Property
->Flags
= KSPROPERTY_TYPE_SET
;
1428 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1430 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1431 CoTaskMemFree(Property
);
1436 KSPROPERTY Property
;
1438 Property
.Set
= guidPropSet
;
1439 Property
.Id
= dwPropID
;
1440 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1442 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1450 REFGUID guidPropSet
,
1452 LPVOID pInstanceData
,
1453 DWORD cbInstanceData
,
1458 ULONG BytesReturned
;
1462 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1464 return E_OUTOFMEMORY
;
1466 Property
->Set
= guidPropSet
;
1467 Property
->Id
= dwPropID
;
1468 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1470 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1472 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1473 CoTaskMemFree(Property
);
1478 KSPROPERTY Property
;
1480 Property
.Set
= guidPropSet
;
1481 Property
.Id
= dwPropID
;
1482 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1484 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1491 COutputPin::QuerySupported(
1492 REFGUID guidPropSet
,
1494 DWORD
*pTypeSupport
)
1496 KSPROPERTY Property
;
1497 ULONG BytesReturned
;
1499 #ifdef KSPROXY_TRACE
1500 OutputDebugStringW(L
"COutputPin::QuerySupported\n");
1503 Property
.Set
= guidPropSet
;
1504 Property
.Id
= dwPropID
;
1505 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1507 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1511 //-------------------------------------------------------------------
1516 COutputPin::Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
)
1519 ALLOCATOR_PROPERTIES Properties
;
1520 IMemAllocatorCallbackTemp
*pMemCallback
;
1522 #ifdef KSPROXY_TRACE
1524 OutputDebugStringW(L
"COutputPin::Connect called\n");
1529 hr
= pReceivePin
->QueryAccept(pmt
);
1536 hr
= pReceivePin
->QueryAccept(&m_MediaFormat
);
1540 pmt
= &m_MediaFormat
;
1543 // query for IMemInput interface
1544 hr
= pReceivePin
->QueryInterface(IID_IMemInputPin
, (void**)&m_MemInputPin
);
1547 #ifdef KSPROXY_TRACE
1548 OutputDebugStringW(L
"COutputPin::Connect no IMemInputPin interface\n");
1555 // get input pin allocator properties
1556 ZeroMemory(&Properties
, sizeof(ALLOCATOR_PROPERTIES
));
1557 m_MemInputPin
->GetAllocatorRequirements(&Properties
);
1559 //FIXME determine allocator properties
1560 Properties
.cBuffers
= 32;
1561 Properties
.cbBuffer
= 2048 * 188; //2048 frames * MPEG2 TS Payload size
1562 Properties
.cbAlign
= 4;
1564 // get input pin allocator
1566 hr
= m_MemInputPin
->GetAllocator(&m_MemAllocator
);
1569 // set allocator properties
1570 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1572 m_MemAllocator
->Release();
1578 hr
= CKsAllocator_Constructor(NULL
, IID_IMemAllocator
, (void**)&m_MemAllocator
);
1582 // set allocator properties
1583 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1586 #ifdef KSPROXY_TRACE
1587 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::SetProperties failed with hr %lx\n", hr
);
1588 OutputDebugStringW(Buffer
);
1590 m_MemAllocator
->Release();
1591 m_MemInputPin
->Release();
1596 // commit property changes
1597 hr
= m_MemAllocator
->Commit();
1600 #ifdef KSPROXY_TRACE
1601 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::Commit failed with hr %lx\n", hr
);
1602 OutputDebugStringW(Buffer
);
1604 m_MemAllocator
->Release();
1605 m_MemInputPin
->Release();
1609 // get callback interface
1610 hr
= m_MemAllocator
->QueryInterface(IID_IMemAllocatorCallbackTemp
, (void**)&pMemCallback
);
1613 #ifdef KSPROXY_TRACE
1614 swprintf(Buffer
, L
"COutputPin::Connect No IMemAllocatorCallbackTemp interface hr %lx\n", hr
);
1615 OutputDebugStringW(Buffer
);
1617 m_MemAllocator
->Release();
1618 m_MemInputPin
->Release();
1622 // set notification routine
1623 hr
= pMemCallback
->SetNotify((IMemAllocatorNotifyCallbackTemp
*)this);
1625 // release IMemAllocatorNotifyCallbackTemp interface
1626 pMemCallback
->Release();
1630 #ifdef KSPROXY_TRACE
1631 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocatorNotifyCallbackTemp::SetNotify failed hr %lx\n", hr
);
1632 OutputDebugStringW(Buffer
);
1634 m_MemAllocator
->Release();
1635 m_MemInputPin
->Release();
1639 // now set allocator
1640 hr
= m_MemInputPin
->NotifyAllocator(m_MemAllocator
, TRUE
);
1643 #ifdef KSPROXY_TRACE
1644 swprintf(Buffer
, L
"COutputPin::Connect IMemInputPin::NotifyAllocator failed with hr %lx\n", hr
);
1645 OutputDebugStringW(Buffer
);
1647 m_MemAllocator
->Release();
1648 m_MemInputPin
->Release();
1654 //FIXME create pin handle
1658 // receive connection;
1659 hr
= pReceivePin
->ReceiveConnection((IPin
*)this, pmt
);
1662 // increment reference count
1663 pReceivePin
->AddRef();
1664 m_Pin
= pReceivePin
;
1665 #ifdef KSPROXY_TRACE
1666 OutputDebugStringW(L
"COutputPin::Connect success\n");
1671 m_MemInputPin
->Release();
1672 m_MemAllocator
->Release();
1680 COutputPin::ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
)
1682 return E_UNEXPECTED
;
1686 COutputPin::Disconnect( void)
1688 #ifdef KSPROXY_TRACE
1689 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1694 // pin was not connected
1699 //check if filter is active
1703 m_MemInputPin
->Release();
1704 m_MemAllocator
->Release();
1706 CloseHandle(m_hPin
);
1707 m_hPin
= INVALID_HANDLE_VALUE
;
1709 #ifdef KSPROXY_TRACE
1710 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1716 COutputPin::ConnectedTo(IPin
**pPin
)
1718 #ifdef KSPROXY_TRACE
1719 OutputDebugStringW(L
"COutputPin::ConnectedTo\n");
1727 // increment reference count
1734 return VFW_E_NOT_CONNECTED
;
1738 COutputPin::ConnectionMediaType(AM_MEDIA_TYPE
*pmt
)
1740 #ifdef KSPROXY_TRACE
1741 OutputDebugStringW(L
"COutputPin::ConnectionMediaType called\n");
1748 COutputPin::QueryPinInfo(PIN_INFO
*pInfo
)
1750 wcscpy(pInfo
->achName
, m_PinName
);
1751 pInfo
->dir
= PINDIR_OUTPUT
;
1752 pInfo
->pFilter
= m_ParentFilter
;
1753 m_ParentFilter
->AddRef();
1759 COutputPin::QueryDirection(PIN_DIRECTION
*pPinDir
)
1763 *pPinDir
= PINDIR_OUTPUT
;
1771 COutputPin::QueryId(LPWSTR
*Id
)
1773 *Id
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_PinName
)+1)*sizeof(WCHAR
));
1775 return E_OUTOFMEMORY
;
1777 wcscpy(*Id
, m_PinName
);
1782 COutputPin::QueryAccept(const AM_MEDIA_TYPE
*pmt
)
1784 #ifdef KSPROXY_TRACE
1785 OutputDebugStringW(L
"COutputPin::QueryAccept called\n");
1792 COutputPin::EnumMediaTypes(IEnumMediaTypes
**ppEnum
)
1795 ULONG MediaTypeCount
= 0, Index
;
1796 AM_MEDIA_TYPE
* MediaTypes
;
1798 IKsObject
* KsObjectParent
;
1800 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1804 // get parent filter handle
1805 hFilter
= KsObjectParent
->KsGetObjectHandle();
1807 // release IKsObject
1808 KsObjectParent
->Release();
1810 // query media type count
1811 hr
= KsGetMediaTypeCount(hFilter
, m_PinId
, &MediaTypeCount
);
1812 if (FAILED(hr
) || !MediaTypeCount
)
1817 // allocate media types
1818 MediaTypes
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1821 // not enough memory
1822 return E_OUTOFMEMORY
;
1826 ZeroMemory(MediaTypes
, sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1828 for(Index
= 0; Index
< MediaTypeCount
; Index
++)
1831 hr
= KsGetMediaType(Index
, &MediaTypes
[Index
], hFilter
, m_PinId
);
1835 CoTaskMemFree(MediaTypes
);
1840 return CEnumMediaTypes_fnConstructor(MediaTypeCount
, MediaTypes
, IID_IEnumMediaTypes
, (void**)ppEnum
);
1844 COutputPin::QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
)
1850 COutputPin::EndOfStream( void)
1852 /* should be called only on input pins */
1853 return E_UNEXPECTED
;
1857 COutputPin::BeginFlush( void)
1859 /* should be called only on input pins */
1860 return E_UNEXPECTED
;
1864 COutputPin::EndFlush( void)
1866 /* should be called only on input pins */
1867 return E_UNEXPECTED
;
1871 COutputPin::NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
)
1875 // we are not connected
1876 return VFW_E_NOT_CONNECTED
;
1879 return m_Pin
->NewSegment(tStart
, tStop
, dRate
);
1882 //-------------------------------------------------------------------
1885 COutputPin::CheckFormat(
1886 const AM_MEDIA_TYPE
*pmt
)
1888 PKSMULTIPLE_ITEM MultipleItem
;
1889 PKSDATAFORMAT DataFormat
;
1891 IKsObject
* KsObjectParent
;
1897 // get IKsObject interface
1898 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1902 // get parent filter handle
1903 hFilter
= KsObjectParent
->KsGetObjectHandle();
1905 // release IKsObject
1906 KsObjectParent
->Release();
1912 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
1916 DataFormat
= (PKSDATAFORMAT
)(MultipleItem
+ 1);
1917 for(ULONG Index
= 0; Index
< MultipleItem
->Count
; Index
++)
1919 if (IsEqualGUID(pmt
->majortype
, DataFormat
->MajorFormat
) &&
1920 IsEqualGUID(pmt
->subtype
, DataFormat
->SubFormat
) &&
1921 IsEqualGUID(pmt
->formattype
, DataFormat
->Specifier
))
1923 // format is supported
1924 CoTaskMemFree(MultipleItem
);
1927 DataFormat
= (PKSDATAFORMAT
)((ULONG_PTR
)DataFormat
+ DataFormat
->FormatSize
);
1929 //format is not supported
1930 CoTaskMemFree(MultipleItem
);
1936 COutputPin::CreatePin(
1937 const AM_MEDIA_TYPE
*pmt
)
1939 PKSMULTIPLE_ITEM MediumList
;
1940 PKSMULTIPLE_ITEM InterfaceList
;
1941 PKSPIN_MEDIUM Medium
;
1942 PKSPIN_INTERFACE Interface
;
1943 IKsInterfaceHandler
* InterfaceHandler
;
1946 // query for pin medium
1947 hr
= KsQueryMediums(&MediumList
);
1951 // query for pin interface
1952 hr
= KsQueryInterfaces(&InterfaceList
);
1956 CoTaskMemFree(MediumList
);
1960 if (MediumList
->Count
)
1962 //use first available medium
1963 Medium
= (PKSPIN_MEDIUM
)(MediumList
+ 1);
1967 // default to standard medium
1968 Medium
= &StandardPinMedium
;
1971 if (InterfaceList
->Count
)
1973 //use first available interface
1974 Interface
= (PKSPIN_INTERFACE
)(InterfaceList
+ 1);
1978 // default to standard interface
1979 Interface
= &StandardPinInterface
;
1982 if (m_Communication
!= KSPIN_COMMUNICATION_BRIDGE
&& m_Communication
!= KSPIN_COMMUNICATION_NONE
)
1985 hr
= CreatePinHandle(Medium
, Interface
, pmt
);
1988 m_InterfaceHandler
->Release();
1989 m_InterfaceHandler
= InterfaceHandler
;
1992 if (!m_InterfaceHandler
)
1994 // now load the IKsInterfaceHandler plugin
1995 hr
= CoCreateInstance(Interface
->Set
, NULL
, CLSCTX_INPROC_SERVER
, IID_IKsInterfaceHandler
, (void**)&InterfaceHandler
);
1998 // failed to load interface handler plugin
1999 CoTaskMemFree(MediumList
);
2000 CoTaskMemFree(InterfaceList
);
2006 hr
= InterfaceHandler
->KsSetPin((IKsPin
*)this);
2009 // failed to load interface handler plugin
2010 InterfaceHandler
->Release();
2011 CoTaskMemFree(MediumList
);
2012 CoTaskMemFree(InterfaceList
);
2016 // store interface handler
2017 m_InterfaceHandler
= InterfaceHandler
;
2022 #ifdef KSPROXY_TRACE
2024 swprintf(Buffer
, L
"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication
, m_PinName
);
2025 OutputDebugStringW(Buffer
);
2032 // free medium / interface / dataformat
2033 CoTaskMemFree(MediumList
);
2034 CoTaskMemFree(InterfaceList
);
2041 COutputPin::CreatePinHandle(
2042 PKSPIN_MEDIUM Medium
,
2043 PKSPIN_INTERFACE Interface
,
2044 const AM_MEDIA_TYPE
*pmt
)
2046 PKSPIN_CONNECT PinConnect
;
2047 PKSDATAFORMAT DataFormat
;
2051 IKsObject
* KsObjectParent
;
2053 //KSALLOCATOR_FRAMING Framing;
2054 //KSPROPERTY Property;
2055 //ULONG BytesReturned;
2057 if (m_hPin
!= INVALID_HANDLE_VALUE
)
2059 // pin already exists
2060 //CloseHandle(m_hPin);
2061 //m_hPin = INVALID_HANDLE_VALUE;
2067 Length
= sizeof(KSPIN_CONNECT
) + sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
2069 // allocate pin connect
2070 PinConnect
= (PKSPIN_CONNECT
)CoTaskMemAlloc(Length
);
2074 return E_OUTOFMEMORY
;
2078 CopyMemory(&PinConnect
->Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
2079 CopyMemory(&PinConnect
->Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
2080 PinConnect
->PinId
= m_PinId
;
2081 PinConnect
->PinToHandle
= NULL
;
2082 PinConnect
->Priority
.PriorityClass
= KSPRIORITY_NORMAL
;
2083 PinConnect
->Priority
.PrioritySubClass
= KSPRIORITY_NORMAL
;
2085 // get dataformat offset
2086 DataFormat
= (PKSDATAFORMAT
)(PinConnect
+ 1);
2089 DataFormat
->FormatSize
= sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
2090 DataFormat
->Flags
= 0;
2091 DataFormat
->SampleSize
= pmt
->lSampleSize
;
2092 DataFormat
->Reserved
= 0;
2093 CopyMemory(&DataFormat
->MajorFormat
, &pmt
->majortype
, sizeof(GUID
));
2094 CopyMemory(&DataFormat
->SubFormat
, &pmt
->subtype
, sizeof(GUID
));
2095 CopyMemory(&DataFormat
->Specifier
, &pmt
->formattype
, sizeof(GUID
));
2099 // copy extended format
2100 CopyMemory((DataFormat
+ 1), pmt
->pbFormat
, pmt
->cbFormat
);
2103 // get IKsObject interface
2104 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
2108 // get parent filter handle
2109 hFilter
= KsObjectParent
->KsGetObjectHandle();
2111 // release IKsObject
2112 KsObjectParent
->Release();
2118 hr
= KsCreatePin(hFilter
, PinConnect
, GENERIC_READ
, &m_hPin
);
2122 // store current interface / medium
2123 CopyMemory(&m_Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
2124 CopyMemory(&m_Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
2125 CopyMemory(&m_MediaFormat
, pmt
, sizeof(AM_MEDIA_TYPE
));
2127 #ifdef KSPROXY_TRACE
2128 LPOLESTR pMajor
, pSub
, pFormat
;
2129 StringFromIID(m_MediaFormat
.majortype
, &pMajor
);
2130 StringFromIID(m_MediaFormat
.subtype
, &pSub
);
2131 StringFromIID(m_MediaFormat
.formattype
, &pFormat
);
2133 swprintf(Buffer
, L
"COutputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor
, pSub
, pFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
2134 CoTaskMemFree(pMajor
);
2135 CoTaskMemFree(pSub
);
2136 CoTaskMemFree(pFormat
);
2137 OutputDebugStringW(Buffer
);
2142 m_MediaFormat
.pbFormat
= (BYTE
*)CoTaskMemAlloc(pmt
->cbFormat
);
2143 if (!m_MediaFormat
.pbFormat
)
2145 CoTaskMemFree(PinConnect
);
2146 m_MediaFormat
.pbFormat
= NULL
;
2147 m_MediaFormat
.cbFormat
= 0;
2148 return E_OUTOFMEMORY
;
2150 CopyMemory(m_MediaFormat
.pbFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
2153 Property
.Set
= KSPROPSETID_Connection
;
2154 Property
.Id
= KSPROPERTY_CONNECTION_ALLOCATORFRAMING
;
2155 Property
.Flags
= KSPROPERTY_TYPE_GET
;
2157 ZeroMemory(&Framing
, sizeof(KSALLOCATOR_FRAMING
));
2158 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (PVOID
)&Framing
, sizeof(KSALLOCATOR_FRAMING
), &BytesReturned
);
2161 m_Properties
.cbAlign
= (Framing
.FileAlignment
+ 1);
2162 m_Properties
.cbBuffer
= Framing
.FrameSize
;
2163 m_Properties
.cbPrefix
= 0; //FIXME
2164 m_Properties
.cBuffers
= Framing
.Frames
;
2169 if (FAILED(InitializeIOThread()))
2171 OutputDebugStringW(L
"COutputPin::CreatePinHandle failed to initialize i/o thread\n");
2178 // get all supported sets
2179 hr
= GetSupportedSets(&pGuid
, &NumGuids
);
2182 #ifdef KSPROXY_TRACE
2183 OutputDebugStringW(L
"CInputPin::CreatePinHandle GetSupportedSets failed\n");
2188 // load all proxy plugins
2189 hr
= LoadProxyPlugins(pGuid
, NumGuids
);
2192 #ifdef KSPROXY_TRACE
2193 OutputDebugStringW(L
"CInputPin::CreatePinHandle LoadProxyPlugins failed\n");
2199 CoTaskMemFree(pGuid
);
2203 // connect pin pipes
2207 CoTaskMemFree(PinConnect
);
2214 COutputPin::GetSupportedSets(
2218 KSPROPERTY Property
;
2220 ULONG NumProperty
= 0;
2221 ULONG NumMethods
= 0;
2222 ULONG NumEvents
= 0;
2224 ULONG BytesReturned
;
2227 Property
.Set
= GUID_NULL
;
2229 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
2231 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumProperty
);
2232 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumMethods
);
2233 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumEvents
);
2235 Length
= NumProperty
+ NumMethods
+ NumEvents
;
2237 // allocate guid buffer
2238 pGuid
= (LPGUID
)CoTaskMemAlloc(Length
);
2242 return E_OUTOFMEMORY
;
2245 NumProperty
/= sizeof(GUID
);
2246 NumMethods
/= sizeof(GUID
);
2247 NumEvents
/= sizeof(GUID
);
2249 // get all properties
2250 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pGuid
, Length
, &BytesReturned
);
2253 CoTaskMemFree(pGuid
);
2256 Length
-= BytesReturned
;
2261 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
], Length
, &BytesReturned
);
2264 CoTaskMemFree(pGuid
);
2267 Length
-= BytesReturned
;
2273 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
+NumMethods
], Length
, &BytesReturned
);
2276 CoTaskMemFree(pGuid
);
2279 Length
-= BytesReturned
;
2282 #ifdef KSPROXY_TRACE
2284 swprintf(Buffer
, L
"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty
, NumMethods
, NumEvents
);
2285 OutputDebugStringW(Buffer
);
2289 *NumGuids
= NumProperty
+NumEvents
+NumMethods
;
2295 COutputPin::LoadProxyPlugins(
2303 IUnknown
* pUnknown
;
2305 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
2307 OutputDebugStringW(L
"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
2311 // enumerate all sets
2312 for(Index
= 0; Index
< NumGuids
; Index
++)
2314 // convert to string
2315 hr
= StringFromCLSID(pGuids
[Index
], &pStr
);
2319 // now try open class key
2320 if (RegOpenKeyExW(hKey
, pStr
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
2322 // no plugin for that set exists
2323 CoTaskMemFree(pStr
);
2328 hr
= CoCreateInstance(pGuids
[Index
], (IBaseFilter
*)this, CLSCTX_INPROC_SERVER
, IID_IUnknown
, (void**)&pUnknown
);
2332 m_Plugins
.push_back(pUnknown
);
2335 RegCloseKey(hSubKey
);
2338 // close media interfaces key
2346 COutputPin::IoProcessRoutine()
2348 IMediaSample
*Sample
;
2351 PKSSTREAM_SEGMENT StreamSegment
;
2353 IMediaSample
* Samples
[1];
2355 #ifdef KSPROXY_TRACE
2359 // first wait for the start event to signal
2360 WaitForSingleObject(m_hStartEvent
, INFINITE
);
2362 assert(m_InterfaceHandler
);
2365 if (m_StopInProgress
)
2371 assert(m_State
== KSSTATE_RUN
);
2372 assert(m_MemAllocator
);
2375 hr
= m_MemAllocator
->GetBuffer(&Sample
, NULL
, NULL
, AM_GBF_NOWAIT
);
2379 WaitForSingleObject(m_hBufferAvailable
, INFINITE
);
2386 Samples
[0] = Sample
;
2388 Sample
->SetTime(NULL
, NULL
);
2389 hr
= m_InterfaceHandler
->KsProcessMediaSamples(NULL
, /* FIXME */
2394 if (FAILED(hr
) || !StreamSegment
)
2396 #ifdef KSPROXY_TRACE
2397 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine KsProcessMediaSamples FAILED PinName %s hr %lx\n", m_PinName
, hr
);
2398 OutputDebugStringW(Buffer
);
2403 // get completion event
2404 hEvent
= StreamSegment
->CompletionEvent
;
2406 // wait for i/o completion
2407 WaitForSingleObject(hEvent
, INFINITE
);
2409 // perform completion
2410 m_InterfaceHandler
->KsCompleteIo(StreamSegment
);
2412 // close completion event
2413 CloseHandle(hEvent
);
2417 assert(m_MemInputPin
);
2419 // now deliver the sample
2420 hr
= m_MemInputPin
->Receive(Sample
);
2422 #ifdef KSPROXY_TRACE
2423 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName
, hr
, Sample
, m_MemAllocator
);
2424 OutputDebugStringW(Buffer
);
2434 // signal end of i/o thread
2435 SetEvent(m_hStopEvent
);
2437 m_IoThreadStarted
= false;
2444 COutputPin_IoThreadStartup(
2447 COutputPin
* Pin
= (COutputPin
*)lpParameter
;
2450 return Pin
->IoProcessRoutine();
2456 COutputPin::InitializeIOThread()
2460 if (m_IoThreadStarted
)
2464 m_hStartEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2467 return E_OUTOFMEMORY
;
2470 m_hStopEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2473 return E_OUTOFMEMORY
;
2475 if (!m_hBufferAvailable
)
2476 m_hBufferAvailable
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2478 if (!m_hBufferAvailable
)
2479 return E_OUTOFMEMORY
;
2481 m_StopInProgress
= false;
2482 m_IoThreadStarted
= true;
2484 // now create the startup thread
2485 hThread
= CreateThread(NULL
, 0, COutputPin_IoThreadStartup
, (LPVOID
)this, 0, NULL
);
2487 return E_OUTOFMEMORY
;
2490 // close thread handle
2491 CloseHandle(hThread
);
2497 COutputPin_SetState(
2502 KSPROPERTY Property
;
2504 ULONG BytesReturned
;
2505 COutputPin
* pPin
= (COutputPin
*)Pin
;
2507 #ifdef KSPROXY_TRACE
2511 Property
.Set
= KSPROPSETID_Connection
;
2512 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
2513 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2515 EnterCriticalSection(&pPin
->m_Lock
);
2517 if (pPin
->m_State
<= State
)
2519 if (pPin
->m_State
== KSSTATE_STOP
)
2521 hr
= pPin
->InitializeIOThread();
2524 // failed to initialize I/O thread
2525 #ifdef KSPROXY_TRACE
2526 OutputDebugStringW(L
"Failed to initialize I/O Thread\n");
2528 LeaveCriticalSection(&pPin
->m_Lock
);
2531 CurState
= KSSTATE_ACQUIRE
;
2532 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2534 #ifdef KSPROXY_TRACE
2535 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_STOP KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2536 OutputDebugStringW(Buffer
);
2541 LeaveCriticalSection(&pPin
->m_Lock
);
2545 pPin
->m_State
= CurState
;
2547 if (pPin
->m_State
== State
)
2549 LeaveCriticalSection(&pPin
->m_Lock
);
2553 if (pPin
->m_State
== KSSTATE_ACQUIRE
)
2555 CurState
= KSSTATE_PAUSE
;
2556 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2558 #ifdef KSPROXY_TRACE
2559 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState KSSTATE_ACQUIRE KSSTATE_PAUSE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2560 OutputDebugStringW(Buffer
);
2565 LeaveCriticalSection(&pPin
->m_Lock
);
2569 pPin
->m_State
= CurState
;
2571 if (pPin
->m_State
== State
)
2573 LeaveCriticalSection(&pPin
->m_Lock
);
2577 if (State
== KSSTATE_RUN
&& pPin
->m_State
== KSSTATE_PAUSE
)
2579 CurState
= KSSTATE_RUN
;
2580 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2582 #ifdef KSPROXY_TRACE
2583 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_RUN PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2584 OutputDebugStringW(Buffer
);
2589 pPin
->m_State
= CurState
;
2590 // signal start event
2591 SetEvent(pPin
->m_hStartEvent
);
2595 LeaveCriticalSection(&pPin
->m_Lock
);
2600 if (pPin
->m_State
== KSSTATE_RUN
)
2602 // setting pending stop flag
2603 pPin
->m_StopInProgress
= true;
2605 // release any waiting threads
2606 SetEvent(pPin
->m_hBufferAvailable
);
2608 // wait until i/o thread is done
2609 WaitForSingleObject(pPin
->m_hStopEvent
, INFINITE
);
2611 CurState
= KSSTATE_PAUSE
;
2612 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2614 #ifdef KSPROXY_TRACE
2615 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_RUN KSSTATE_PAUSE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2616 OutputDebugStringW(Buffer
);
2621 LeaveCriticalSection(&pPin
->m_Lock
);
2625 pPin
->m_State
= CurState
;
2629 LeaveCriticalSection(&pPin
->m_Lock
);
2633 if (pPin
->m_State
== KSSTATE_PAUSE
)
2635 CurState
= KSSTATE_ACQUIRE
;
2636 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2638 #ifdef KSPROXY_TRACE
2639 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2640 OutputDebugStringW(Buffer
);
2645 LeaveCriticalSection(&pPin
->m_Lock
);
2649 pPin
->m_State
= CurState
;
2651 if (pPin
->m_State
== State
)
2653 LeaveCriticalSection(&pPin
->m_Lock
);
2658 CloseHandle(pPin
->m_hStopEvent
);
2659 CloseHandle(pPin
->m_hStartEvent
);
2660 CloseHandle(pPin
->m_hBufferAvailable
);
2662 /* close event handles */
2663 pPin
->m_hStopEvent
= NULL
;
2664 pPin
->m_hStartEvent
= NULL
;
2665 pPin
->m_hBufferAvailable
= NULL
;
2667 CurState
= KSSTATE_STOP
;
2668 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2670 #ifdef KSPROXY_TRACE
2671 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_ACQUIRE KSSTATE_STOP PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2672 OutputDebugStringW(Buffer
);
2678 pPin
->m_State
= CurState
;
2681 // unset pending stop flag
2682 pPin
->m_StopInProgress
= false;
2684 LeaveCriticalSection(&pPin
->m_Lock
);
2691 COutputPin_Constructor(
2692 IBaseFilter
* ParentFilter
,
2695 KSPIN_COMMUNICATION Communication
,
2699 COutputPin
* handler
= new COutputPin(ParentFilter
, PinName
, PinId
, Communication
);
2702 return E_OUTOFMEMORY
;
2704 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
2708 return E_NOINTERFACE
;