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
));
249 ZeroMemory(&m_MediaFormat
, sizeof(AM_MEDIA_TYPE
));
251 hr
= KsGetMediaType(0, &m_MediaFormat
, KsObjectParent
->KsGetObjectHandle(), m_PinId
);
255 swprintf(Buffer
, L
"COutputPin::COutputPin Format %p pbFormat %lu\n", &m_MediaFormat
, m_MediaFormat
.cbFormat
);
256 OutputDebugStringW(Buffer
);
261 InitializeCriticalSection(&m_Lock
);
263 KsObjectParent
->Release();
268 COutputPin::QueryInterface(
273 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
274 IsEqualGUID(refiid
, IID_IPin
))
277 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IPin\n");
279 *Output
= PVOID(this);
280 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
283 else if (IsEqualGUID(refiid
, IID_IKsObject
))
285 if (m_hPin
== INVALID_HANDLE_VALUE
)
287 HRESULT hr
= CreatePin(&m_MediaFormat
);
292 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsObject\n");
294 *Output
= (IKsObject
*)(this);
295 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
298 else if (IsEqualGUID(refiid
, IID_IKsPin
) || IsEqualGUID(refiid
, IID_IKsPinEx
))
300 *Output
= (IKsPinEx
*)(this);
301 reinterpret_cast<IKsPinEx
*>(*Output
)->AddRef();
304 else if (IsEqualGUID(refiid
, IID_IKsPinPipe
))
306 *Output
= (IKsPinPipe
*)(this);
307 reinterpret_cast<IKsPinPipe
*>(*Output
)->AddRef();
310 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
312 *Output
= (IKsAggregateControl
*)(this);
313 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
316 else if (IsEqualGUID(refiid
, IID_IQualityControl
))
318 *Output
= (IQualityControl
*)(this);
319 reinterpret_cast<IQualityControl
*>(*Output
)->AddRef();
322 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
324 if (m_hPin
== INVALID_HANDLE_VALUE
)
326 HRESULT hr
= CreatePin(&m_MediaFormat
);
331 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPropertySet\n");
333 *Output
= (IKsPropertySet
*)(this);
334 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
337 else if (IsEqualGUID(refiid
, IID_IKsControl
))
340 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsControl\n");
342 *Output
= (IKsControl
*)(this);
343 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
347 else if (IsEqualGUID(refiid
, IID_IStreamBuilder
))
349 *Output
= (IStreamBuilder
*)(this);
350 reinterpret_cast<IStreamBuilder
*>(*Output
)->AddRef();
354 else if (IsEqualGUID(refiid
, IID_IKsPinFactory
))
357 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPinFactory\n");
359 *Output
= (IKsPinFactory
*)(this);
360 reinterpret_cast<IKsPinFactory
*>(*Output
)->AddRef();
363 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
366 OutputDebugStringW(L
"COutputPin::QueryInterface IID_ISpecifyPropertyPages\n");
368 *Output
= (ISpecifyPropertyPages
*)(this);
369 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
372 else if (IsEqualGUID(refiid
, IID_IMediaSeeking
))
374 *Output
= (IMediaSeeking
*)(this);
375 reinterpret_cast<IMediaSeeking
*>(*Output
)->AddRef();
378 else if (IsEqualGUID(refiid
, IID_IAMBufferNegotiation
))
380 *Output
= (IAMBufferNegotiation
*)(this);
381 reinterpret_cast<IAMBufferNegotiation
*>(*Output
)->AddRef();
384 else if (IsEqualGUID(refiid
, IID_IAMStreamConfig
))
386 *Output
= (IAMStreamConfig
*)(this);
387 reinterpret_cast<IAMStreamConfig
*>(*Output
)->AddRef();
390 else if (IsEqualGUID(refiid
, IID_IMemAllocatorNotifyCallbackTemp
))
392 *Output
= (IMemAllocatorNotifyCallbackTemp
*)(this);
393 reinterpret_cast<IMemAllocatorNotifyCallbackTemp
*>(*Output
)->AddRef();
398 WCHAR Buffer
[MAX_PATH
];
400 StringFromCLSID(refiid
, &lpstr
);
401 swprintf(Buffer
, L
"COutputPin::QueryInterface: NoInterface for %s PinId %u PinName %s\n", lpstr
, m_PinId
, m_PinName
);
402 OutputDebugStringW(Buffer
);
403 CoTaskMemFree(lpstr
);
406 return E_NOINTERFACE
;
409 //-------------------------------------------------------------------
410 // IAMBufferNegotiation interface
414 COutputPin::SuggestAllocatorProperties(
415 const ALLOCATOR_PROPERTIES
*pprop
)
418 OutputDebugStringW(L
"COutputPin::SuggestAllocatorProperties\n");
423 // pin is already connected
424 return VFW_E_ALREADY_CONNECTED
;
427 CopyMemory(&m_Properties
, pprop
, sizeof(ALLOCATOR_PROPERTIES
));
433 COutputPin::GetAllocatorProperties(
434 ALLOCATOR_PROPERTIES
*pprop
)
437 OutputDebugStringW(L
"COutputPin::GetAllocatorProperties\n");
442 // you should call this method AFTER you connected
446 if (!m_KsAllocatorEx
)
448 // something went wrong while creating the allocator
452 CopyMemory(pprop
, &m_Properties
, sizeof(ALLOCATOR_PROPERTIES
));
456 //-------------------------------------------------------------------
457 // IAMStreamConfig interface
461 COutputPin::SetFormat(
465 OutputDebugStringW(L
"COutputPin::SetFormat NotImplemented\n");
472 COutputPin::GetFormat(AM_MEDIA_TYPE
**ppmt
)
475 OutputDebugStringW(L
"COutputPin::GetFormat NotImplemented\n");
482 COutputPin::GetNumberOfCapabilities(
487 OutputDebugStringW(L
"COutputPin::GetNumberOfCapabilities NotImplemented\n");
494 COutputPin::GetStreamCaps(
496 AM_MEDIA_TYPE
**ppmt
,
500 OutputDebugStringW(L
"COutputPin::GetStreamCaps NotImplemented\n");
505 //-------------------------------------------------------------------
506 // IMemAllocatorNotifyCallbackTemp interface
510 COutputPin::NotifyRelease()
513 OutputDebugStringW(L
"COutputPin::NotifyRelease\n");
516 // notify thread of new available sample
517 SetEvent(m_hBufferAvailable
);
522 //-------------------------------------------------------------------
523 // IMediaSeeking interface
527 COutputPin::GetCapabilities(
528 DWORD
*pCapabilities
)
530 IMediaSeeking
* FilterMediaSeeking
;
533 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
537 hr
= FilterMediaSeeking
->GetCapabilities(pCapabilities
);
539 FilterMediaSeeking
->Release();
545 COutputPin::CheckCapabilities(
546 DWORD
*pCapabilities
)
548 IMediaSeeking
* FilterMediaSeeking
;
551 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
555 hr
= FilterMediaSeeking
->CheckCapabilities(pCapabilities
);
557 FilterMediaSeeking
->Release();
563 COutputPin::IsFormatSupported(
566 IMediaSeeking
* FilterMediaSeeking
;
569 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
573 hr
= FilterMediaSeeking
->IsFormatSupported(pFormat
);
575 FilterMediaSeeking
->Release();
581 COutputPin::QueryPreferredFormat(
584 IMediaSeeking
* FilterMediaSeeking
;
587 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
591 hr
= FilterMediaSeeking
->QueryPreferredFormat(pFormat
);
593 FilterMediaSeeking
->Release();
599 COutputPin::GetTimeFormat(
602 IMediaSeeking
* FilterMediaSeeking
;
605 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
609 hr
= FilterMediaSeeking
->GetTimeFormat(pFormat
);
611 FilterMediaSeeking
->Release();
617 COutputPin::IsUsingTimeFormat(
620 IMediaSeeking
* FilterMediaSeeking
;
623 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
627 hr
= FilterMediaSeeking
->IsUsingTimeFormat(pFormat
);
629 FilterMediaSeeking
->Release();
635 COutputPin::SetTimeFormat(
638 IMediaSeeking
* FilterMediaSeeking
;
641 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
645 hr
= FilterMediaSeeking
->SetTimeFormat(pFormat
);
647 FilterMediaSeeking
->Release();
653 COutputPin::GetDuration(
656 IMediaSeeking
* FilterMediaSeeking
;
659 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
663 hr
= FilterMediaSeeking
->GetDuration(pDuration
);
665 FilterMediaSeeking
->Release();
671 COutputPin::GetStopPosition(
674 IMediaSeeking
* FilterMediaSeeking
;
677 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
681 hr
= FilterMediaSeeking
->GetStopPosition(pStop
);
683 FilterMediaSeeking
->Release();
690 COutputPin::GetCurrentPosition(
693 IMediaSeeking
* FilterMediaSeeking
;
696 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
700 hr
= FilterMediaSeeking
->GetCurrentPosition(pCurrent
);
702 FilterMediaSeeking
->Release();
708 COutputPin::ConvertTimeFormat(
710 const GUID
*pTargetFormat
,
712 const GUID
*pSourceFormat
)
714 IMediaSeeking
* FilterMediaSeeking
;
717 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
721 hr
= FilterMediaSeeking
->ConvertTimeFormat(pTarget
, pTargetFormat
, Source
, pSourceFormat
);
723 FilterMediaSeeking
->Release();
729 COutputPin::SetPositions(
731 DWORD dwCurrentFlags
,
735 IMediaSeeking
* FilterMediaSeeking
;
738 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
742 hr
= FilterMediaSeeking
->SetPositions(pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
744 FilterMediaSeeking
->Release();
750 COutputPin::GetPositions(
754 IMediaSeeking
* FilterMediaSeeking
;
757 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
761 hr
= FilterMediaSeeking
->GetPositions(pCurrent
, pStop
);
763 FilterMediaSeeking
->Release();
769 COutputPin::GetAvailable(
773 IMediaSeeking
* FilterMediaSeeking
;
776 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
780 hr
= FilterMediaSeeking
->GetAvailable(pEarliest
, pLatest
);
782 FilterMediaSeeking
->Release();
791 IMediaSeeking
* FilterMediaSeeking
;
794 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
798 hr
= FilterMediaSeeking
->SetRate(dRate
);
800 FilterMediaSeeking
->Release();
809 IMediaSeeking
* FilterMediaSeeking
;
812 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
816 hr
= FilterMediaSeeking
->GetRate(pdRate
);
818 FilterMediaSeeking
->Release();
824 COutputPin::GetPreroll(
825 LONGLONG
*pllPreroll
)
827 IMediaSeeking
* FilterMediaSeeking
;
830 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
834 hr
= FilterMediaSeeking
->GetPreroll(pllPreroll
);
836 FilterMediaSeeking
->Release();
840 //-------------------------------------------------------------------
841 // IQualityControl interface
850 OutputDebugStringW(L
"COutputPin::Notify NotImplemented\n");
858 IQualityControl
*piqc
)
861 OutputDebugStringW(L
"COutputPin::SetSink NotImplemented\n");
867 //-------------------------------------------------------------------
868 // IKsAggregateControl interface
872 COutputPin::KsAddAggregate(
873 IN REFGUID AggregateClass
)
876 OutputDebugStringW(L
"COutputPin::KsAddAggregate NotImplemented\n");
883 COutputPin::KsRemoveAggregate(
884 REFGUID AggregateClass
)
887 OutputDebugStringW(L
"COutputPin::KsRemoveAggregate NotImplemented\n");
893 //-------------------------------------------------------------------
899 COutputPin::KsQueryMediums(
900 PKSMULTIPLE_ITEM
* MediumList
)
904 IKsObject
* KsObjectParent
;
906 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
908 return E_NOINTERFACE
;
910 hFilter
= KsObjectParent
->KsGetObjectHandle();
913 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_MEDIUMS
, (PVOID
*)MediumList
);
917 KsObjectParent
->Release();
924 COutputPin::KsQueryInterfaces(
925 PKSMULTIPLE_ITEM
* InterfaceList
)
929 IKsObject
* KsObjectParent
;
931 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
935 hFilter
= KsObjectParent
->KsGetObjectHandle();
938 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_INTERFACES
, (PVOID
*)InterfaceList
);
942 KsObjectParent
->Release();
949 COutputPin::KsCreateSinkPinHandle(
950 KSPIN_INTERFACE
& Interface
,
951 KSPIN_MEDIUM
& Medium
)
954 OutputDebugStringW(L
"COutputPin::KsCreateSinkPinHandle NotImplemented\n");
961 COutputPin::KsGetCurrentCommunication(
962 KSPIN_COMMUNICATION
*Communication
,
963 KSPIN_INTERFACE
*Interface
,
964 KSPIN_MEDIUM
*Medium
)
968 *Communication
= m_Communication
;
974 return VFW_E_NOT_CONNECTED
;
976 CopyMemory(Interface
, &m_Interface
, sizeof(KSPIN_INTERFACE
));
982 return VFW_E_NOT_CONNECTED
;
984 CopyMemory(Medium
, &m_Medium
, sizeof(KSPIN_MEDIUM
));
991 COutputPin::KsPropagateAcquire()
999 OutputDebugStringW(L
"COutputPin::KsPropagateAcquire\n");
1002 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1004 Property
.Set
= KSPROPSETID_Connection
;
1005 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
1006 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1008 State
= KSSTATE_ACQUIRE
;
1010 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (LPVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
1017 //propagate to connected pin on the pipe
1024 COutputPin::KsDeliver(
1025 IMediaSample
* Sample
,
1033 COutputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
)
1040 COutputPin::KsPeekAllocator(KSPEEKOPERATION Operation
)
1042 if (Operation
== KsPeekOperation_AddRef
)
1044 // add reference on allocator
1045 m_MemAllocator
->AddRef();
1048 return m_MemAllocator
;
1053 COutputPin::KsReceiveAllocator(IMemAllocator
*MemAllocator
)
1057 MemAllocator
->AddRef();
1062 m_MemAllocator
->Release();
1065 m_MemAllocator
= MemAllocator
;
1071 COutputPin::KsRenegotiateAllocator()
1078 COutputPin::KsIncrementPendingIoCount()
1080 return InterlockedIncrement((volatile LONG
*)&m_IoCount
);
1085 COutputPin::KsDecrementPendingIoCount()
1087 return InterlockedDecrement((volatile LONG
*)&m_IoCount
);
1092 COutputPin::KsQualityNotify(
1094 REFERENCE_TIME TimeDelta
)
1096 #ifdef KSPROXY_TRACE
1097 OutputDebugStringW(L
"COutputPin::KsQualityNotify NotImplemented\n");
1102 //-------------------------------------------------------------------
1108 COutputPin::KsNotifyError(
1109 IMediaSample
* Sample
,
1112 #ifdef KSPROXY_TRACE
1113 OutputDebugStringW(L
"COutputPin::KsNotifyError NotImplemented\n");
1118 //-------------------------------------------------------------------
1124 COutputPin::KsGetPinFramingCache(
1125 PKSALLOCATOR_FRAMING_EX
*FramingEx
,
1126 PFRAMING_PROP FramingProp
,
1127 FRAMING_CACHE_OPS Option
)
1129 if (Option
> Framing_Cache_Write
|| Option
< Framing_Cache_ReadLast
)
1132 return E_INVALIDARG
;
1135 // get framing properties
1136 *FramingProp
= m_FramingProp
[Option
];
1137 *FramingEx
= m_FramingEx
[Option
];
1144 COutputPin::KsSetPinFramingCache(
1145 PKSALLOCATOR_FRAMING_EX FramingEx
,
1146 PFRAMING_PROP FramingProp
,
1147 FRAMING_CACHE_OPS Option
)
1152 if (m_FramingEx
[Option
])
1154 for(Index
= 1; Index
< 4; Index
++)
1156 if (m_FramingEx
[Index
] == m_FramingEx
[Option
])
1162 // existing framing is only used once
1163 CoTaskMemFree(m_FramingEx
[Option
]);
1168 m_FramingEx
[Option
] = FramingEx
;
1169 m_FramingProp
[Option
] = *FramingProp
;
1176 COutputPin::KsGetConnectedPin()
1183 COutputPin::KsGetPipe(
1184 KSPEEKOPERATION Operation
)
1186 if (Operation
== KsPeekOperation_AddRef
)
1188 if (m_KsAllocatorEx
)
1189 m_KsAllocatorEx
->AddRef();
1191 return m_KsAllocatorEx
;
1196 COutputPin::KsSetPipe(
1197 IKsAllocatorEx
*KsAllocator
)
1200 KsAllocator
->AddRef();
1202 if (m_KsAllocatorEx
)
1203 m_KsAllocatorEx
->Release();
1205 m_KsAllocatorEx
= KsAllocator
;
1211 COutputPin::KsGetPipeAllocatorFlag()
1213 return m_PipeAllocatorFlag
;
1219 COutputPin::KsSetPipeAllocatorFlag(
1222 m_PipeAllocatorFlag
= Flag
;
1228 COutputPin::KsGetPinBusCache()
1230 if (!m_bPinBusCacheInitialized
)
1232 CopyMemory(&m_PinBusCache
, &m_Medium
.Set
, sizeof(GUID
));
1233 m_bPinBusCacheInitialized
= TRUE
;
1236 return m_PinBusCache
;
1241 COutputPin::KsSetPinBusCache(
1244 CopyMemory(&m_PinBusCache
, &Bus
, sizeof(GUID
));
1250 COutputPin::KsGetPinName()
1252 return (PWCHAR
)m_PinName
;
1258 COutputPin::KsGetFilterName()
1260 return m_FilterName
;
1263 //-------------------------------------------------------------------
1264 // ISpecifyPropertyPages
1269 COutputPin::GetPages(CAUUID
*pPages
)
1271 #ifdef KSPROXY_TRACE
1272 OutputDebugStringW(L
"COutputPin::GetPages NotImplemented\n");
1279 pPages
->pElems
= NULL
;
1284 //-------------------------------------------------------------------
1290 COutputPin::KsPinFactory(
1293 #ifdef KSPROXY_TRACE
1294 OutputDebugStringW(L
"COutputPin::KsPinFactory\n");
1297 *PinFactory
= m_PinId
;
1302 //-------------------------------------------------------------------
1310 IGraphBuilder
*pGraph
)
1312 #ifdef KSPROXY_TRACE
1313 OutputDebugStringW(L
"COutputPin::Render\n");
1320 COutputPin::Backout(
1322 IGraphBuilder
*pGraph
)
1324 #ifdef KSPROXY_TRACE
1325 OutputDebugStringW(L
"COutputPin::Backout\n");
1330 //-------------------------------------------------------------------
1335 COutputPin::KsGetObjectHandle()
1337 #ifdef KSPROXY_TRACE
1338 OutputDebugStringW(L
"COutputPin::KsGetObjectHandle\n");
1341 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1345 //-------------------------------------------------------------------
1350 COutputPin::KsProperty(
1351 PKSPROPERTY Property
,
1352 ULONG PropertyLength
,
1353 LPVOID PropertyData
,
1355 ULONG
* BytesReturned
)
1359 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1361 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
1362 #ifdef KSPROXY_TRACE
1365 StringFromCLSID(Property
->Set
, &pstr
);
1366 swprintf(Buffer
, L
"COutputPin::KsProperty Set %s Id %lu Flags %x hr %x\n", pstr
, Property
->Id
, Property
->Flags
, hr
);
1367 OutputDebugStringW(Buffer
);
1375 COutputPin::KsMethod(
1380 ULONG
* BytesReturned
)
1382 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1383 #ifdef KSPROXY_TRACE
1384 OutputDebugStringW(L
"COutputPin::KsMethod\n");
1386 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
1391 COutputPin::KsEvent(
1396 ULONG
* BytesReturned
)
1398 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1400 #ifdef KSPROXY_TRACE
1401 OutputDebugStringW(L
"COutputPin::KsEvent\n");
1405 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
1407 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
1411 //-------------------------------------------------------------------
1417 REFGUID guidPropSet
,
1419 LPVOID pInstanceData
,
1420 DWORD cbInstanceData
,
1424 ULONG BytesReturned
;
1428 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1430 return E_OUTOFMEMORY
;
1432 Property
->Set
= guidPropSet
;
1433 Property
->Id
= dwPropID
;
1434 Property
->Flags
= KSPROPERTY_TYPE_SET
;
1436 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1438 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1439 CoTaskMemFree(Property
);
1444 KSPROPERTY Property
;
1446 Property
.Set
= guidPropSet
;
1447 Property
.Id
= dwPropID
;
1448 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1450 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1458 REFGUID guidPropSet
,
1460 LPVOID pInstanceData
,
1461 DWORD cbInstanceData
,
1466 ULONG BytesReturned
;
1470 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1472 return E_OUTOFMEMORY
;
1474 Property
->Set
= guidPropSet
;
1475 Property
->Id
= dwPropID
;
1476 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1478 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1480 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1481 CoTaskMemFree(Property
);
1486 KSPROPERTY Property
;
1488 Property
.Set
= guidPropSet
;
1489 Property
.Id
= dwPropID
;
1490 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1492 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1499 COutputPin::QuerySupported(
1500 REFGUID guidPropSet
,
1502 DWORD
*pTypeSupport
)
1504 KSPROPERTY Property
;
1505 ULONG BytesReturned
;
1507 #ifdef KSPROXY_TRACE
1508 OutputDebugStringW(L
"COutputPin::QuerySupported\n");
1511 Property
.Set
= guidPropSet
;
1512 Property
.Id
= dwPropID
;
1513 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1515 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1519 //-------------------------------------------------------------------
1524 COutputPin::Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
)
1527 ALLOCATOR_PROPERTIES Properties
;
1528 IMemAllocatorCallbackTemp
*pMemCallback
;
1532 #ifdef KSPROXY_TRACE
1534 OutputDebugStringW(L
"COutputPin::Connect called\n");
1539 hr
= pReceivePin
->QueryAccept(pmt
);
1546 hr
= pReceivePin
->QueryAccept(&m_MediaFormat
);
1550 pmt
= &m_MediaFormat
;
1553 if (m_hPin
== INVALID_HANDLE_VALUE
)
1555 hr
= CreatePin(pmt
);
1558 #ifdef KSPROXY_TRACE
1559 swprintf(Buffer
, L
"COutputPin::Connect CreatePin handle failed with %lx\n", hr
);
1560 OutputDebugStringW(Buffer
);
1567 // query for IMemInput interface
1568 hr
= pReceivePin
->QueryInterface(IID_IMemInputPin
, (void**)&m_MemInputPin
);
1571 #ifdef KSPROXY_TRACE
1572 OutputDebugStringW(L
"COutputPin::Connect no IMemInputPin interface\n");
1578 // get input pin allocator properties
1579 ZeroMemory(&Properties
, sizeof(ALLOCATOR_PROPERTIES
));
1580 m_MemInputPin
->GetAllocatorRequirements(&Properties
);
1582 //FIXME determine allocator properties
1583 Properties
.cBuffers
= 32;
1584 Properties
.cbBuffer
= 2048 * 188; //2048 frames * MPEG2 TS Payload size
1585 Properties
.cbAlign
= 4;
1587 // get input pin allocator
1589 hr
= m_MemInputPin
->GetAllocator(&m_MemAllocator
);
1592 // set allocator properties
1593 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1595 m_MemAllocator
->Release();
1601 hr
= CKsAllocator_Constructor(NULL
, IID_IMemAllocator
, (void**)&m_MemAllocator
);
1605 // set allocator properties
1606 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1609 #ifdef KSPROXY_TRACE
1610 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::SetProperties failed with hr %lx\n", hr
);
1611 OutputDebugStringW(Buffer
);
1613 m_MemAllocator
->Release();
1614 m_MemInputPin
->Release();
1619 // commit property changes
1620 hr
= m_MemAllocator
->Commit();
1623 #ifdef KSPROXY_TRACE
1624 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::Commit failed with hr %lx\n", hr
);
1625 OutputDebugStringW(Buffer
);
1627 m_MemAllocator
->Release();
1628 m_MemInputPin
->Release();
1632 // get callback interface
1633 hr
= m_MemAllocator
->QueryInterface(IID_IMemAllocatorCallbackTemp
, (void**)&pMemCallback
);
1636 #ifdef KSPROXY_TRACE
1637 swprintf(Buffer
, L
"COutputPin::Connect No IMemAllocatorCallbackTemp interface hr %lx\n", hr
);
1638 OutputDebugStringW(Buffer
);
1640 m_MemAllocator
->Release();
1641 m_MemInputPin
->Release();
1645 // set notification routine
1646 hr
= pMemCallback
->SetNotify((IMemAllocatorNotifyCallbackTemp
*)this);
1648 // release IMemAllocatorNotifyCallbackTemp interface
1649 pMemCallback
->Release();
1653 #ifdef KSPROXY_TRACE
1654 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocatorNotifyCallbackTemp::SetNotify failed hr %lx\n", hr
);
1655 OutputDebugStringW(Buffer
);
1657 m_MemAllocator
->Release();
1658 m_MemInputPin
->Release();
1662 // now set allocator
1663 hr
= m_MemInputPin
->NotifyAllocator(m_MemAllocator
, TRUE
);
1666 #ifdef KSPROXY_TRACE
1667 swprintf(Buffer
, L
"COutputPin::Connect IMemInputPin::NotifyAllocator failed with hr %lx\n", hr
);
1668 OutputDebugStringW(Buffer
);
1670 m_MemAllocator
->Release();
1671 m_MemInputPin
->Release();
1676 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1678 // get all supported sets
1679 if (m_Plugins
.size() == 0)
1681 if (GetSupportedSets(&pGuid
, &NumGuids
))
1683 // load all proxy plugins
1684 if (FAILED(LoadProxyPlugins(pGuid
, NumGuids
)));
1686 #ifdef KSPROXY_TRACE
1687 OutputDebugStringW(L
"COutputPin::Connect LoadProxyPlugins failed\n");
1691 CoTaskMemFree(pGuid
);
1695 // receive connection;
1696 hr
= pReceivePin
->ReceiveConnection((IPin
*)this, pmt
);
1699 // increment reference count
1700 pReceivePin
->AddRef();
1701 m_Pin
= pReceivePin
;
1702 #ifdef KSPROXY_TRACE
1703 OutputDebugStringW(L
"COutputPin::Connect success\n");
1708 m_MemInputPin
->Release();
1709 m_MemAllocator
->Release();
1717 COutputPin::ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
)
1719 return E_UNEXPECTED
;
1723 COutputPin::Disconnect( void)
1725 #ifdef KSPROXY_TRACE
1726 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1731 // pin was not connected
1736 //check if filter is active
1740 m_MemInputPin
->Release();
1741 m_MemAllocator
->Release();
1743 CloseHandle(m_hPin
);
1744 m_hPin
= INVALID_HANDLE_VALUE
;
1746 #ifdef KSPROXY_TRACE
1747 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1753 COutputPin::ConnectedTo(IPin
**pPin
)
1755 #ifdef KSPROXY_TRACE
1756 OutputDebugStringW(L
"COutputPin::ConnectedTo\n");
1764 // increment reference count
1771 return VFW_E_NOT_CONNECTED
;
1775 COutputPin::ConnectionMediaType(AM_MEDIA_TYPE
*pmt
)
1777 #ifdef KSPROXY_TRACE
1778 OutputDebugStringW(L
"COutputPin::ConnectionMediaType called\n");
1785 COutputPin::QueryPinInfo(PIN_INFO
*pInfo
)
1787 wcscpy(pInfo
->achName
, m_PinName
);
1788 pInfo
->dir
= PINDIR_OUTPUT
;
1789 pInfo
->pFilter
= m_ParentFilter
;
1790 m_ParentFilter
->AddRef();
1796 COutputPin::QueryDirection(PIN_DIRECTION
*pPinDir
)
1800 *pPinDir
= PINDIR_OUTPUT
;
1808 COutputPin::QueryId(LPWSTR
*Id
)
1810 *Id
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_PinName
)+1)*sizeof(WCHAR
));
1812 return E_OUTOFMEMORY
;
1814 wcscpy(*Id
, m_PinName
);
1819 COutputPin::QueryAccept(const AM_MEDIA_TYPE
*pmt
)
1821 #ifdef KSPROXY_TRACE
1822 OutputDebugStringW(L
"COutputPin::QueryAccept called\n");
1829 COutputPin::EnumMediaTypes(IEnumMediaTypes
**ppEnum
)
1832 ULONG MediaTypeCount
= 0, Index
;
1833 AM_MEDIA_TYPE
* MediaTypes
;
1835 IKsObject
* KsObjectParent
;
1837 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1841 // get parent filter handle
1842 hFilter
= KsObjectParent
->KsGetObjectHandle();
1844 // release IKsObject
1845 KsObjectParent
->Release();
1847 // query media type count
1848 hr
= KsGetMediaTypeCount(hFilter
, m_PinId
, &MediaTypeCount
);
1849 if (FAILED(hr
) || !MediaTypeCount
)
1854 // allocate media types
1855 MediaTypes
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1858 // not enough memory
1859 return E_OUTOFMEMORY
;
1863 ZeroMemory(MediaTypes
, sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1865 for(Index
= 0; Index
< MediaTypeCount
; Index
++)
1868 hr
= KsGetMediaType(Index
, &MediaTypes
[Index
], hFilter
, m_PinId
);
1872 CoTaskMemFree(MediaTypes
);
1877 return CEnumMediaTypes_fnConstructor(MediaTypeCount
, MediaTypes
, IID_IEnumMediaTypes
, (void**)ppEnum
);
1881 COutputPin::QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
)
1887 COutputPin::EndOfStream( void)
1889 /* should be called only on input pins */
1890 return E_UNEXPECTED
;
1894 COutputPin::BeginFlush( void)
1896 /* should be called only on input pins */
1897 return E_UNEXPECTED
;
1901 COutputPin::EndFlush( void)
1903 /* should be called only on input pins */
1904 return E_UNEXPECTED
;
1908 COutputPin::NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
)
1912 // we are not connected
1913 return VFW_E_NOT_CONNECTED
;
1916 return m_Pin
->NewSegment(tStart
, tStop
, dRate
);
1919 //-------------------------------------------------------------------
1922 COutputPin::CheckFormat(
1923 const AM_MEDIA_TYPE
*pmt
)
1925 PKSMULTIPLE_ITEM MultipleItem
;
1926 PKSDATAFORMAT DataFormat
;
1928 IKsObject
* KsObjectParent
;
1934 // get IKsObject interface
1935 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1939 // get parent filter handle
1940 hFilter
= KsObjectParent
->KsGetObjectHandle();
1942 // release IKsObject
1943 KsObjectParent
->Release();
1949 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
1953 DataFormat
= (PKSDATAFORMAT
)(MultipleItem
+ 1);
1954 for(ULONG Index
= 0; Index
< MultipleItem
->Count
; Index
++)
1956 if (IsEqualGUID(pmt
->majortype
, DataFormat
->MajorFormat
) &&
1957 IsEqualGUID(pmt
->subtype
, DataFormat
->SubFormat
) &&
1958 IsEqualGUID(pmt
->formattype
, DataFormat
->Specifier
))
1960 // format is supported
1961 CoTaskMemFree(MultipleItem
);
1964 DataFormat
= (PKSDATAFORMAT
)((ULONG_PTR
)DataFormat
+ DataFormat
->FormatSize
);
1966 //format is not supported
1967 CoTaskMemFree(MultipleItem
);
1973 COutputPin::CreatePin(
1974 const AM_MEDIA_TYPE
*pmt
)
1976 PKSMULTIPLE_ITEM MediumList
;
1977 PKSMULTIPLE_ITEM InterfaceList
;
1978 PKSPIN_MEDIUM Medium
;
1979 PKSPIN_INTERFACE Interface
;
1980 IKsInterfaceHandler
* InterfaceHandler
;
1983 // query for pin medium
1984 hr
= KsQueryMediums(&MediumList
);
1987 #ifdef KSPROXY_TRACE
1989 swprintf(Buffer
, L
"COutputPin::CreatePin KsQueryMediums failed %lx\n", hr
);
1990 OutputDebugStringW(Buffer
);
1995 // query for pin interface
1996 hr
= KsQueryInterfaces(&InterfaceList
);
2000 #ifdef KSPROXY_TRACE
2002 swprintf(Buffer
, L
"COutputPin::CreatePin KsQueryInterfaces failed %lx\n", hr
);
2003 OutputDebugStringW(Buffer
);
2006 CoTaskMemFree(MediumList
);
2010 if (MediumList
->Count
)
2012 //use first available medium
2013 Medium
= (PKSPIN_MEDIUM
)(MediumList
+ 1);
2017 // default to standard medium
2018 Medium
= &StandardPinMedium
;
2021 if (InterfaceList
->Count
)
2023 //use first available interface
2024 Interface
= (PKSPIN_INTERFACE
)(InterfaceList
+ 1);
2028 // default to standard interface
2029 Interface
= &StandardPinInterface
;
2032 if (m_Communication
!= KSPIN_COMMUNICATION_BRIDGE
&& m_Communication
!= KSPIN_COMMUNICATION_NONE
)
2035 hr
= CreatePinHandle(Medium
, Interface
, pmt
);
2038 #ifdef KSPROXY_TRACE
2040 swprintf(Buffer
, L
"COutputPin::CreatePinHandle failed with %lx\n", hr
);
2041 OutputDebugStringW(Buffer
);
2046 if (!m_InterfaceHandler
)
2048 // now load the IKsInterfaceHandler plugin
2049 hr
= CoCreateInstance(Interface
->Set
, NULL
, CLSCTX_INPROC_SERVER
, IID_IKsInterfaceHandler
, (void**)&InterfaceHandler
);
2052 // failed to load interface handler plugin
2053 CoTaskMemFree(MediumList
);
2054 CoTaskMemFree(InterfaceList
);
2056 #ifdef KSPROXY_TRACE
2058 swprintf(Buffer
, L
"COutputPin::CreatePin failed to create interface handler %lx\n", hr
);
2059 OutputDebugStringW(Buffer
);
2066 hr
= InterfaceHandler
->KsSetPin((IKsPin
*)this);
2069 // failed to initialize interface handler plugin
2070 #ifdef KSPROXY_TRACE
2072 swprintf(Buffer
, L
"COutputPin::CreatePin failed to initialize interface handler %lx\n", hr
);
2073 OutputDebugStringW(Buffer
);
2075 InterfaceHandler
->Release();
2076 CoTaskMemFree(MediumList
);
2077 CoTaskMemFree(InterfaceList
);
2081 // store interface handler
2082 m_InterfaceHandler
= InterfaceHandler
;
2087 #ifdef KSPROXY_TRACE
2089 swprintf(Buffer
, L
"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication
, m_PinName
);
2090 OutputDebugStringW(Buffer
);
2096 // free medium / interface / dataformat
2097 CoTaskMemFree(MediumList
);
2098 CoTaskMemFree(InterfaceList
);
2100 #ifdef KSPROXY_TRACE
2102 swprintf(Buffer
, L
"COutputPin::CreatePin Result %lx\n", hr
);
2103 OutputDebugStringW(Buffer
);
2111 COutputPin::CreatePinHandle(
2112 PKSPIN_MEDIUM Medium
,
2113 PKSPIN_INTERFACE Interface
,
2114 const AM_MEDIA_TYPE
*pmt
)
2116 PKSPIN_CONNECT PinConnect
;
2117 PKSDATAFORMAT DataFormat
;
2121 IKsObject
* KsObjectParent
;
2123 //KSALLOCATOR_FRAMING Framing;
2124 //KSPROPERTY Property;
2125 //ULONG BytesReturned;
2127 OutputDebugStringW(L
"COutputPin::CreatePinHandle\n");
2129 if (m_hPin
!= INVALID_HANDLE_VALUE
)
2131 // pin already exists
2132 //CloseHandle(m_hPin);
2133 //m_hPin = INVALID_HANDLE_VALUE;
2134 OutputDebugStringW(L
"COutputPin::CreatePinHandle pin already exists\n");
2140 Length
= sizeof(KSPIN_CONNECT
) + sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
2142 // allocate pin connect
2143 PinConnect
= (PKSPIN_CONNECT
)CoTaskMemAlloc(Length
);
2147 OutputDebugStringW(L
"COutputPin::CreatePinHandle out of memory\n");
2148 return E_OUTOFMEMORY
;
2150 OutputDebugStringW(L
"COutputPin::CreatePinHandle copy pinconnect\n");
2152 CopyMemory(&PinConnect
->Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
2153 CopyMemory(&PinConnect
->Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
2154 PinConnect
->PinId
= m_PinId
;
2155 PinConnect
->PinToHandle
= NULL
;
2156 PinConnect
->Priority
.PriorityClass
= KSPRIORITY_NORMAL
;
2157 PinConnect
->Priority
.PrioritySubClass
= KSPRIORITY_NORMAL
;
2159 // get dataformat offset
2160 DataFormat
= (PKSDATAFORMAT
)(PinConnect
+ 1);
2161 OutputDebugStringW(L
"COutputPin::CreatePinHandle copy format\n");
2163 DataFormat
->FormatSize
= sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
2164 DataFormat
->Flags
= 0;
2165 DataFormat
->SampleSize
= pmt
->lSampleSize
;
2166 DataFormat
->Reserved
= 0;
2167 CopyMemory(&DataFormat
->MajorFormat
, &pmt
->majortype
, sizeof(GUID
));
2168 CopyMemory(&DataFormat
->SubFormat
, &pmt
->subtype
, sizeof(GUID
));
2169 CopyMemory(&DataFormat
->Specifier
, &pmt
->formattype
, sizeof(GUID
));
2173 // copy extended format
2175 swprintf(Buffer
, L
"COutputPin::CreatePinHandle copy format %p pbFormat %lu\n", pmt
, pmt
->cbFormat
);
2176 OutputDebugStringW(Buffer
);
2177 CopyMemory((DataFormat
+ 1), pmt
->pbFormat
, pmt
->cbFormat
);
2180 // get IKsObject interface
2181 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
2184 OutputDebugStringW(L
"COutputPin::CreatePinHandle no IID_IKsObject interface\n");
2188 // get parent filter handle
2189 hFilter
= KsObjectParent
->KsGetObjectHandle();
2191 // release IKsObject
2192 KsObjectParent
->Release();
2196 OutputDebugStringW(L
"COutputPin::CreatePinHandle no filter handle\n");
2200 OutputDebugStringW(L
"COutputPin::CreatePinHandle before creating pin\n");
2202 DWORD dwError
= KsCreatePin(hFilter
, PinConnect
, GENERIC_READ
, &m_hPin
);
2204 if (dwError
== ERROR_SUCCESS
)
2206 OutputDebugStringW(L
"COutputPin::CreatePinHandle created pin\n");
2208 // store current interface / medium
2209 CopyMemory(&m_Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
2210 CopyMemory(&m_Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
2211 CopyMemory(&m_MediaFormat
, pmt
, sizeof(AM_MEDIA_TYPE
));
2213 #ifdef KSPROXY_TRACE
2214 LPOLESTR pMajor
, pSub
, pFormat
;
2215 StringFromIID(m_MediaFormat
.majortype
, &pMajor
);
2216 StringFromIID(m_MediaFormat
.subtype
, &pSub
);
2217 StringFromIID(m_MediaFormat
.formattype
, &pFormat
);
2219 swprintf(Buffer
, L
"COutputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor
, pSub
, pFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
2220 CoTaskMemFree(pMajor
);
2221 CoTaskMemFree(pSub
);
2222 CoTaskMemFree(pFormat
);
2223 OutputDebugStringW(Buffer
);
2228 m_MediaFormat
.pbFormat
= (BYTE
*)CoTaskMemAlloc(pmt
->cbFormat
);
2229 if (!m_MediaFormat
.pbFormat
)
2231 CoTaskMemFree(PinConnect
);
2232 m_MediaFormat
.pbFormat
= NULL
;
2233 m_MediaFormat
.cbFormat
= 0;
2234 return E_OUTOFMEMORY
;
2236 CopyMemory(m_MediaFormat
.pbFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
2239 Property
.Set
= KSPROPSETID_Connection
;
2240 Property
.Id
= KSPROPERTY_CONNECTION_ALLOCATORFRAMING
;
2241 Property
.Flags
= KSPROPERTY_TYPE_GET
;
2243 ZeroMemory(&Framing
, sizeof(KSALLOCATOR_FRAMING
));
2244 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (PVOID
)&Framing
, sizeof(KSALLOCATOR_FRAMING
), &BytesReturned
);
2247 m_Properties
.cbAlign
= (Framing
.FileAlignment
+ 1);
2248 m_Properties
.cbBuffer
= Framing
.FrameSize
;
2249 m_Properties
.cbPrefix
= 0; //FIXME
2250 m_Properties
.cBuffers
= Framing
.Frames
;
2255 if (FAILED(InitializeIOThread()))
2257 OutputDebugStringW(L
"COutputPin::CreatePinHandle failed to initialize i/o thread\n");
2261 // connect pin pipes
2265 OutputDebugStringW(L
"COutputPin::CreatePinHandle failed to create pin\n");
2267 CoTaskMemFree(PinConnect
);
2274 COutputPin::GetSupportedSets(
2278 KSPROPERTY Property
;
2280 ULONG NumProperty
= 0;
2281 ULONG NumMethods
= 0;
2282 ULONG NumEvents
= 0;
2284 ULONG BytesReturned
;
2287 Property
.Set
= GUID_NULL
;
2289 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
2291 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumProperty
);
2292 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumMethods
);
2293 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumEvents
);
2295 Length
= NumProperty
+ NumMethods
+ NumEvents
;
2299 // allocate guid buffer
2300 pGuid
= (LPGUID
)CoTaskMemAlloc(Length
);
2304 return E_OUTOFMEMORY
;
2307 NumProperty
/= sizeof(GUID
);
2308 NumMethods
/= sizeof(GUID
);
2309 NumEvents
/= sizeof(GUID
);
2311 // get all properties
2312 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pGuid
, Length
, &BytesReturned
);
2315 CoTaskMemFree(pGuid
);
2318 Length
-= BytesReturned
;
2321 if (Length
&& NumMethods
)
2323 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
], Length
, &BytesReturned
);
2326 CoTaskMemFree(pGuid
);
2329 Length
-= BytesReturned
;
2333 if (Length
&& NumEvents
)
2335 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
+NumMethods
], Length
, &BytesReturned
);
2338 CoTaskMemFree(pGuid
);
2341 Length
-= BytesReturned
;
2344 #ifdef KSPROXY_TRACE
2346 swprintf(Buffer
, L
"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty
, NumMethods
, NumEvents
);
2347 OutputDebugStringW(Buffer
);
2351 *NumGuids
= NumProperty
+NumEvents
+NumMethods
;
2357 COutputPin::LoadProxyPlugins(
2365 IUnknown
* pUnknown
;
2367 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
2369 OutputDebugStringW(L
"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
2373 // enumerate all sets
2374 for(Index
= 0; Index
< NumGuids
; Index
++)
2376 // convert to string
2377 hr
= StringFromCLSID(pGuids
[Index
], &pStr
);
2381 // now try open class key
2382 if (RegOpenKeyExW(hKey
, pStr
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
2384 // no plugin for that set exists
2385 CoTaskMemFree(pStr
);
2390 hr
= CoCreateInstance(pGuids
[Index
], (IBaseFilter
*)this, CLSCTX_INPROC_SERVER
, IID_IUnknown
, (void**)&pUnknown
);
2394 m_Plugins
.push_back(pUnknown
);
2397 RegCloseKey(hSubKey
);
2400 // close media interfaces key
2408 COutputPin::IoProcessRoutine()
2410 IMediaSample
*Sample
;
2413 PKSSTREAM_SEGMENT
* StreamSegment
;
2415 IMediaSample
** Samples
;
2419 #ifdef KSPROXY_TRACE
2423 NumHandles
= m_Properties
.cBuffers
/ 2;
2430 //allocate stream segment array
2431 StreamSegment
= (PKSSTREAM_SEGMENT
*)CoTaskMemAlloc(sizeof(PKSSTREAM_SEGMENT
) * NumHandles
);
2434 OutputDebugStringW(L
"COutputPin::IoProcessRoutine out of memory\n");
2438 // allocate handle array
2439 Samples
= (IMediaSample
**)CoTaskMemAlloc(sizeof(IMediaSample
*) * NumHandles
);
2442 OutputDebugStringW(L
"COutputPin::IoProcessRoutine out of memory\n");
2446 // zero handles array
2447 ZeroMemory(StreamSegment
, sizeof(PKSSTREAM_SEGMENT
) * NumHandles
);
2448 ZeroMemory(Samples
, sizeof(IMediaSample
*) * NumHandles
);
2450 // first wait for the start event to signal
2451 WaitForSingleObject(m_hStartEvent
, INFINITE
);
2455 assert(m_InterfaceHandler
);
2458 if (m_StopInProgress
)
2464 assert(m_State
== KSSTATE_RUN
);
2465 assert(m_MemAllocator
);
2468 hr
= m_MemAllocator
->GetBuffer(&Sample
, NULL
, NULL
, AM_GBF_NOWAIT
);
2472 WaitForSingleObject(m_hBufferAvailable
, INFINITE
);
2479 Samples
[m_IoCount
] = Sample
;
2481 Sample
->SetTime(NULL
, NULL
);
2482 hr
= m_InterfaceHandler
->KsProcessMediaSamples(NULL
, /* FIXME */
2483 &Samples
[m_IoCount
],
2486 &StreamSegment
[m_IoCount
]);
2487 if (FAILED(hr
) || !StreamSegment
)
2489 #ifdef KSPROXY_TRACE
2490 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine KsProcessMediaSamples FAILED PinName %s hr %lx\n", m_PinName
, hr
);
2491 OutputDebugStringW(Buffer
);
2496 // interface handle should increment pending i/o count
2497 assert(m_IoCount
>= 1);
2499 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine m_IoCount %lu NumHandles %lu\n", m_IoCount
, NumHandles
);
2500 OutputDebugStringW(Buffer
);
2502 if (m_IoCount
!= NumHandles
)
2505 // get completion handle
2506 hEvent
= StreamSegment
[0]->CompletionEvent
;
2508 // wait for i/o completion
2509 dwStatus
= WaitForSingleObject(hEvent
, INFINITE
);
2511 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine dwStatus %lx Error %lx NumHandles %lu\n", dwStatus
, GetLastError(), NumHandles
);
2512 OutputDebugStringW(Buffer
);
2514 // perform completion
2515 m_InterfaceHandler
->KsCompleteIo(StreamSegment
[0]);
2517 // close completion event
2518 CloseHandle(hEvent
);
2522 assert(m_MemInputPin
);
2524 // now deliver the sample
2525 hr
= m_MemInputPin
->Receive(Samples
[0]);
2527 #ifdef KSPROXY_TRACE
2528 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName
, hr
, Sample
, m_MemAllocator
);
2529 OutputDebugStringW(Buffer
);
2538 //circular stream segment array
2539 RtlMoveMemory(StreamSegment
, &StreamSegment
[1], sizeof(PKSSTREAM_SEGMENT
) * (NumHandles
- 1));
2540 RtlMoveMemory(Samples
, &Samples
[1], sizeof(IMediaSample
*) * (NumHandles
- 1));
2544 // signal end of i/o thread
2545 SetEvent(m_hStopEvent
);
2547 m_IoThreadStarted
= false;
2554 COutputPin_IoThreadStartup(
2557 COutputPin
* Pin
= (COutputPin
*)lpParameter
;
2560 return Pin
->IoProcessRoutine();
2566 COutputPin::InitializeIOThread()
2570 if (m_IoThreadStarted
)
2574 m_hStartEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2577 return E_OUTOFMEMORY
;
2580 m_hStopEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2583 return E_OUTOFMEMORY
;
2585 if (!m_hBufferAvailable
)
2586 m_hBufferAvailable
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2588 if (!m_hBufferAvailable
)
2589 return E_OUTOFMEMORY
;
2591 m_StopInProgress
= false;
2592 m_IoThreadStarted
= true;
2594 // now create the startup thread
2595 hThread
= CreateThread(NULL
, 0, COutputPin_IoThreadStartup
, (LPVOID
)this, 0, NULL
);
2597 return E_OUTOFMEMORY
;
2600 // close thread handle
2601 CloseHandle(hThread
);
2607 COutputPin_SetState(
2612 KSPROPERTY Property
;
2614 ULONG BytesReturned
;
2615 COutputPin
* pPin
= (COutputPin
*)Pin
;
2617 #ifdef KSPROXY_TRACE
2621 Property
.Set
= KSPROPSETID_Connection
;
2622 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
2623 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2625 EnterCriticalSection(&pPin
->m_Lock
);
2627 if (pPin
->m_State
<= State
)
2629 if (pPin
->m_State
== KSSTATE_STOP
)
2631 hr
= pPin
->InitializeIOThread();
2634 // failed to initialize I/O thread
2635 #ifdef KSPROXY_TRACE
2636 OutputDebugStringW(L
"Failed to initialize I/O Thread\n");
2638 LeaveCriticalSection(&pPin
->m_Lock
);
2641 CurState
= KSSTATE_ACQUIRE
;
2642 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2644 #ifdef KSPROXY_TRACE
2645 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_STOP KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2646 OutputDebugStringW(Buffer
);
2651 LeaveCriticalSection(&pPin
->m_Lock
);
2655 pPin
->m_State
= CurState
;
2657 if (pPin
->m_State
== State
)
2659 LeaveCriticalSection(&pPin
->m_Lock
);
2663 if (pPin
->m_State
== KSSTATE_ACQUIRE
)
2665 CurState
= KSSTATE_PAUSE
;
2666 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2668 #ifdef KSPROXY_TRACE
2669 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState KSSTATE_ACQUIRE KSSTATE_PAUSE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2670 OutputDebugStringW(Buffer
);
2675 LeaveCriticalSection(&pPin
->m_Lock
);
2679 pPin
->m_State
= CurState
;
2681 if (pPin
->m_State
== State
)
2683 LeaveCriticalSection(&pPin
->m_Lock
);
2687 if (State
== KSSTATE_RUN
&& pPin
->m_State
== KSSTATE_PAUSE
)
2689 CurState
= KSSTATE_RUN
;
2690 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2692 #ifdef KSPROXY_TRACE
2693 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_RUN PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2694 OutputDebugStringW(Buffer
);
2699 pPin
->m_State
= CurState
;
2700 // signal start event
2701 SetEvent(pPin
->m_hStartEvent
);
2705 LeaveCriticalSection(&pPin
->m_Lock
);
2710 if (pPin
->m_State
== KSSTATE_RUN
)
2712 // setting pending stop flag
2713 pPin
->m_StopInProgress
= true;
2715 // release any waiting threads
2716 SetEvent(pPin
->m_hBufferAvailable
);
2718 // wait until i/o thread is done
2719 WaitForSingleObject(pPin
->m_hStopEvent
, INFINITE
);
2721 CurState
= KSSTATE_PAUSE
;
2722 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2724 #ifdef KSPROXY_TRACE
2725 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_RUN KSSTATE_PAUSE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2726 OutputDebugStringW(Buffer
);
2731 LeaveCriticalSection(&pPin
->m_Lock
);
2735 pPin
->m_State
= CurState
;
2739 LeaveCriticalSection(&pPin
->m_Lock
);
2743 if (pPin
->m_State
== KSSTATE_PAUSE
)
2745 CurState
= KSSTATE_ACQUIRE
;
2746 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2748 #ifdef KSPROXY_TRACE
2749 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2750 OutputDebugStringW(Buffer
);
2755 LeaveCriticalSection(&pPin
->m_Lock
);
2759 pPin
->m_State
= CurState
;
2761 if (pPin
->m_State
== State
)
2763 LeaveCriticalSection(&pPin
->m_Lock
);
2768 CloseHandle(pPin
->m_hStopEvent
);
2769 CloseHandle(pPin
->m_hStartEvent
);
2770 CloseHandle(pPin
->m_hBufferAvailable
);
2772 /* close event handles */
2773 pPin
->m_hStopEvent
= NULL
;
2774 pPin
->m_hStartEvent
= NULL
;
2775 pPin
->m_hBufferAvailable
= NULL
;
2777 CurState
= KSSTATE_STOP
;
2778 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2780 #ifdef KSPROXY_TRACE
2781 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_ACQUIRE KSSTATE_STOP PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2782 OutputDebugStringW(Buffer
);
2788 pPin
->m_State
= CurState
;
2791 // unset pending stop flag
2792 pPin
->m_StopInProgress
= false;
2794 LeaveCriticalSection(&pPin
->m_Lock
);
2801 COutputPin_Constructor(
2802 IBaseFilter
* ParentFilter
,
2805 KSPIN_COMMUNICATION Communication
,
2809 COutputPin
* handler
= new COutputPin(ParentFilter
, PinName
, PinId
, Communication
);
2812 return E_OUTOFMEMORY
;
2814 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
2818 return E_NOINTERFACE
;