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 extern const GUID IID_IKsPin
;
12 extern const GUID IID_IKsInterfaceHandler
;
14 class COutputPin
: public IPin
,
16 public IKsPropertySet
,
17 public IStreamBuilder
,
19 public ISpecifyPropertyPages
,
23 public IKsAggregateControl
,
24 public IQualityControl
,
26 public IAMBufferNegotiation
,
27 public IAMStreamConfig
,
28 public IMemAllocatorNotifyCallbackTemp
32 typedef std::vector
<IUnknown
*>ProxyPluginVector
;
34 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
36 STDMETHODIMP_(ULONG
) AddRef()
38 InterlockedIncrement(&m_Ref
);
41 STDMETHODIMP_(ULONG
) Release()
43 InterlockedDecrement(&m_Ref
);
53 HRESULT STDMETHODCALLTYPE
KsQueryMediums(PKSMULTIPLE_ITEM
* MediumList
);
54 HRESULT STDMETHODCALLTYPE
KsQueryInterfaces(PKSMULTIPLE_ITEM
* InterfaceList
);
55 HRESULT STDMETHODCALLTYPE
KsCreateSinkPinHandle(KSPIN_INTERFACE
& Interface
, KSPIN_MEDIUM
& Medium
);
56 HRESULT STDMETHODCALLTYPE
KsGetCurrentCommunication(KSPIN_COMMUNICATION
*Communication
, KSPIN_INTERFACE
*Interface
, KSPIN_MEDIUM
*Medium
);
57 HRESULT STDMETHODCALLTYPE
KsPropagateAcquire();
58 HRESULT STDMETHODCALLTYPE
KsDeliver(IMediaSample
* Sample
, ULONG Flags
);
59 HRESULT STDMETHODCALLTYPE
KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
);
60 IMemAllocator
* STDMETHODCALLTYPE
KsPeekAllocator(KSPEEKOPERATION Operation
);
61 HRESULT STDMETHODCALLTYPE
KsReceiveAllocator(IMemAllocator
*MemAllocator
);
62 HRESULT STDMETHODCALLTYPE
KsRenegotiateAllocator();
63 LONG STDMETHODCALLTYPE
KsIncrementPendingIoCount();
64 LONG STDMETHODCALLTYPE
KsDecrementPendingIoCount();
65 HRESULT STDMETHODCALLTYPE
KsQualityNotify(ULONG Proportion
, REFERENCE_TIME TimeDelta
);
67 VOID STDMETHODCALLTYPE
KsNotifyError(IMediaSample
* Sample
, HRESULT hr
);
70 HRESULT STDMETHODCALLTYPE
KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX
*FramingEx
, PFRAMING_PROP FramingProp
, FRAMING_CACHE_OPS Option
);
71 HRESULT STDMETHODCALLTYPE
KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx
, PFRAMING_PROP FramingProp
, FRAMING_CACHE_OPS Option
);
72 IPin
* STDMETHODCALLTYPE
KsGetConnectedPin();
73 IKsAllocatorEx
* STDMETHODCALLTYPE
KsGetPipe(KSPEEKOPERATION Operation
);
74 HRESULT STDMETHODCALLTYPE
KsSetPipe(IKsAllocatorEx
*KsAllocator
);
75 ULONG STDMETHODCALLTYPE
KsGetPipeAllocatorFlag();
76 HRESULT STDMETHODCALLTYPE
KsSetPipeAllocatorFlag(ULONG Flag
);
77 GUID STDMETHODCALLTYPE
KsGetPinBusCache();
78 HRESULT STDMETHODCALLTYPE
KsSetPinBusCache(GUID Bus
);
79 PWCHAR STDMETHODCALLTYPE
KsGetPinName();
80 PWCHAR STDMETHODCALLTYPE
KsGetFilterName();
83 HRESULT STDMETHODCALLTYPE
Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
);
84 HRESULT STDMETHODCALLTYPE
ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
);
85 HRESULT STDMETHODCALLTYPE
Disconnect();
86 HRESULT STDMETHODCALLTYPE
ConnectedTo(IPin
**pPin
);
87 HRESULT STDMETHODCALLTYPE
ConnectionMediaType(AM_MEDIA_TYPE
*pmt
);
88 HRESULT STDMETHODCALLTYPE
QueryPinInfo(PIN_INFO
*pInfo
);
89 HRESULT STDMETHODCALLTYPE
QueryDirection(PIN_DIRECTION
*pPinDir
);
90 HRESULT STDMETHODCALLTYPE
QueryId(LPWSTR
*Id
);
91 HRESULT STDMETHODCALLTYPE
QueryAccept(const AM_MEDIA_TYPE
*pmt
);
92 HRESULT STDMETHODCALLTYPE
EnumMediaTypes(IEnumMediaTypes
**ppEnum
);
93 HRESULT STDMETHODCALLTYPE
QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
);
94 HRESULT STDMETHODCALLTYPE
EndOfStream();
95 HRESULT STDMETHODCALLTYPE
BeginFlush();
96 HRESULT STDMETHODCALLTYPE
EndFlush();
97 HRESULT STDMETHODCALLTYPE
NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
);
99 // ISpecifyPropertyPages
100 HRESULT STDMETHODCALLTYPE
GetPages(CAUUID
*pPages
);
103 HANDLE STDMETHODCALLTYPE
KsGetObjectHandle();
106 HRESULT STDMETHODCALLTYPE
Set(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
);
107 HRESULT STDMETHODCALLTYPE
Get(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
, DWORD
*pcbReturned
);
108 HRESULT STDMETHODCALLTYPE
QuerySupported(REFGUID guidPropSet
, DWORD dwPropID
, DWORD
*pTypeSupport
);
111 HRESULT STDMETHODCALLTYPE
KsProperty(PKSPROPERTY Property
, ULONG PropertyLength
, LPVOID PropertyData
, ULONG DataLength
, ULONG
* BytesReturned
);
112 HRESULT STDMETHODCALLTYPE
KsMethod(PKSMETHOD Method
, ULONG MethodLength
, LPVOID MethodData
, ULONG DataLength
, ULONG
* BytesReturned
);
113 HRESULT STDMETHODCALLTYPE
KsEvent(PKSEVENT Event
, ULONG EventLength
, LPVOID EventData
, ULONG DataLength
, ULONG
* BytesReturned
);
116 HRESULT STDMETHODCALLTYPE
Render(IPin
*ppinOut
, IGraphBuilder
*pGraph
);
117 HRESULT STDMETHODCALLTYPE
Backout(IPin
*ppinOut
, IGraphBuilder
*pGraph
);
120 HRESULT STDMETHODCALLTYPE
KsPinFactory(ULONG
* PinFactory
);
122 //IKsAggregateControl
123 HRESULT STDMETHODCALLTYPE
KsAddAggregate(IN REFGUID AggregateClass
);
124 HRESULT STDMETHODCALLTYPE
KsRemoveAggregate(REFGUID AggregateClass
);
127 HRESULT STDMETHODCALLTYPE
Notify(IBaseFilter
*pSelf
, Quality q
);
128 HRESULT STDMETHODCALLTYPE
SetSink(IQualityControl
*piqc
);
131 HRESULT STDMETHODCALLTYPE
GetCapabilities(DWORD
*pCapabilities
);
132 HRESULT STDMETHODCALLTYPE
CheckCapabilities(DWORD
*pCapabilities
);
133 HRESULT STDMETHODCALLTYPE
IsFormatSupported(const GUID
*pFormat
);
134 HRESULT STDMETHODCALLTYPE
QueryPreferredFormat(GUID
*pFormat
);
135 HRESULT STDMETHODCALLTYPE
GetTimeFormat(GUID
*pFormat
);
136 HRESULT STDMETHODCALLTYPE
IsUsingTimeFormat(const GUID
*pFormat
);
137 HRESULT STDMETHODCALLTYPE
SetTimeFormat(const GUID
*pFormat
);
138 HRESULT STDMETHODCALLTYPE
GetDuration(LONGLONG
*pDuration
);
139 HRESULT STDMETHODCALLTYPE
GetStopPosition(LONGLONG
*pStop
);
140 HRESULT STDMETHODCALLTYPE
GetCurrentPosition(LONGLONG
*pCurrent
);
141 HRESULT STDMETHODCALLTYPE
ConvertTimeFormat(LONGLONG
*pTarget
, const GUID
*pTargetFormat
, LONGLONG Source
, const GUID
*pSourceFormat
);
142 HRESULT STDMETHODCALLTYPE
SetPositions(LONGLONG
*pCurrent
, DWORD dwCurrentFlags
, LONGLONG
*pStop
, DWORD dwStopFlags
);
143 HRESULT STDMETHODCALLTYPE
GetPositions(LONGLONG
*pCurrent
, LONGLONG
*pStop
);
144 HRESULT STDMETHODCALLTYPE
GetAvailable(LONGLONG
*pEarliest
, LONGLONG
*pLatest
);
145 HRESULT STDMETHODCALLTYPE
SetRate(double dRate
);
146 HRESULT STDMETHODCALLTYPE
GetRate(double *pdRate
);
147 HRESULT STDMETHODCALLTYPE
GetPreroll(LONGLONG
*pllPreroll
);
149 //IAMBufferNegotiation
150 HRESULT STDMETHODCALLTYPE
SuggestAllocatorProperties(const ALLOCATOR_PROPERTIES
*pprop
);
151 HRESULT STDMETHODCALLTYPE
GetAllocatorProperties(ALLOCATOR_PROPERTIES
*pprop
);
154 HRESULT STDMETHODCALLTYPE
SetFormat(AM_MEDIA_TYPE
*pmt
);
155 HRESULT STDMETHODCALLTYPE
GetFormat(AM_MEDIA_TYPE
**ppmt
);
156 HRESULT STDMETHODCALLTYPE
GetNumberOfCapabilities(int *piCount
, int *piSize
);
157 HRESULT STDMETHODCALLTYPE
GetStreamCaps(int iIndex
, AM_MEDIA_TYPE
**ppmt
, BYTE
*pSCC
);
159 //IMemAllocatorNotifyCallbackTemp
160 HRESULT STDMETHODCALLTYPE
NotifyRelease();
162 //---------------------------------------------------------------
163 COutputPin(IBaseFilter
* ParentFilter
, LPCWSTR PinName
, ULONG PinId
, KSPIN_COMMUNICATION Communication
);
164 virtual ~COutputPin();
165 HRESULT STDMETHODCALLTYPE
CheckFormat(const AM_MEDIA_TYPE
*pmt
);
166 HRESULT STDMETHODCALLTYPE
CreatePin(const AM_MEDIA_TYPE
*pmt
);
167 HRESULT STDMETHODCALLTYPE
CreatePinHandle(PKSPIN_MEDIUM Medium
, PKSPIN_INTERFACE Interface
, const AM_MEDIA_TYPE
*pmt
);
168 HRESULT WINAPI
IoProcessRoutine();
169 HRESULT WINAPI
InitializeIOThread();
170 HRESULT STDMETHODCALLTYPE
GetSupportedSets(LPGUID
* pOutGuid
, PULONG NumGuids
);
171 HRESULT STDMETHODCALLTYPE
LoadProxyPlugins(LPGUID pGuids
, ULONG NumGuids
);
173 friend DWORD WINAPI
COutputPin_IoThreadStartup(LPVOID lpParameter
);
174 friend HRESULT STDMETHODCALLTYPE
COutputPin_SetState(IPin
* Pin
, KSSTATE State
);
178 IBaseFilter
* m_ParentFilter
;
183 IKsAllocatorEx
* m_KsAllocatorEx
;
184 ULONG m_PipeAllocatorFlag
;
185 BOOL m_bPinBusCacheInitialized
;
188 FRAMING_PROP m_FramingProp
[4];
189 PKSALLOCATOR_FRAMING_EX m_FramingEx
[4];
191 IMemAllocator
* m_MemAllocator
;
192 IMemInputPin
* m_MemInputPin
;
194 KSPIN_COMMUNICATION m_Communication
;
195 KSPIN_INTERFACE m_Interface
;
196 KSPIN_MEDIUM m_Medium
;
197 AM_MEDIA_TYPE m_MediaFormat
;
198 ALLOCATOR_PROPERTIES m_Properties
;
199 IKsInterfaceHandler
* m_InterfaceHandler
;
201 HANDLE m_hStartEvent
;
202 HANDLE m_hBufferAvailable
;
204 BOOL m_StopInProgress
;
205 BOOL m_IoThreadStarted
;
208 CRITICAL_SECTION m_Lock
;
210 ProxyPluginVector m_Plugins
;
213 COutputPin::~COutputPin()
217 COutputPin::COutputPin(
218 IBaseFilter
* ParentFilter
,
221 KSPIN_COMMUNICATION Communication
) : m_Ref(0),
222 m_ParentFilter(ParentFilter
),
224 m_hPin(INVALID_HANDLE_VALUE
),
228 m_PipeAllocatorFlag(0),
229 m_bPinBusCacheInitialized(0),
234 m_Communication(Communication
),
235 m_InterfaceHandler(0),
237 m_hBufferAvailable(0),
240 m_IoThreadStarted(0),
241 m_State(KSSTATE_STOP
),
245 IKsObject
* KsObjectParent
;
247 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
250 ZeroMemory(m_FramingProp
, sizeof(m_FramingProp
));
251 ZeroMemory(m_FramingEx
, sizeof(m_FramingEx
));
252 ZeroMemory(&m_MediaFormat
, sizeof(AM_MEDIA_TYPE
));
254 hr
= KsGetMediaType(0, &m_MediaFormat
, KsObjectParent
->KsGetObjectHandle(), m_PinId
);
258 swprintf(Buffer
, L
"COutputPin::COutputPin Format %p pbFormat %lu\n", &m_MediaFormat
, m_MediaFormat
.cbFormat
);
259 OutputDebugStringW(Buffer
);
264 InitializeCriticalSection(&m_Lock
);
266 KsObjectParent
->Release();
271 COutputPin::QueryInterface(
276 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
277 IsEqualGUID(refiid
, IID_IPin
))
280 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IPin\n");
282 *Output
= PVOID(this);
283 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
286 else if (IsEqualGUID(refiid
, IID_IKsObject
))
288 if (m_hPin
== INVALID_HANDLE_VALUE
)
290 HRESULT hr
= CreatePin(&m_MediaFormat
);
295 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsObject\n");
297 *Output
= (IKsObject
*)(this);
298 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
301 else if (IsEqualGUID(refiid
, IID_IKsPin
) || IsEqualGUID(refiid
, IID_IKsPinEx
))
303 *Output
= (IKsPinEx
*)(this);
304 reinterpret_cast<IKsPinEx
*>(*Output
)->AddRef();
307 else if (IsEqualGUID(refiid
, IID_IKsPinPipe
))
309 *Output
= (IKsPinPipe
*)(this);
310 reinterpret_cast<IKsPinPipe
*>(*Output
)->AddRef();
313 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
315 *Output
= (IKsAggregateControl
*)(this);
316 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
319 else if (IsEqualGUID(refiid
, IID_IQualityControl
))
321 *Output
= (IQualityControl
*)(this);
322 reinterpret_cast<IQualityControl
*>(*Output
)->AddRef();
325 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
327 if (m_hPin
== INVALID_HANDLE_VALUE
)
329 HRESULT hr
= CreatePin(&m_MediaFormat
);
334 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPropertySet\n");
336 *Output
= (IKsPropertySet
*)(this);
337 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
340 else if (IsEqualGUID(refiid
, IID_IKsControl
))
343 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsControl\n");
345 *Output
= (IKsControl
*)(this);
346 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
350 else if (IsEqualGUID(refiid
, IID_IStreamBuilder
))
352 *Output
= (IStreamBuilder
*)(this);
353 reinterpret_cast<IStreamBuilder
*>(*Output
)->AddRef();
357 else if (IsEqualGUID(refiid
, IID_IKsPinFactory
))
360 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPinFactory\n");
362 *Output
= (IKsPinFactory
*)(this);
363 reinterpret_cast<IKsPinFactory
*>(*Output
)->AddRef();
366 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
369 OutputDebugStringW(L
"COutputPin::QueryInterface IID_ISpecifyPropertyPages\n");
371 *Output
= (ISpecifyPropertyPages
*)(this);
372 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
375 else if (IsEqualGUID(refiid
, IID_IMediaSeeking
))
377 *Output
= (IMediaSeeking
*)(this);
378 reinterpret_cast<IMediaSeeking
*>(*Output
)->AddRef();
381 else if (IsEqualGUID(refiid
, IID_IAMBufferNegotiation
))
383 *Output
= (IAMBufferNegotiation
*)(this);
384 reinterpret_cast<IAMBufferNegotiation
*>(*Output
)->AddRef();
387 else if (IsEqualGUID(refiid
, IID_IAMStreamConfig
))
389 *Output
= (IAMStreamConfig
*)(this);
390 reinterpret_cast<IAMStreamConfig
*>(*Output
)->AddRef();
393 else if (IsEqualGUID(refiid
, IID_IMemAllocatorNotifyCallbackTemp
))
395 *Output
= (IMemAllocatorNotifyCallbackTemp
*)(this);
396 reinterpret_cast<IMemAllocatorNotifyCallbackTemp
*>(*Output
)->AddRef();
401 WCHAR Buffer
[MAX_PATH
];
403 StringFromCLSID(refiid
, &lpstr
);
404 swprintf(Buffer
, L
"COutputPin::QueryInterface: NoInterface for %s PinId %u PinName %s\n", lpstr
, m_PinId
, m_PinName
);
405 OutputDebugStringW(Buffer
);
406 CoTaskMemFree(lpstr
);
409 return E_NOINTERFACE
;
412 //-------------------------------------------------------------------
413 // IAMBufferNegotiation interface
417 COutputPin::SuggestAllocatorProperties(
418 const ALLOCATOR_PROPERTIES
*pprop
)
421 OutputDebugStringW(L
"COutputPin::SuggestAllocatorProperties\n");
426 // pin is already connected
427 return VFW_E_ALREADY_CONNECTED
;
430 CopyMemory(&m_Properties
, pprop
, sizeof(ALLOCATOR_PROPERTIES
));
436 COutputPin::GetAllocatorProperties(
437 ALLOCATOR_PROPERTIES
*pprop
)
440 OutputDebugStringW(L
"COutputPin::GetAllocatorProperties\n");
445 // you should call this method AFTER you connected
449 if (!m_KsAllocatorEx
)
451 // something went wrong while creating the allocator
455 CopyMemory(pprop
, &m_Properties
, sizeof(ALLOCATOR_PROPERTIES
));
459 //-------------------------------------------------------------------
460 // IAMStreamConfig interface
464 COutputPin::SetFormat(
468 OutputDebugStringW(L
"COutputPin::SetFormat NotImplemented\n");
475 COutputPin::GetFormat(AM_MEDIA_TYPE
**ppmt
)
478 OutputDebugStringW(L
"COutputPin::GetFormat NotImplemented\n");
485 COutputPin::GetNumberOfCapabilities(
490 OutputDebugStringW(L
"COutputPin::GetNumberOfCapabilities NotImplemented\n");
497 COutputPin::GetStreamCaps(
499 AM_MEDIA_TYPE
**ppmt
,
503 OutputDebugStringW(L
"COutputPin::GetStreamCaps NotImplemented\n");
508 //-------------------------------------------------------------------
509 // IMemAllocatorNotifyCallbackTemp interface
513 COutputPin::NotifyRelease()
516 OutputDebugStringW(L
"COutputPin::NotifyRelease\n");
519 // notify thread of new available sample
520 SetEvent(m_hBufferAvailable
);
525 //-------------------------------------------------------------------
526 // IMediaSeeking interface
530 COutputPin::GetCapabilities(
531 DWORD
*pCapabilities
)
533 IMediaSeeking
* FilterMediaSeeking
;
536 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
540 hr
= FilterMediaSeeking
->GetCapabilities(pCapabilities
);
542 FilterMediaSeeking
->Release();
548 COutputPin::CheckCapabilities(
549 DWORD
*pCapabilities
)
551 IMediaSeeking
* FilterMediaSeeking
;
554 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
558 hr
= FilterMediaSeeking
->CheckCapabilities(pCapabilities
);
560 FilterMediaSeeking
->Release();
566 COutputPin::IsFormatSupported(
569 IMediaSeeking
* FilterMediaSeeking
;
572 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
576 hr
= FilterMediaSeeking
->IsFormatSupported(pFormat
);
578 FilterMediaSeeking
->Release();
584 COutputPin::QueryPreferredFormat(
587 IMediaSeeking
* FilterMediaSeeking
;
590 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
594 hr
= FilterMediaSeeking
->QueryPreferredFormat(pFormat
);
596 FilterMediaSeeking
->Release();
602 COutputPin::GetTimeFormat(
605 IMediaSeeking
* FilterMediaSeeking
;
608 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
612 hr
= FilterMediaSeeking
->GetTimeFormat(pFormat
);
614 FilterMediaSeeking
->Release();
620 COutputPin::IsUsingTimeFormat(
623 IMediaSeeking
* FilterMediaSeeking
;
626 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
630 hr
= FilterMediaSeeking
->IsUsingTimeFormat(pFormat
);
632 FilterMediaSeeking
->Release();
638 COutputPin::SetTimeFormat(
641 IMediaSeeking
* FilterMediaSeeking
;
644 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
648 hr
= FilterMediaSeeking
->SetTimeFormat(pFormat
);
650 FilterMediaSeeking
->Release();
656 COutputPin::GetDuration(
659 IMediaSeeking
* FilterMediaSeeking
;
662 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
666 hr
= FilterMediaSeeking
->GetDuration(pDuration
);
668 FilterMediaSeeking
->Release();
674 COutputPin::GetStopPosition(
677 IMediaSeeking
* FilterMediaSeeking
;
680 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
684 hr
= FilterMediaSeeking
->GetStopPosition(pStop
);
686 FilterMediaSeeking
->Release();
693 COutputPin::GetCurrentPosition(
696 IMediaSeeking
* FilterMediaSeeking
;
699 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
703 hr
= FilterMediaSeeking
->GetCurrentPosition(pCurrent
);
705 FilterMediaSeeking
->Release();
711 COutputPin::ConvertTimeFormat(
713 const GUID
*pTargetFormat
,
715 const GUID
*pSourceFormat
)
717 IMediaSeeking
* FilterMediaSeeking
;
720 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
724 hr
= FilterMediaSeeking
->ConvertTimeFormat(pTarget
, pTargetFormat
, Source
, pSourceFormat
);
726 FilterMediaSeeking
->Release();
732 COutputPin::SetPositions(
734 DWORD dwCurrentFlags
,
738 IMediaSeeking
* FilterMediaSeeking
;
741 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
745 hr
= FilterMediaSeeking
->SetPositions(pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
747 FilterMediaSeeking
->Release();
753 COutputPin::GetPositions(
757 IMediaSeeking
* FilterMediaSeeking
;
760 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
764 hr
= FilterMediaSeeking
->GetPositions(pCurrent
, pStop
);
766 FilterMediaSeeking
->Release();
772 COutputPin::GetAvailable(
776 IMediaSeeking
* FilterMediaSeeking
;
779 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
783 hr
= FilterMediaSeeking
->GetAvailable(pEarliest
, pLatest
);
785 FilterMediaSeeking
->Release();
794 IMediaSeeking
* FilterMediaSeeking
;
797 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
801 hr
= FilterMediaSeeking
->SetRate(dRate
);
803 FilterMediaSeeking
->Release();
812 IMediaSeeking
* FilterMediaSeeking
;
815 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
819 hr
= FilterMediaSeeking
->GetRate(pdRate
);
821 FilterMediaSeeking
->Release();
827 COutputPin::GetPreroll(
828 LONGLONG
*pllPreroll
)
830 IMediaSeeking
* FilterMediaSeeking
;
833 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
837 hr
= FilterMediaSeeking
->GetPreroll(pllPreroll
);
839 FilterMediaSeeking
->Release();
843 //-------------------------------------------------------------------
844 // IQualityControl interface
853 OutputDebugStringW(L
"COutputPin::Notify NotImplemented\n");
861 IQualityControl
*piqc
)
864 OutputDebugStringW(L
"COutputPin::SetSink NotImplemented\n");
870 //-------------------------------------------------------------------
871 // IKsAggregateControl interface
875 COutputPin::KsAddAggregate(
876 IN REFGUID AggregateClass
)
879 OutputDebugStringW(L
"COutputPin::KsAddAggregate NotImplemented\n");
886 COutputPin::KsRemoveAggregate(
887 REFGUID AggregateClass
)
890 OutputDebugStringW(L
"COutputPin::KsRemoveAggregate NotImplemented\n");
896 //-------------------------------------------------------------------
902 COutputPin::KsQueryMediums(
903 PKSMULTIPLE_ITEM
* MediumList
)
907 IKsObject
* KsObjectParent
;
909 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
911 return E_NOINTERFACE
;
913 hFilter
= KsObjectParent
->KsGetObjectHandle();
916 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_MEDIUMS
, (PVOID
*)MediumList
);
920 KsObjectParent
->Release();
927 COutputPin::KsQueryInterfaces(
928 PKSMULTIPLE_ITEM
* InterfaceList
)
932 IKsObject
* KsObjectParent
;
934 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
938 hFilter
= KsObjectParent
->KsGetObjectHandle();
941 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_INTERFACES
, (PVOID
*)InterfaceList
);
945 KsObjectParent
->Release();
952 COutputPin::KsCreateSinkPinHandle(
953 KSPIN_INTERFACE
& Interface
,
954 KSPIN_MEDIUM
& Medium
)
957 OutputDebugStringW(L
"COutputPin::KsCreateSinkPinHandle NotImplemented\n");
964 COutputPin::KsGetCurrentCommunication(
965 KSPIN_COMMUNICATION
*Communication
,
966 KSPIN_INTERFACE
*Interface
,
967 KSPIN_MEDIUM
*Medium
)
971 *Communication
= m_Communication
;
977 return VFW_E_NOT_CONNECTED
;
979 CopyMemory(Interface
, &m_Interface
, sizeof(KSPIN_INTERFACE
));
985 return VFW_E_NOT_CONNECTED
;
987 CopyMemory(Medium
, &m_Medium
, sizeof(KSPIN_MEDIUM
));
994 COutputPin::KsPropagateAcquire()
1001 #ifdef KSPROXY_TRACE
1002 OutputDebugStringW(L
"COutputPin::KsPropagateAcquire\n");
1005 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1007 Property
.Set
= KSPROPSETID_Connection
;
1008 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
1009 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1011 State
= KSSTATE_ACQUIRE
;
1013 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (LPVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
1020 //propagate to connected pin on the pipe
1027 COutputPin::KsDeliver(
1028 IMediaSample
* Sample
,
1036 COutputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
)
1043 COutputPin::KsPeekAllocator(KSPEEKOPERATION Operation
)
1045 if (Operation
== KsPeekOperation_AddRef
)
1047 // add reference on allocator
1048 m_MemAllocator
->AddRef();
1051 return m_MemAllocator
;
1056 COutputPin::KsReceiveAllocator(IMemAllocator
*MemAllocator
)
1060 MemAllocator
->AddRef();
1065 m_MemAllocator
->Release();
1068 m_MemAllocator
= MemAllocator
;
1074 COutputPin::KsRenegotiateAllocator()
1081 COutputPin::KsIncrementPendingIoCount()
1083 return InterlockedIncrement((volatile LONG
*)&m_IoCount
);
1088 COutputPin::KsDecrementPendingIoCount()
1090 return InterlockedDecrement((volatile LONG
*)&m_IoCount
);
1095 COutputPin::KsQualityNotify(
1097 REFERENCE_TIME TimeDelta
)
1099 #ifdef KSPROXY_TRACE
1100 OutputDebugStringW(L
"COutputPin::KsQualityNotify NotImplemented\n");
1105 //-------------------------------------------------------------------
1111 COutputPin::KsNotifyError(
1112 IMediaSample
* Sample
,
1115 #ifdef KSPROXY_TRACE
1116 OutputDebugStringW(L
"COutputPin::KsNotifyError NotImplemented\n");
1121 //-------------------------------------------------------------------
1127 COutputPin::KsGetPinFramingCache(
1128 PKSALLOCATOR_FRAMING_EX
*FramingEx
,
1129 PFRAMING_PROP FramingProp
,
1130 FRAMING_CACHE_OPS Option
)
1132 if (Option
> Framing_Cache_Write
|| Option
< Framing_Cache_ReadLast
)
1135 return E_INVALIDARG
;
1138 // get framing properties
1139 *FramingProp
= m_FramingProp
[Option
];
1140 *FramingEx
= m_FramingEx
[Option
];
1147 COutputPin::KsSetPinFramingCache(
1148 PKSALLOCATOR_FRAMING_EX FramingEx
,
1149 PFRAMING_PROP FramingProp
,
1150 FRAMING_CACHE_OPS Option
)
1155 if (m_FramingEx
[Option
])
1157 for(Index
= 1; Index
< 4; Index
++)
1159 if (m_FramingEx
[Index
] == m_FramingEx
[Option
])
1165 // existing framing is only used once
1166 CoTaskMemFree(m_FramingEx
[Option
]);
1171 m_FramingEx
[Option
] = FramingEx
;
1172 m_FramingProp
[Option
] = *FramingProp
;
1179 COutputPin::KsGetConnectedPin()
1186 COutputPin::KsGetPipe(
1187 KSPEEKOPERATION Operation
)
1189 if (Operation
== KsPeekOperation_AddRef
)
1191 if (m_KsAllocatorEx
)
1192 m_KsAllocatorEx
->AddRef();
1194 return m_KsAllocatorEx
;
1199 COutputPin::KsSetPipe(
1200 IKsAllocatorEx
*KsAllocator
)
1203 KsAllocator
->AddRef();
1205 if (m_KsAllocatorEx
)
1206 m_KsAllocatorEx
->Release();
1208 m_KsAllocatorEx
= KsAllocator
;
1214 COutputPin::KsGetPipeAllocatorFlag()
1216 return m_PipeAllocatorFlag
;
1222 COutputPin::KsSetPipeAllocatorFlag(
1225 m_PipeAllocatorFlag
= Flag
;
1231 COutputPin::KsGetPinBusCache()
1233 if (!m_bPinBusCacheInitialized
)
1235 CopyMemory(&m_PinBusCache
, &m_Medium
.Set
, sizeof(GUID
));
1236 m_bPinBusCacheInitialized
= TRUE
;
1239 return m_PinBusCache
;
1244 COutputPin::KsSetPinBusCache(
1247 CopyMemory(&m_PinBusCache
, &Bus
, sizeof(GUID
));
1253 COutputPin::KsGetPinName()
1255 return (PWCHAR
)m_PinName
;
1261 COutputPin::KsGetFilterName()
1263 return m_FilterName
;
1266 //-------------------------------------------------------------------
1267 // ISpecifyPropertyPages
1272 COutputPin::GetPages(CAUUID
*pPages
)
1274 #ifdef KSPROXY_TRACE
1275 OutputDebugStringW(L
"COutputPin::GetPages NotImplemented\n");
1282 pPages
->pElems
= NULL
;
1287 //-------------------------------------------------------------------
1293 COutputPin::KsPinFactory(
1296 #ifdef KSPROXY_TRACE
1297 OutputDebugStringW(L
"COutputPin::KsPinFactory\n");
1300 *PinFactory
= m_PinId
;
1305 //-------------------------------------------------------------------
1313 IGraphBuilder
*pGraph
)
1315 #ifdef KSPROXY_TRACE
1316 OutputDebugStringW(L
"COutputPin::Render\n");
1323 COutputPin::Backout(
1325 IGraphBuilder
*pGraph
)
1327 #ifdef KSPROXY_TRACE
1328 OutputDebugStringW(L
"COutputPin::Backout\n");
1333 //-------------------------------------------------------------------
1338 COutputPin::KsGetObjectHandle()
1340 #ifdef KSPROXY_TRACE
1341 OutputDebugStringW(L
"COutputPin::KsGetObjectHandle\n");
1344 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1348 //-------------------------------------------------------------------
1353 COutputPin::KsProperty(
1354 PKSPROPERTY Property
,
1355 ULONG PropertyLength
,
1356 LPVOID PropertyData
,
1358 ULONG
* BytesReturned
)
1362 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1364 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
1365 #ifdef KSPROXY_TRACE
1368 StringFromCLSID(Property
->Set
, &pstr
);
1369 swprintf(Buffer
, L
"COutputPin::KsProperty Set %s Id %lu Flags %x hr %x\n", pstr
, Property
->Id
, Property
->Flags
, hr
);
1370 OutputDebugStringW(Buffer
);
1378 COutputPin::KsMethod(
1383 ULONG
* BytesReturned
)
1385 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1386 #ifdef KSPROXY_TRACE
1387 OutputDebugStringW(L
"COutputPin::KsMethod\n");
1389 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
1394 COutputPin::KsEvent(
1399 ULONG
* BytesReturned
)
1401 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1403 #ifdef KSPROXY_TRACE
1404 OutputDebugStringW(L
"COutputPin::KsEvent\n");
1408 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
1410 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
1414 //-------------------------------------------------------------------
1420 REFGUID guidPropSet
,
1422 LPVOID pInstanceData
,
1423 DWORD cbInstanceData
,
1427 ULONG BytesReturned
;
1431 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1433 return E_OUTOFMEMORY
;
1435 Property
->Set
= guidPropSet
;
1436 Property
->Id
= dwPropID
;
1437 Property
->Flags
= KSPROPERTY_TYPE_SET
;
1439 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1441 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1442 CoTaskMemFree(Property
);
1447 KSPROPERTY Property
;
1449 Property
.Set
= guidPropSet
;
1450 Property
.Id
= dwPropID
;
1451 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1453 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1461 REFGUID guidPropSet
,
1463 LPVOID pInstanceData
,
1464 DWORD cbInstanceData
,
1469 ULONG BytesReturned
;
1473 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1475 return E_OUTOFMEMORY
;
1477 Property
->Set
= guidPropSet
;
1478 Property
->Id
= dwPropID
;
1479 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1481 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1483 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1484 CoTaskMemFree(Property
);
1489 KSPROPERTY Property
;
1491 Property
.Set
= guidPropSet
;
1492 Property
.Id
= dwPropID
;
1493 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1495 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1502 COutputPin::QuerySupported(
1503 REFGUID guidPropSet
,
1505 DWORD
*pTypeSupport
)
1507 KSPROPERTY Property
;
1508 ULONG BytesReturned
;
1510 #ifdef KSPROXY_TRACE
1511 OutputDebugStringW(L
"COutputPin::QuerySupported\n");
1514 Property
.Set
= guidPropSet
;
1515 Property
.Id
= dwPropID
;
1516 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1518 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1522 //-------------------------------------------------------------------
1527 COutputPin::Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
)
1530 ALLOCATOR_PROPERTIES Properties
;
1531 IMemAllocatorCallbackTemp
*pMemCallback
;
1535 #ifdef KSPROXY_TRACE
1537 OutputDebugStringW(L
"COutputPin::Connect called\n");
1542 hr
= pReceivePin
->QueryAccept(pmt
);
1549 hr
= pReceivePin
->QueryAccept(&m_MediaFormat
);
1553 pmt
= &m_MediaFormat
;
1556 if (m_hPin
== INVALID_HANDLE_VALUE
)
1558 hr
= CreatePin(pmt
);
1561 #ifdef KSPROXY_TRACE
1562 swprintf(Buffer
, L
"COutputPin::Connect CreatePin handle failed with %lx\n", hr
);
1563 OutputDebugStringW(Buffer
);
1570 // query for IMemInput interface
1571 hr
= pReceivePin
->QueryInterface(IID_IMemInputPin
, (void**)&m_MemInputPin
);
1574 #ifdef KSPROXY_TRACE
1575 OutputDebugStringW(L
"COutputPin::Connect no IMemInputPin interface\n");
1581 // get input pin allocator properties
1582 ZeroMemory(&Properties
, sizeof(ALLOCATOR_PROPERTIES
));
1583 m_MemInputPin
->GetAllocatorRequirements(&Properties
);
1585 //FIXME determine allocator properties
1586 Properties
.cBuffers
= 32;
1587 Properties
.cbBuffer
= 2048 * 188; //2048 frames * MPEG2 TS Payload size
1588 Properties
.cbAlign
= 4;
1590 // get input pin allocator
1592 hr
= m_MemInputPin
->GetAllocator(&m_MemAllocator
);
1595 // set allocator properties
1596 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1598 m_MemAllocator
->Release();
1604 hr
= CKsAllocator_Constructor(NULL
, IID_IMemAllocator
, (void**)&m_MemAllocator
);
1608 // set allocator properties
1609 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1612 #ifdef KSPROXY_TRACE
1613 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::SetProperties failed with hr %lx\n", hr
);
1614 OutputDebugStringW(Buffer
);
1616 m_MemAllocator
->Release();
1617 m_MemInputPin
->Release();
1622 // commit property changes
1623 hr
= m_MemAllocator
->Commit();
1626 #ifdef KSPROXY_TRACE
1627 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::Commit failed with hr %lx\n", hr
);
1628 OutputDebugStringW(Buffer
);
1630 m_MemAllocator
->Release();
1631 m_MemInputPin
->Release();
1635 // get callback interface
1636 hr
= m_MemAllocator
->QueryInterface(IID_IMemAllocatorCallbackTemp
, (void**)&pMemCallback
);
1639 #ifdef KSPROXY_TRACE
1640 swprintf(Buffer
, L
"COutputPin::Connect No IMemAllocatorCallbackTemp interface hr %lx\n", hr
);
1641 OutputDebugStringW(Buffer
);
1643 m_MemAllocator
->Release();
1644 m_MemInputPin
->Release();
1648 // set notification routine
1649 hr
= pMemCallback
->SetNotify((IMemAllocatorNotifyCallbackTemp
*)this);
1651 // release IMemAllocatorNotifyCallbackTemp interface
1652 pMemCallback
->Release();
1656 #ifdef KSPROXY_TRACE
1657 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocatorNotifyCallbackTemp::SetNotify failed hr %lx\n", hr
);
1658 OutputDebugStringW(Buffer
);
1660 m_MemAllocator
->Release();
1661 m_MemInputPin
->Release();
1665 // now set allocator
1666 hr
= m_MemInputPin
->NotifyAllocator(m_MemAllocator
, TRUE
);
1669 #ifdef KSPROXY_TRACE
1670 swprintf(Buffer
, L
"COutputPin::Connect IMemInputPin::NotifyAllocator failed with hr %lx\n", hr
);
1671 OutputDebugStringW(Buffer
);
1673 m_MemAllocator
->Release();
1674 m_MemInputPin
->Release();
1679 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1681 // get all supported sets
1682 if (m_Plugins
.size() == 0)
1684 if (GetSupportedSets(&pGuid
, &NumGuids
))
1686 // load all proxy plugins
1687 if (FAILED(LoadProxyPlugins(pGuid
, NumGuids
)))
1689 #ifdef KSPROXY_TRACE
1690 OutputDebugStringW(L
"COutputPin::Connect LoadProxyPlugins failed\n");
1694 CoTaskMemFree(pGuid
);
1698 // receive connection;
1699 hr
= pReceivePin
->ReceiveConnection((IPin
*)this, pmt
);
1702 // increment reference count
1703 pReceivePin
->AddRef();
1704 m_Pin
= pReceivePin
;
1705 #ifdef KSPROXY_TRACE
1706 OutputDebugStringW(L
"COutputPin::Connect success\n");
1711 m_MemInputPin
->Release();
1712 m_MemAllocator
->Release();
1720 COutputPin::ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
)
1722 return E_UNEXPECTED
;
1726 COutputPin::Disconnect( void)
1728 #ifdef KSPROXY_TRACE
1729 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1734 // pin was not connected
1739 //check if filter is active
1743 m_MemInputPin
->Release();
1744 m_MemAllocator
->Release();
1746 CloseHandle(m_hPin
);
1747 m_hPin
= INVALID_HANDLE_VALUE
;
1749 #ifdef KSPROXY_TRACE
1750 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1756 COutputPin::ConnectedTo(IPin
**pPin
)
1758 #ifdef KSPROXY_TRACE
1759 OutputDebugStringW(L
"COutputPin::ConnectedTo\n");
1767 // increment reference count
1774 return VFW_E_NOT_CONNECTED
;
1778 COutputPin::ConnectionMediaType(AM_MEDIA_TYPE
*pmt
)
1780 #ifdef KSPROXY_TRACE
1781 OutputDebugStringW(L
"COutputPin::ConnectionMediaType called\n");
1788 COutputPin::QueryPinInfo(PIN_INFO
*pInfo
)
1790 wcscpy(pInfo
->achName
, m_PinName
);
1791 pInfo
->dir
= PINDIR_OUTPUT
;
1792 pInfo
->pFilter
= m_ParentFilter
;
1793 m_ParentFilter
->AddRef();
1799 COutputPin::QueryDirection(PIN_DIRECTION
*pPinDir
)
1803 *pPinDir
= PINDIR_OUTPUT
;
1811 COutputPin::QueryId(LPWSTR
*Id
)
1813 *Id
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_PinName
)+1)*sizeof(WCHAR
));
1815 return E_OUTOFMEMORY
;
1817 wcscpy(*Id
, m_PinName
);
1822 COutputPin::QueryAccept(const AM_MEDIA_TYPE
*pmt
)
1824 #ifdef KSPROXY_TRACE
1825 OutputDebugStringW(L
"COutputPin::QueryAccept called\n");
1832 COutputPin::EnumMediaTypes(IEnumMediaTypes
**ppEnum
)
1835 ULONG MediaTypeCount
= 0, Index
;
1836 AM_MEDIA_TYPE
* MediaTypes
;
1838 IKsObject
* KsObjectParent
;
1840 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1844 // get parent filter handle
1845 hFilter
= KsObjectParent
->KsGetObjectHandle();
1847 // release IKsObject
1848 KsObjectParent
->Release();
1850 // query media type count
1851 hr
= KsGetMediaTypeCount(hFilter
, m_PinId
, &MediaTypeCount
);
1852 if (FAILED(hr
) || !MediaTypeCount
)
1857 // allocate media types
1858 MediaTypes
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1861 // not enough memory
1862 return E_OUTOFMEMORY
;
1866 ZeroMemory(MediaTypes
, sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1868 for(Index
= 0; Index
< MediaTypeCount
; Index
++)
1871 hr
= KsGetMediaType(Index
, &MediaTypes
[Index
], hFilter
, m_PinId
);
1875 CoTaskMemFree(MediaTypes
);
1880 return CEnumMediaTypes_fnConstructor(MediaTypeCount
, MediaTypes
, IID_IEnumMediaTypes
, (void**)ppEnum
);
1884 COutputPin::QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
)
1890 COutputPin::EndOfStream( void)
1892 /* should be called only on input pins */
1893 return E_UNEXPECTED
;
1897 COutputPin::BeginFlush( void)
1899 /* should be called only on input pins */
1900 return E_UNEXPECTED
;
1904 COutputPin::EndFlush( void)
1906 /* should be called only on input pins */
1907 return E_UNEXPECTED
;
1911 COutputPin::NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
)
1915 // we are not connected
1916 return VFW_E_NOT_CONNECTED
;
1919 return m_Pin
->NewSegment(tStart
, tStop
, dRate
);
1922 //-------------------------------------------------------------------
1925 COutputPin::CheckFormat(
1926 const AM_MEDIA_TYPE
*pmt
)
1928 PKSMULTIPLE_ITEM MultipleItem
;
1929 PKSDATAFORMAT DataFormat
;
1931 IKsObject
* KsObjectParent
;
1937 // get IKsObject interface
1938 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1942 // get parent filter handle
1943 hFilter
= KsObjectParent
->KsGetObjectHandle();
1945 // release IKsObject
1946 KsObjectParent
->Release();
1952 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
1956 DataFormat
= (PKSDATAFORMAT
)(MultipleItem
+ 1);
1957 for(ULONG Index
= 0; Index
< MultipleItem
->Count
; Index
++)
1959 if (IsEqualGUID(pmt
->majortype
, DataFormat
->MajorFormat
) &&
1960 IsEqualGUID(pmt
->subtype
, DataFormat
->SubFormat
) &&
1961 IsEqualGUID(pmt
->formattype
, DataFormat
->Specifier
))
1963 // format is supported
1964 CoTaskMemFree(MultipleItem
);
1967 DataFormat
= (PKSDATAFORMAT
)((ULONG_PTR
)DataFormat
+ DataFormat
->FormatSize
);
1969 //format is not supported
1970 CoTaskMemFree(MultipleItem
);
1976 COutputPin::CreatePin(
1977 const AM_MEDIA_TYPE
*pmt
)
1979 PKSMULTIPLE_ITEM MediumList
;
1980 PKSMULTIPLE_ITEM InterfaceList
;
1981 PKSPIN_MEDIUM Medium
;
1982 PKSPIN_INTERFACE Interface
;
1983 IKsInterfaceHandler
* InterfaceHandler
;
1986 // query for pin medium
1987 hr
= KsQueryMediums(&MediumList
);
1990 #ifdef KSPROXY_TRACE
1992 swprintf(Buffer
, L
"COutputPin::CreatePin KsQueryMediums failed %lx\n", hr
);
1993 OutputDebugStringW(Buffer
);
1998 // query for pin interface
1999 hr
= KsQueryInterfaces(&InterfaceList
);
2003 #ifdef KSPROXY_TRACE
2005 swprintf(Buffer
, L
"COutputPin::CreatePin KsQueryInterfaces failed %lx\n", hr
);
2006 OutputDebugStringW(Buffer
);
2009 CoTaskMemFree(MediumList
);
2013 if (MediumList
->Count
)
2015 //use first available medium
2016 Medium
= (PKSPIN_MEDIUM
)(MediumList
+ 1);
2020 // default to standard medium
2021 Medium
= &StandardPinMedium
;
2024 if (InterfaceList
->Count
)
2026 //use first available interface
2027 Interface
= (PKSPIN_INTERFACE
)(InterfaceList
+ 1);
2031 // default to standard interface
2032 Interface
= &StandardPinInterface
;
2035 if (m_Communication
!= KSPIN_COMMUNICATION_BRIDGE
&& m_Communication
!= KSPIN_COMMUNICATION_NONE
)
2038 hr
= CreatePinHandle(Medium
, Interface
, pmt
);
2041 #ifdef KSPROXY_TRACE
2043 swprintf(Buffer
, L
"COutputPin::CreatePinHandle failed with %lx\n", hr
);
2044 OutputDebugStringW(Buffer
);
2049 if (!m_InterfaceHandler
)
2051 // now load the IKsInterfaceHandler plugin
2052 hr
= CoCreateInstance(Interface
->Set
, NULL
, CLSCTX_INPROC_SERVER
, IID_IKsInterfaceHandler
, (void**)&InterfaceHandler
);
2055 // failed to load interface handler plugin
2056 CoTaskMemFree(MediumList
);
2057 CoTaskMemFree(InterfaceList
);
2059 #ifdef KSPROXY_TRACE
2061 swprintf(Buffer
, L
"COutputPin::CreatePin failed to create interface handler %lx\n", hr
);
2062 OutputDebugStringW(Buffer
);
2069 hr
= InterfaceHandler
->KsSetPin((IKsPin
*)this);
2072 // failed to initialize interface handler plugin
2073 #ifdef KSPROXY_TRACE
2075 swprintf(Buffer
, L
"COutputPin::CreatePin failed to initialize interface handler %lx\n", hr
);
2076 OutputDebugStringW(Buffer
);
2078 InterfaceHandler
->Release();
2079 CoTaskMemFree(MediumList
);
2080 CoTaskMemFree(InterfaceList
);
2084 // store interface handler
2085 m_InterfaceHandler
= InterfaceHandler
;
2090 #ifdef KSPROXY_TRACE
2092 swprintf(Buffer
, L
"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication
, m_PinName
);
2093 OutputDebugStringW(Buffer
);
2099 // free medium / interface / dataformat
2100 CoTaskMemFree(MediumList
);
2101 CoTaskMemFree(InterfaceList
);
2103 #ifdef KSPROXY_TRACE
2105 swprintf(Buffer
, L
"COutputPin::CreatePin Result %lx\n", hr
);
2106 OutputDebugStringW(Buffer
);
2114 COutputPin::CreatePinHandle(
2115 PKSPIN_MEDIUM Medium
,
2116 PKSPIN_INTERFACE Interface
,
2117 const AM_MEDIA_TYPE
*pmt
)
2119 PKSPIN_CONNECT PinConnect
;
2120 PKSDATAFORMAT DataFormat
;
2124 IKsObject
* KsObjectParent
;
2126 //KSALLOCATOR_FRAMING Framing;
2127 //KSPROPERTY Property;
2128 //ULONG BytesReturned;
2130 OutputDebugStringW(L
"COutputPin::CreatePinHandle\n");
2132 if (m_hPin
!= INVALID_HANDLE_VALUE
)
2134 // pin already exists
2135 //CloseHandle(m_hPin);
2136 //m_hPin = INVALID_HANDLE_VALUE;
2137 OutputDebugStringW(L
"COutputPin::CreatePinHandle pin already exists\n");
2143 Length
= sizeof(KSPIN_CONNECT
) + sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
2145 // allocate pin connect
2146 PinConnect
= (PKSPIN_CONNECT
)CoTaskMemAlloc(Length
);
2150 OutputDebugStringW(L
"COutputPin::CreatePinHandle out of memory\n");
2151 return E_OUTOFMEMORY
;
2153 OutputDebugStringW(L
"COutputPin::CreatePinHandle copy pinconnect\n");
2155 CopyMemory(&PinConnect
->Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
2156 CopyMemory(&PinConnect
->Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
2157 PinConnect
->PinId
= m_PinId
;
2158 PinConnect
->PinToHandle
= NULL
;
2159 PinConnect
->Priority
.PriorityClass
= KSPRIORITY_NORMAL
;
2160 PinConnect
->Priority
.PrioritySubClass
= KSPRIORITY_NORMAL
;
2162 // get dataformat offset
2163 DataFormat
= (PKSDATAFORMAT
)(PinConnect
+ 1);
2164 OutputDebugStringW(L
"COutputPin::CreatePinHandle copy format\n");
2166 DataFormat
->FormatSize
= sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
2167 DataFormat
->Flags
= 0;
2168 DataFormat
->SampleSize
= pmt
->lSampleSize
;
2169 DataFormat
->Reserved
= 0;
2170 CopyMemory(&DataFormat
->MajorFormat
, &pmt
->majortype
, sizeof(GUID
));
2171 CopyMemory(&DataFormat
->SubFormat
, &pmt
->subtype
, sizeof(GUID
));
2172 CopyMemory(&DataFormat
->Specifier
, &pmt
->formattype
, sizeof(GUID
));
2176 // copy extended format
2178 swprintf(Buffer
, L
"COutputPin::CreatePinHandle copy format %p pbFormat %lu\n", pmt
, pmt
->cbFormat
);
2179 OutputDebugStringW(Buffer
);
2180 CopyMemory((DataFormat
+ 1), pmt
->pbFormat
, pmt
->cbFormat
);
2183 // get IKsObject interface
2184 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
2187 OutputDebugStringW(L
"COutputPin::CreatePinHandle no IID_IKsObject interface\n");
2191 // get parent filter handle
2192 hFilter
= KsObjectParent
->KsGetObjectHandle();
2194 // release IKsObject
2195 KsObjectParent
->Release();
2199 OutputDebugStringW(L
"COutputPin::CreatePinHandle no filter handle\n");
2203 OutputDebugStringW(L
"COutputPin::CreatePinHandle before creating pin\n");
2205 DWORD dwError
= KsCreatePin(hFilter
, PinConnect
, GENERIC_READ
, &m_hPin
);
2207 if (dwError
== ERROR_SUCCESS
)
2209 OutputDebugStringW(L
"COutputPin::CreatePinHandle created pin\n");
2211 // store current interface / medium
2212 CopyMemory(&m_Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
2213 CopyMemory(&m_Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
2214 CopyMemory(&m_MediaFormat
, pmt
, sizeof(AM_MEDIA_TYPE
));
2216 #ifdef KSPROXY_TRACE
2217 LPOLESTR pMajor
, pSub
, pFormat
;
2218 StringFromIID(m_MediaFormat
.majortype
, &pMajor
);
2219 StringFromIID(m_MediaFormat
.subtype
, &pSub
);
2220 StringFromIID(m_MediaFormat
.formattype
, &pFormat
);
2222 swprintf(Buffer
, L
"COutputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor
, pSub
, pFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
2223 CoTaskMemFree(pMajor
);
2224 CoTaskMemFree(pSub
);
2225 CoTaskMemFree(pFormat
);
2226 OutputDebugStringW(Buffer
);
2231 m_MediaFormat
.pbFormat
= (BYTE
*)CoTaskMemAlloc(pmt
->cbFormat
);
2232 if (!m_MediaFormat
.pbFormat
)
2234 CoTaskMemFree(PinConnect
);
2235 m_MediaFormat
.pbFormat
= NULL
;
2236 m_MediaFormat
.cbFormat
= 0;
2237 return E_OUTOFMEMORY
;
2239 CopyMemory(m_MediaFormat
.pbFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
2242 Property
.Set
= KSPROPSETID_Connection
;
2243 Property
.Id
= KSPROPERTY_CONNECTION_ALLOCATORFRAMING
;
2244 Property
.Flags
= KSPROPERTY_TYPE_GET
;
2246 ZeroMemory(&Framing
, sizeof(KSALLOCATOR_FRAMING
));
2247 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (PVOID
)&Framing
, sizeof(KSALLOCATOR_FRAMING
), &BytesReturned
);
2250 m_Properties
.cbAlign
= (Framing
.FileAlignment
+ 1);
2251 m_Properties
.cbBuffer
= Framing
.FrameSize
;
2252 m_Properties
.cbPrefix
= 0; //FIXME
2253 m_Properties
.cBuffers
= Framing
.Frames
;
2258 if (FAILED(InitializeIOThread()))
2260 OutputDebugStringW(L
"COutputPin::CreatePinHandle failed to initialize i/o thread\n");
2264 // connect pin pipes
2268 OutputDebugStringW(L
"COutputPin::CreatePinHandle failed to create pin\n");
2270 CoTaskMemFree(PinConnect
);
2277 COutputPin::GetSupportedSets(
2281 KSPROPERTY Property
;
2283 ULONG NumProperty
= 0;
2284 ULONG NumMethods
= 0;
2285 ULONG NumEvents
= 0;
2287 ULONG BytesReturned
;
2290 Property
.Set
= GUID_NULL
;
2292 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
2294 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumProperty
);
2295 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumMethods
);
2296 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumEvents
);
2298 Length
= NumProperty
+ NumMethods
+ NumEvents
;
2302 // allocate guid buffer
2303 pGuid
= (LPGUID
)CoTaskMemAlloc(Length
);
2307 return E_OUTOFMEMORY
;
2310 NumProperty
/= sizeof(GUID
);
2311 NumMethods
/= sizeof(GUID
);
2312 NumEvents
/= sizeof(GUID
);
2314 // get all properties
2315 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pGuid
, Length
, &BytesReturned
);
2318 CoTaskMemFree(pGuid
);
2321 Length
-= BytesReturned
;
2324 if (Length
&& NumMethods
)
2326 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
], Length
, &BytesReturned
);
2329 CoTaskMemFree(pGuid
);
2332 Length
-= BytesReturned
;
2336 if (Length
&& NumEvents
)
2338 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
+NumMethods
], Length
, &BytesReturned
);
2341 CoTaskMemFree(pGuid
);
2344 Length
-= BytesReturned
;
2347 #ifdef KSPROXY_TRACE
2349 swprintf(Buffer
, L
"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty
, NumMethods
, NumEvents
);
2350 OutputDebugStringW(Buffer
);
2354 *NumGuids
= NumProperty
+NumEvents
+NumMethods
;
2360 COutputPin::LoadProxyPlugins(
2368 IUnknown
* pUnknown
;
2370 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
2372 OutputDebugStringW(L
"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
2376 // enumerate all sets
2377 for(Index
= 0; Index
< NumGuids
; Index
++)
2379 // convert to string
2380 hr
= StringFromCLSID(pGuids
[Index
], &pStr
);
2384 // now try open class key
2385 if (RegOpenKeyExW(hKey
, pStr
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
2387 // no plugin for that set exists
2388 CoTaskMemFree(pStr
);
2393 hr
= CoCreateInstance(pGuids
[Index
], (IBaseFilter
*)this, CLSCTX_INPROC_SERVER
, IID_IUnknown
, (void**)&pUnknown
);
2397 m_Plugins
.push_back(pUnknown
);
2400 RegCloseKey(hSubKey
);
2403 // close media interfaces key
2411 COutputPin::IoProcessRoutine()
2413 IMediaSample
*Sample
;
2416 PKSSTREAM_SEGMENT
* StreamSegment
;
2418 IMediaSample
** Samples
;
2422 #ifdef KSPROXY_TRACE
2426 NumHandles
= m_Properties
.cBuffers
/ 2;
2433 //allocate stream segment array
2434 StreamSegment
= (PKSSTREAM_SEGMENT
*)CoTaskMemAlloc(sizeof(PKSSTREAM_SEGMENT
) * NumHandles
);
2437 OutputDebugStringW(L
"COutputPin::IoProcessRoutine out of memory\n");
2441 // allocate handle array
2442 Samples
= (IMediaSample
**)CoTaskMemAlloc(sizeof(IMediaSample
*) * NumHandles
);
2445 OutputDebugStringW(L
"COutputPin::IoProcessRoutine out of memory\n");
2449 // zero handles array
2450 ZeroMemory(StreamSegment
, sizeof(PKSSTREAM_SEGMENT
) * NumHandles
);
2451 ZeroMemory(Samples
, sizeof(IMediaSample
*) * NumHandles
);
2453 // first wait for the start event to signal
2454 WaitForSingleObject(m_hStartEvent
, INFINITE
);
2458 assert(m_InterfaceHandler
);
2461 if (m_StopInProgress
)
2467 assert(m_State
== KSSTATE_RUN
);
2468 assert(m_MemAllocator
);
2471 hr
= m_MemAllocator
->GetBuffer(&Sample
, NULL
, NULL
, AM_GBF_NOWAIT
);
2475 WaitForSingleObject(m_hBufferAvailable
, INFINITE
);
2482 Samples
[m_IoCount
] = Sample
;
2484 Sample
->SetTime(NULL
, NULL
);
2485 hr
= m_InterfaceHandler
->KsProcessMediaSamples(NULL
, /* FIXME */
2486 &Samples
[m_IoCount
],
2489 &StreamSegment
[m_IoCount
]);
2490 if (FAILED(hr
) || !StreamSegment
)
2492 #ifdef KSPROXY_TRACE
2493 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine KsProcessMediaSamples FAILED PinName %s hr %lx\n", m_PinName
, hr
);
2494 OutputDebugStringW(Buffer
);
2499 // interface handle should increment pending i/o count
2500 assert(m_IoCount
>= 1);
2502 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine m_IoCount %lu NumHandles %lu\n", m_IoCount
, NumHandles
);
2503 OutputDebugStringW(Buffer
);
2505 if (m_IoCount
!= NumHandles
)
2508 // get completion handle
2509 hEvent
= StreamSegment
[0]->CompletionEvent
;
2511 // wait for i/o completion
2512 dwStatus
= WaitForSingleObject(hEvent
, INFINITE
);
2514 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine dwStatus %lx Error %lx NumHandles %lu\n", dwStatus
, GetLastError(), NumHandles
);
2515 OutputDebugStringW(Buffer
);
2517 // perform completion
2518 m_InterfaceHandler
->KsCompleteIo(StreamSegment
[0]);
2520 // close completion event
2521 CloseHandle(hEvent
);
2525 assert(m_MemInputPin
);
2527 // now deliver the sample
2528 hr
= m_MemInputPin
->Receive(Samples
[0]);
2530 #ifdef KSPROXY_TRACE
2531 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName
, hr
, Sample
, m_MemAllocator
);
2532 OutputDebugStringW(Buffer
);
2541 //circular stream segment array
2542 RtlMoveMemory(StreamSegment
, &StreamSegment
[1], sizeof(PKSSTREAM_SEGMENT
) * (NumHandles
- 1));
2543 RtlMoveMemory(Samples
, &Samples
[1], sizeof(IMediaSample
*) * (NumHandles
- 1));
2547 // signal end of i/o thread
2548 SetEvent(m_hStopEvent
);
2550 m_IoThreadStarted
= false;
2557 COutputPin_IoThreadStartup(
2560 COutputPin
* Pin
= (COutputPin
*)lpParameter
;
2563 return Pin
->IoProcessRoutine();
2569 COutputPin::InitializeIOThread()
2573 if (m_IoThreadStarted
)
2577 m_hStartEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2580 return E_OUTOFMEMORY
;
2583 m_hStopEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2586 return E_OUTOFMEMORY
;
2588 if (!m_hBufferAvailable
)
2589 m_hBufferAvailable
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2591 if (!m_hBufferAvailable
)
2592 return E_OUTOFMEMORY
;
2594 m_StopInProgress
= false;
2595 m_IoThreadStarted
= true;
2597 // now create the startup thread
2598 hThread
= CreateThread(NULL
, 0, COutputPin_IoThreadStartup
, (LPVOID
)this, 0, NULL
);
2600 return E_OUTOFMEMORY
;
2603 // close thread handle
2604 CloseHandle(hThread
);
2610 COutputPin_SetState(
2615 KSPROPERTY Property
;
2617 ULONG BytesReturned
;
2618 COutputPin
* pPin
= (COutputPin
*)Pin
;
2620 #ifdef KSPROXY_TRACE
2624 Property
.Set
= KSPROPSETID_Connection
;
2625 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
2626 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2628 EnterCriticalSection(&pPin
->m_Lock
);
2630 if (pPin
->m_State
<= State
)
2632 if (pPin
->m_State
== KSSTATE_STOP
)
2634 hr
= pPin
->InitializeIOThread();
2637 // failed to initialize I/O thread
2638 #ifdef KSPROXY_TRACE
2639 OutputDebugStringW(L
"Failed to initialize I/O Thread\n");
2641 LeaveCriticalSection(&pPin
->m_Lock
);
2644 CurState
= KSSTATE_ACQUIRE
;
2645 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2647 #ifdef KSPROXY_TRACE
2648 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_STOP KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2649 OutputDebugStringW(Buffer
);
2654 LeaveCriticalSection(&pPin
->m_Lock
);
2658 pPin
->m_State
= CurState
;
2660 if (pPin
->m_State
== State
)
2662 LeaveCriticalSection(&pPin
->m_Lock
);
2666 if (pPin
->m_State
== KSSTATE_ACQUIRE
)
2668 CurState
= KSSTATE_PAUSE
;
2669 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2671 #ifdef KSPROXY_TRACE
2672 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState KSSTATE_ACQUIRE KSSTATE_PAUSE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2673 OutputDebugStringW(Buffer
);
2678 LeaveCriticalSection(&pPin
->m_Lock
);
2682 pPin
->m_State
= CurState
;
2684 if (pPin
->m_State
== State
)
2686 LeaveCriticalSection(&pPin
->m_Lock
);
2690 if (State
== KSSTATE_RUN
&& pPin
->m_State
== KSSTATE_PAUSE
)
2692 CurState
= KSSTATE_RUN
;
2693 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2695 #ifdef KSPROXY_TRACE
2696 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_RUN PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2697 OutputDebugStringW(Buffer
);
2702 pPin
->m_State
= CurState
;
2703 // signal start event
2704 SetEvent(pPin
->m_hStartEvent
);
2708 LeaveCriticalSection(&pPin
->m_Lock
);
2713 if (pPin
->m_State
== KSSTATE_RUN
)
2715 // setting pending stop flag
2716 pPin
->m_StopInProgress
= true;
2718 // release any waiting threads
2719 SetEvent(pPin
->m_hBufferAvailable
);
2721 // wait until i/o thread is done
2722 WaitForSingleObject(pPin
->m_hStopEvent
, INFINITE
);
2724 CurState
= KSSTATE_PAUSE
;
2725 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2727 #ifdef KSPROXY_TRACE
2728 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_RUN KSSTATE_PAUSE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2729 OutputDebugStringW(Buffer
);
2734 LeaveCriticalSection(&pPin
->m_Lock
);
2738 pPin
->m_State
= CurState
;
2742 LeaveCriticalSection(&pPin
->m_Lock
);
2746 if (pPin
->m_State
== KSSTATE_PAUSE
)
2748 CurState
= KSSTATE_ACQUIRE
;
2749 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2751 #ifdef KSPROXY_TRACE
2752 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2753 OutputDebugStringW(Buffer
);
2758 LeaveCriticalSection(&pPin
->m_Lock
);
2762 pPin
->m_State
= CurState
;
2764 if (pPin
->m_State
== State
)
2766 LeaveCriticalSection(&pPin
->m_Lock
);
2771 CloseHandle(pPin
->m_hStopEvent
);
2772 CloseHandle(pPin
->m_hStartEvent
);
2773 CloseHandle(pPin
->m_hBufferAvailable
);
2775 /* close event handles */
2776 pPin
->m_hStopEvent
= NULL
;
2777 pPin
->m_hStartEvent
= NULL
;
2778 pPin
->m_hBufferAvailable
= NULL
;
2780 CurState
= KSSTATE_STOP
;
2781 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2783 #ifdef KSPROXY_TRACE
2784 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_ACQUIRE KSSTATE_STOP PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2785 OutputDebugStringW(Buffer
);
2791 pPin
->m_State
= CurState
;
2794 // unset pending stop flag
2795 pPin
->m_StopInProgress
= false;
2797 LeaveCriticalSection(&pPin
->m_Lock
);
2804 COutputPin_Constructor(
2805 IBaseFilter
* ParentFilter
,
2808 KSPIN_COMMUNICATION Communication
,
2812 COutputPin
* handler
= new COutputPin(ParentFilter
, PinName
, PinId
, Communication
);
2815 return E_OUTOFMEMORY
;
2817 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
2821 return E_NOINTERFACE
;