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 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
31 STDMETHODIMP_(ULONG
) AddRef()
33 InterlockedIncrement(&m_Ref
);
36 STDMETHODIMP_(ULONG
) Release()
38 InterlockedDecrement(&m_Ref
);
48 HRESULT STDMETHODCALLTYPE
KsQueryMediums(PKSMULTIPLE_ITEM
* MediumList
);
49 HRESULT STDMETHODCALLTYPE
KsQueryInterfaces(PKSMULTIPLE_ITEM
* InterfaceList
);
50 HRESULT STDMETHODCALLTYPE
KsCreateSinkPinHandle(KSPIN_INTERFACE
& Interface
, KSPIN_MEDIUM
& Medium
);
51 HRESULT STDMETHODCALLTYPE
KsGetCurrentCommunication(KSPIN_COMMUNICATION
*Communication
, KSPIN_INTERFACE
*Interface
, KSPIN_MEDIUM
*Medium
);
52 HRESULT STDMETHODCALLTYPE
KsPropagateAcquire();
53 HRESULT STDMETHODCALLTYPE
KsDeliver(IMediaSample
* Sample
, ULONG Flags
);
54 HRESULT STDMETHODCALLTYPE
KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
);
55 IMemAllocator
* STDMETHODCALLTYPE
KsPeekAllocator(KSPEEKOPERATION Operation
);
56 HRESULT STDMETHODCALLTYPE
KsReceiveAllocator(IMemAllocator
*MemAllocator
);
57 HRESULT STDMETHODCALLTYPE
KsRenegotiateAllocator();
58 LONG STDMETHODCALLTYPE
KsIncrementPendingIoCount();
59 LONG STDMETHODCALLTYPE
KsDecrementPendingIoCount();
60 HRESULT STDMETHODCALLTYPE
KsQualityNotify(ULONG Proportion
, REFERENCE_TIME TimeDelta
);
62 VOID STDMETHODCALLTYPE
KsNotifyError(IMediaSample
* Sample
, HRESULT hr
);
65 HRESULT STDMETHODCALLTYPE
KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX
*FramingEx
, PFRAMING_PROP FramingProp
, FRAMING_CACHE_OPS Option
);
66 HRESULT STDMETHODCALLTYPE
KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx
, PFRAMING_PROP FramingProp
, FRAMING_CACHE_OPS Option
);
67 IPin
* STDMETHODCALLTYPE
KsGetConnectedPin();
68 IKsAllocatorEx
* STDMETHODCALLTYPE
KsGetPipe(KSPEEKOPERATION Operation
);
69 HRESULT STDMETHODCALLTYPE
KsSetPipe(IKsAllocatorEx
*KsAllocator
);
70 ULONG STDMETHODCALLTYPE
KsGetPipeAllocatorFlag();
71 HRESULT STDMETHODCALLTYPE
KsSetPipeAllocatorFlag(ULONG Flag
);
72 GUID STDMETHODCALLTYPE
KsGetPinBusCache();
73 HRESULT STDMETHODCALLTYPE
KsSetPinBusCache(GUID Bus
);
74 PWCHAR STDMETHODCALLTYPE
KsGetPinName();
75 PWCHAR STDMETHODCALLTYPE
KsGetFilterName();
78 HRESULT STDMETHODCALLTYPE
Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
);
79 HRESULT STDMETHODCALLTYPE
ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
);
80 HRESULT STDMETHODCALLTYPE
Disconnect();
81 HRESULT STDMETHODCALLTYPE
ConnectedTo(IPin
**pPin
);
82 HRESULT STDMETHODCALLTYPE
ConnectionMediaType(AM_MEDIA_TYPE
*pmt
);
83 HRESULT STDMETHODCALLTYPE
QueryPinInfo(PIN_INFO
*pInfo
);
84 HRESULT STDMETHODCALLTYPE
QueryDirection(PIN_DIRECTION
*pPinDir
);
85 HRESULT STDMETHODCALLTYPE
QueryId(LPWSTR
*Id
);
86 HRESULT STDMETHODCALLTYPE
QueryAccept(const AM_MEDIA_TYPE
*pmt
);
87 HRESULT STDMETHODCALLTYPE
EnumMediaTypes(IEnumMediaTypes
**ppEnum
);
88 HRESULT STDMETHODCALLTYPE
QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
);
89 HRESULT STDMETHODCALLTYPE
EndOfStream();
90 HRESULT STDMETHODCALLTYPE
BeginFlush();
91 HRESULT STDMETHODCALLTYPE
EndFlush();
92 HRESULT STDMETHODCALLTYPE
NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
);
94 // ISpecifyPropertyPages
95 HRESULT STDMETHODCALLTYPE
GetPages(CAUUID
*pPages
);
98 HANDLE STDMETHODCALLTYPE
KsGetObjectHandle();
101 HRESULT STDMETHODCALLTYPE
Set(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
);
102 HRESULT STDMETHODCALLTYPE
Get(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
, DWORD
*pcbReturned
);
103 HRESULT STDMETHODCALLTYPE
QuerySupported(REFGUID guidPropSet
, DWORD dwPropID
, DWORD
*pTypeSupport
);
106 HRESULT STDMETHODCALLTYPE
KsProperty(PKSPROPERTY Property
, ULONG PropertyLength
, LPVOID PropertyData
, ULONG DataLength
, ULONG
* BytesReturned
);
107 HRESULT STDMETHODCALLTYPE
KsMethod(PKSMETHOD Method
, ULONG MethodLength
, LPVOID MethodData
, ULONG DataLength
, ULONG
* BytesReturned
);
108 HRESULT STDMETHODCALLTYPE
KsEvent(PKSEVENT Event
, ULONG EventLength
, LPVOID EventData
, ULONG DataLength
, ULONG
* BytesReturned
);
111 HRESULT STDMETHODCALLTYPE
Render(IPin
*ppinOut
, IGraphBuilder
*pGraph
);
112 HRESULT STDMETHODCALLTYPE
Backout(IPin
*ppinOut
, IGraphBuilder
*pGraph
);
115 HRESULT STDMETHODCALLTYPE
KsPinFactory(ULONG
* PinFactory
);
117 //IKsAggregateControl
118 HRESULT STDMETHODCALLTYPE
KsAddAggregate(IN REFGUID AggregateClass
);
119 HRESULT STDMETHODCALLTYPE
KsRemoveAggregate(REFGUID AggregateClass
);
122 HRESULT STDMETHODCALLTYPE
Notify(IBaseFilter
*pSelf
, Quality q
);
123 HRESULT STDMETHODCALLTYPE
SetSink(IQualityControl
*piqc
);
126 HRESULT STDMETHODCALLTYPE
GetCapabilities(DWORD
*pCapabilities
);
127 HRESULT STDMETHODCALLTYPE
CheckCapabilities(DWORD
*pCapabilities
);
128 HRESULT STDMETHODCALLTYPE
IsFormatSupported(const GUID
*pFormat
);
129 HRESULT STDMETHODCALLTYPE
QueryPreferredFormat(GUID
*pFormat
);
130 HRESULT STDMETHODCALLTYPE
GetTimeFormat(GUID
*pFormat
);
131 HRESULT STDMETHODCALLTYPE
IsUsingTimeFormat(const GUID
*pFormat
);
132 HRESULT STDMETHODCALLTYPE
SetTimeFormat(const GUID
*pFormat
);
133 HRESULT STDMETHODCALLTYPE
GetDuration(LONGLONG
*pDuration
);
134 HRESULT STDMETHODCALLTYPE
GetStopPosition(LONGLONG
*pStop
);
135 HRESULT STDMETHODCALLTYPE
GetCurrentPosition(LONGLONG
*pCurrent
);
136 HRESULT STDMETHODCALLTYPE
ConvertTimeFormat(LONGLONG
*pTarget
, const GUID
*pTargetFormat
, LONGLONG Source
, const GUID
*pSourceFormat
);
137 HRESULT STDMETHODCALLTYPE
SetPositions(LONGLONG
*pCurrent
, DWORD dwCurrentFlags
, LONGLONG
*pStop
, DWORD dwStopFlags
);
138 HRESULT STDMETHODCALLTYPE
GetPositions(LONGLONG
*pCurrent
, LONGLONG
*pStop
);
139 HRESULT STDMETHODCALLTYPE
GetAvailable(LONGLONG
*pEarliest
, LONGLONG
*pLatest
);
140 HRESULT STDMETHODCALLTYPE
SetRate(double dRate
);
141 HRESULT STDMETHODCALLTYPE
GetRate(double *pdRate
);
142 HRESULT STDMETHODCALLTYPE
GetPreroll(LONGLONG
*pllPreroll
);
144 //IAMBufferNegotiation
145 HRESULT STDMETHODCALLTYPE
SuggestAllocatorProperties(const ALLOCATOR_PROPERTIES
*pprop
);
146 HRESULT STDMETHODCALLTYPE
GetAllocatorProperties(ALLOCATOR_PROPERTIES
*pprop
);
149 HRESULT STDMETHODCALLTYPE
SetFormat(AM_MEDIA_TYPE
*pmt
);
150 HRESULT STDMETHODCALLTYPE
GetFormat(AM_MEDIA_TYPE
**ppmt
);
151 HRESULT STDMETHODCALLTYPE
GetNumberOfCapabilities(int *piCount
, int *piSize
);
152 HRESULT STDMETHODCALLTYPE
GetStreamCaps(int iIndex
, AM_MEDIA_TYPE
**ppmt
, BYTE
*pSCC
);
154 //IMemAllocatorNotifyCallbackTemp
155 HRESULT STDMETHODCALLTYPE
NotifyRelease();
157 //---------------------------------------------------------------
158 COutputPin(IBaseFilter
* ParentFilter
, LPCWSTR PinName
, ULONG PinId
, KSPIN_COMMUNICATION Communication
);
159 virtual ~COutputPin();
160 HRESULT STDMETHODCALLTYPE
CheckFormat(const AM_MEDIA_TYPE
*pmt
);
161 HRESULT STDMETHODCALLTYPE
CreatePin(const AM_MEDIA_TYPE
*pmt
);
162 HRESULT STDMETHODCALLTYPE
CreatePinHandle(PKSPIN_MEDIUM Medium
, PKSPIN_INTERFACE Interface
, const AM_MEDIA_TYPE
*pmt
);
163 HRESULT WINAPI
IoProcessRoutine();
164 HRESULT WINAPI
InitializeIOThread();
166 friend DWORD WINAPI
COutputPin_IoThreadStartup(LPVOID lpParameter
);
167 friend HRESULT STDMETHODCALLTYPE
COutputPin_SetState(IPin
* Pin
, KSSTATE State
);
171 IBaseFilter
* m_ParentFilter
;
175 IKsObject
* m_KsObjectParent
;
177 IKsAllocatorEx
* m_KsAllocatorEx
;
178 ULONG m_PipeAllocatorFlag
;
179 BOOL m_bPinBusCacheInitialized
;
182 FRAMING_PROP m_FramingProp
[4];
183 PKSALLOCATOR_FRAMING_EX m_FramingEx
[4];
185 IMemAllocator
* m_MemAllocator
;
186 IMemInputPin
* m_MemInputPin
;
188 KSPIN_COMMUNICATION m_Communication
;
189 KSPIN_INTERFACE m_Interface
;
190 KSPIN_MEDIUM m_Medium
;
191 AM_MEDIA_TYPE m_MediaFormat
;
193 IMediaSeeking
* m_FilterMediaSeeking
;
194 ALLOCATOR_PROPERTIES m_Properties
;
195 IKsInterfaceHandler
* m_InterfaceHandler
;
197 HANDLE m_hStartEvent
;
198 HANDLE m_hBufferAvailable
;
200 BOOL m_StopInProgress
;
201 BOOL m_IoThreadStarted
;
206 COutputPin::~COutputPin()
208 if (m_KsObjectParent
)
209 m_KsObjectParent
->Release();
212 COutputPin::COutputPin(
213 IBaseFilter
* ParentFilter
,
216 KSPIN_COMMUNICATION Communication
) : m_Ref(0),
217 m_ParentFilter(ParentFilter
),
219 m_hPin(INVALID_HANDLE_VALUE
),
224 m_PipeAllocatorFlag(0),
225 m_bPinBusCacheInitialized(0),
230 m_Communication(Communication
),
231 m_FilterMediaSeeking(0),
232 m_InterfaceHandler(0),
234 m_hBufferAvailable(0),
237 m_IoThreadStarted(0),
238 m_State(KSSTATE_STOP
)
242 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&m_KsObjectParent
);
245 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&m_FilterMediaSeeking
);
248 ZeroMemory(m_FramingProp
, sizeof(m_FramingProp
));
249 ZeroMemory(m_FramingEx
, sizeof(m_FramingEx
));
251 hr
= KsGetMediaType(0, &m_MediaFormat
, m_KsObjectParent
->KsGetObjectHandle(), m_PinId
);
257 COutputPin::QueryInterface(
262 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
263 IsEqualGUID(refiid
, IID_IPin
))
265 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IPin\n");
266 *Output
= PVOID(this);
267 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
270 else if (IsEqualGUID(refiid
, IID_IKsObject
))
272 if (m_hPin
== INVALID_HANDLE_VALUE
)
274 HRESULT hr
= CreatePin(&m_MediaFormat
);
279 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsObject\n");
280 *Output
= (IKsObject
*)(this);
281 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
284 else if (IsEqualGUID(refiid
, IID_IKsPin
) || IsEqualGUID(refiid
, IID_IKsPinEx
))
286 *Output
= (IKsPinEx
*)(this);
287 reinterpret_cast<IKsPinEx
*>(*Output
)->AddRef();
290 else if (IsEqualGUID(refiid
, IID_IKsPinPipe
))
292 *Output
= (IKsPinPipe
*)(this);
293 reinterpret_cast<IKsPinPipe
*>(*Output
)->AddRef();
296 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
298 *Output
= (IKsAggregateControl
*)(this);
299 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
302 else if (IsEqualGUID(refiid
, IID_IQualityControl
))
304 *Output
= (IQualityControl
*)(this);
305 reinterpret_cast<IQualityControl
*>(*Output
)->AddRef();
308 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
310 if (m_hPin
== INVALID_HANDLE_VALUE
)
312 HRESULT hr
= CreatePin(&m_MediaFormat
);
316 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPropertySet\n");
317 *Output
= (IKsPropertySet
*)(this);
318 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
321 else if (IsEqualGUID(refiid
, IID_IKsControl
))
323 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsControl\n");
324 *Output
= (IKsControl
*)(this);
325 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
329 else if (IsEqualGUID(refiid
, IID_IStreamBuilder
))
331 *Output
= (IStreamBuilder
*)(this);
332 reinterpret_cast<IStreamBuilder
*>(*Output
)->AddRef();
336 else if (IsEqualGUID(refiid
, IID_IKsPinFactory
))
338 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPinFactory\n");
339 *Output
= (IKsPinFactory
*)(this);
340 reinterpret_cast<IKsPinFactory
*>(*Output
)->AddRef();
343 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
345 OutputDebugStringW(L
"COutputPin::QueryInterface IID_ISpecifyPropertyPages\n");
346 *Output
= (ISpecifyPropertyPages
*)(this);
347 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
350 else if (IsEqualGUID(refiid
, IID_IMediaSeeking
))
352 *Output
= (IMediaSeeking
*)(this);
353 reinterpret_cast<IMediaSeeking
*>(*Output
)->AddRef();
356 else if (IsEqualGUID(refiid
, IID_IAMBufferNegotiation
))
358 *Output
= (IAMBufferNegotiation
*)(this);
359 reinterpret_cast<IAMBufferNegotiation
*>(*Output
)->AddRef();
362 else if (IsEqualGUID(refiid
, IID_IAMStreamConfig
))
364 *Output
= (IAMStreamConfig
*)(this);
365 reinterpret_cast<IAMStreamConfig
*>(*Output
)->AddRef();
368 else if (IsEqualGUID(refiid
, IID_IMemAllocatorNotifyCallbackTemp
))
370 *Output
= (IMemAllocatorNotifyCallbackTemp
*)(this);
371 reinterpret_cast<IMemAllocatorNotifyCallbackTemp
*>(*Output
)->AddRef();
375 WCHAR Buffer
[MAX_PATH
];
377 StringFromCLSID(refiid
, &lpstr
);
378 swprintf(Buffer
, L
"COutputPin::QueryInterface: NoInterface for %s PinId %u PinName %s\n", lpstr
, m_PinId
, m_PinName
);
379 OutputDebugStringW(Buffer
);
380 CoTaskMemFree(lpstr
);
382 return E_NOINTERFACE
;
385 //-------------------------------------------------------------------
386 // IAMBufferNegotiation interface
390 COutputPin::SuggestAllocatorProperties(
391 const ALLOCATOR_PROPERTIES
*pprop
)
393 OutputDebugStringW(L
"COutputPin::SuggestAllocatorProperties\n");
397 // pin is already connected
398 return VFW_E_ALREADY_CONNECTED
;
401 CopyMemory(&m_Properties
, pprop
, sizeof(ALLOCATOR_PROPERTIES
));
407 COutputPin::GetAllocatorProperties(
408 ALLOCATOR_PROPERTIES
*pprop
)
410 OutputDebugStringW(L
"COutputPin::GetAllocatorProperties\n");
414 // you should call this method AFTER you connected
418 if (!m_KsAllocatorEx
)
420 // something went wrong while creating the allocator
424 CopyMemory(pprop
, &m_Properties
, sizeof(ALLOCATOR_PROPERTIES
));
428 //-------------------------------------------------------------------
429 // IAMStreamConfig interface
433 COutputPin::SetFormat(
436 OutputDebugStringW(L
"COutputPin::SetFormat NotImplemented\n");
442 COutputPin::GetFormat(AM_MEDIA_TYPE
**ppmt
)
444 OutputDebugStringW(L
"COutputPin::GetFormat NotImplemented\n");
450 COutputPin::GetNumberOfCapabilities(
454 OutputDebugStringW(L
"COutputPin::GetNumberOfCapabilities NotImplemented\n");
460 COutputPin::GetStreamCaps(
462 AM_MEDIA_TYPE
**ppmt
,
465 OutputDebugStringW(L
"COutputPin::GetStreamCaps NotImplemented\n");
469 //-------------------------------------------------------------------
470 // IMemAllocatorNotifyCallbackTemp interface
474 COutputPin::NotifyRelease()
476 OutputDebugStringW(L
"COutputPin::NotifyRelease\n");
478 // notify thread of new available sample
479 SetEvent(m_hBufferAvailable
);
484 //-------------------------------------------------------------------
485 // IMediaSeeking interface
489 COutputPin::GetCapabilities(
490 DWORD
*pCapabilities
)
492 return m_FilterMediaSeeking
->GetCapabilities(pCapabilities
);
497 COutputPin::CheckCapabilities(
498 DWORD
*pCapabilities
)
500 return m_FilterMediaSeeking
->CheckCapabilities(pCapabilities
);
505 COutputPin::IsFormatSupported(
508 return m_FilterMediaSeeking
->IsFormatSupported(pFormat
);
513 COutputPin::QueryPreferredFormat(
516 return m_FilterMediaSeeking
->QueryPreferredFormat(pFormat
);
521 COutputPin::GetTimeFormat(
524 return m_FilterMediaSeeking
->GetTimeFormat(pFormat
);
529 COutputPin::IsUsingTimeFormat(
532 return m_FilterMediaSeeking
->IsUsingTimeFormat(pFormat
);
537 COutputPin::SetTimeFormat(
540 return m_FilterMediaSeeking
->SetTimeFormat(pFormat
);
545 COutputPin::GetDuration(
548 return m_FilterMediaSeeking
->GetDuration(pDuration
);
553 COutputPin::GetStopPosition(
556 return m_FilterMediaSeeking
->GetStopPosition(pStop
);
562 COutputPin::GetCurrentPosition(
565 return m_FilterMediaSeeking
->GetCurrentPosition(pCurrent
);
570 COutputPin::ConvertTimeFormat(
572 const GUID
*pTargetFormat
,
574 const GUID
*pSourceFormat
)
576 return m_FilterMediaSeeking
->ConvertTimeFormat(pTarget
, pTargetFormat
, Source
, pSourceFormat
);
581 COutputPin::SetPositions(
583 DWORD dwCurrentFlags
,
587 return m_FilterMediaSeeking
->SetPositions(pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
592 COutputPin::GetPositions(
596 return m_FilterMediaSeeking
->GetPositions(pCurrent
, pStop
);
601 COutputPin::GetAvailable(
605 return m_FilterMediaSeeking
->GetAvailable(pEarliest
, pLatest
);
613 return m_FilterMediaSeeking
->SetRate(dRate
);
621 return m_FilterMediaSeeking
->GetRate(pdRate
);
626 COutputPin::GetPreroll(
627 LONGLONG
*pllPreroll
)
629 return m_FilterMediaSeeking
->GetPreroll(pllPreroll
);
632 //-------------------------------------------------------------------
633 // IQualityControl interface
641 OutputDebugStringW(L
"COutputPin::Notify NotImplemented\n");
648 IQualityControl
*piqc
)
650 OutputDebugStringW(L
"COutputPin::SetSink NotImplemented\n");
655 //-------------------------------------------------------------------
656 // IKsAggregateControl interface
660 COutputPin::KsAddAggregate(
661 IN REFGUID AggregateClass
)
663 OutputDebugStringW(L
"COutputPin::KsAddAggregate NotImplemented\n");
669 COutputPin::KsRemoveAggregate(
670 REFGUID AggregateClass
)
672 OutputDebugStringW(L
"COutputPin::KsRemoveAggregate NotImplemented\n");
677 //-------------------------------------------------------------------
683 COutputPin::KsQueryMediums(
684 PKSMULTIPLE_ITEM
* MediumList
)
686 HANDLE hFilter
= m_KsObjectParent
->KsGetObjectHandle();
687 return KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_MEDIUMS
, (PVOID
*)MediumList
);
692 COutputPin::KsQueryInterfaces(
693 PKSMULTIPLE_ITEM
* InterfaceList
)
695 HANDLE hFilter
= m_KsObjectParent
->KsGetObjectHandle();
697 return KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_INTERFACES
, (PVOID
*)InterfaceList
);
702 COutputPin::KsCreateSinkPinHandle(
703 KSPIN_INTERFACE
& Interface
,
704 KSPIN_MEDIUM
& Medium
)
706 OutputDebugStringW(L
"COutputPin::KsCreateSinkPinHandle NotImplemented\n");
712 COutputPin::KsGetCurrentCommunication(
713 KSPIN_COMMUNICATION
*Communication
,
714 KSPIN_INTERFACE
*Interface
,
715 KSPIN_MEDIUM
*Medium
)
719 *Communication
= m_Communication
;
725 return VFW_E_NOT_CONNECTED
;
727 CopyMemory(Interface
, &m_Interface
, sizeof(KSPIN_INTERFACE
));
733 return VFW_E_NOT_CONNECTED
;
735 CopyMemory(Medium
, &m_Medium
, sizeof(KSPIN_MEDIUM
));
742 COutputPin::KsPropagateAcquire()
749 OutputDebugStringW(L
"COutputPin::KsPropagateAcquire\n");
751 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
753 Property
.Set
= KSPROPSETID_Connection
;
754 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
755 Property
.Flags
= KSPROPERTY_TYPE_SET
;
757 State
= KSSTATE_ACQUIRE
;
759 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (LPVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
762 //propagate to connected pin on the pipe
769 COutputPin::KsDeliver(
770 IMediaSample
* Sample
,
778 COutputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
)
785 COutputPin::KsPeekAllocator(KSPEEKOPERATION Operation
)
787 if (Operation
== KsPeekOperation_AddRef
)
789 // add reference on allocator
790 m_MemAllocator
->AddRef();
793 return m_MemAllocator
;
798 COutputPin::KsReceiveAllocator(IMemAllocator
*MemAllocator
)
802 MemAllocator
->AddRef();
807 m_MemAllocator
->Release();
810 m_MemAllocator
= MemAllocator
;
816 COutputPin::KsRenegotiateAllocator()
823 COutputPin::KsIncrementPendingIoCount()
825 return InterlockedIncrement((volatile LONG
*)&m_IoCount
);
830 COutputPin::KsDecrementPendingIoCount()
832 return InterlockedDecrement((volatile LONG
*)&m_IoCount
);
837 COutputPin::KsQualityNotify(
839 REFERENCE_TIME TimeDelta
)
841 OutputDebugStringW(L
"COutputPin::KsQualityNotify NotImplemented\n");
845 //-------------------------------------------------------------------
851 COutputPin::KsNotifyError(
852 IMediaSample
* Sample
,
855 OutputDebugStringW(L
"COutputPin::KsNotifyError NotImplemented\n");
859 //-------------------------------------------------------------------
865 COutputPin::KsGetPinFramingCache(
866 PKSALLOCATOR_FRAMING_EX
*FramingEx
,
867 PFRAMING_PROP FramingProp
,
868 FRAMING_CACHE_OPS Option
)
870 if (Option
> Framing_Cache_Write
|| Option
< Framing_Cache_ReadLast
)
876 // get framing properties
877 *FramingProp
= m_FramingProp
[Option
];
878 *FramingEx
= m_FramingEx
[Option
];
885 COutputPin::KsSetPinFramingCache(
886 PKSALLOCATOR_FRAMING_EX FramingEx
,
887 PFRAMING_PROP FramingProp
,
888 FRAMING_CACHE_OPS Option
)
893 if (m_FramingEx
[Option
])
895 for(Index
= 1; Index
< 4; Index
++)
897 if (m_FramingEx
[Index
] == m_FramingEx
[Option
])
903 // existing framing is only used once
904 CoTaskMemFree(m_FramingEx
[Option
]);
909 m_FramingEx
[Option
] = FramingEx
;
910 m_FramingProp
[Option
] = *FramingProp
;
917 COutputPin::KsGetConnectedPin()
924 COutputPin::KsGetPipe(
925 KSPEEKOPERATION Operation
)
927 if (Operation
== KsPeekOperation_AddRef
)
930 m_KsAllocatorEx
->AddRef();
932 return m_KsAllocatorEx
;
937 COutputPin::KsSetPipe(
938 IKsAllocatorEx
*KsAllocator
)
941 KsAllocator
->AddRef();
944 m_KsAllocatorEx
->Release();
946 m_KsAllocatorEx
= KsAllocator
;
952 COutputPin::KsGetPipeAllocatorFlag()
954 return m_PipeAllocatorFlag
;
960 COutputPin::KsSetPipeAllocatorFlag(
963 m_PipeAllocatorFlag
= Flag
;
969 COutputPin::KsGetPinBusCache()
971 if (!m_bPinBusCacheInitialized
)
973 CopyMemory(&m_PinBusCache
, &m_Medium
.Set
, sizeof(GUID
));
974 m_bPinBusCacheInitialized
= TRUE
;
977 return m_PinBusCache
;
982 COutputPin::KsSetPinBusCache(
985 CopyMemory(&m_PinBusCache
, &Bus
, sizeof(GUID
));
991 COutputPin::KsGetPinName()
993 return (PWCHAR
)m_PinName
;
999 COutputPin::KsGetFilterName()
1001 return m_FilterName
;
1004 //-------------------------------------------------------------------
1005 // ISpecifyPropertyPages
1010 COutputPin::GetPages(CAUUID
*pPages
)
1012 OutputDebugStringW(L
"COutputPin::GetPages NotImplemented\n");
1018 pPages
->pElems
= NULL
;
1023 //-------------------------------------------------------------------
1029 COutputPin::KsPinFactory(
1032 OutputDebugStringW(L
"COutputPin::KsPinFactory\n");
1033 *PinFactory
= m_PinId
;
1038 //-------------------------------------------------------------------
1046 IGraphBuilder
*pGraph
)
1048 OutputDebugStringW(L
"COutputPin::Render\n");
1054 COutputPin::Backout(
1056 IGraphBuilder
*pGraph
)
1058 OutputDebugStringW(L
"COutputPin::Backout\n");
1061 //-------------------------------------------------------------------
1066 COutputPin::KsGetObjectHandle()
1068 OutputDebugStringW(L
"COutputPin::KsGetObjectHandle\n");
1069 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1073 //-------------------------------------------------------------------
1078 COutputPin::KsProperty(
1079 PKSPROPERTY Property
,
1080 ULONG PropertyLength
,
1081 LPVOID PropertyData
,
1083 ULONG
* BytesReturned
)
1089 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1091 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
1093 StringFromCLSID(Property
->Set
, &pstr
);
1094 swprintf(Buffer
, L
"COutputPin::KsProperty Set %s Id %lu Flags %x hr %x\n", pstr
, Property
->Id
, Property
->Flags
, hr
);
1095 OutputDebugStringW(Buffer
);
1102 COutputPin::KsMethod(
1107 ULONG
* BytesReturned
)
1109 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1110 OutputDebugStringW(L
"COutputPin::KsMethod\n");
1111 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
1116 COutputPin::KsEvent(
1121 ULONG
* BytesReturned
)
1123 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1125 OutputDebugStringW(L
"COutputPin::KsEvent\n");
1128 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
1130 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
1134 //-------------------------------------------------------------------
1140 REFGUID guidPropSet
,
1142 LPVOID pInstanceData
,
1143 DWORD cbInstanceData
,
1147 ULONG BytesReturned
;
1151 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1153 return E_OUTOFMEMORY
;
1155 Property
->Set
= guidPropSet
;
1156 Property
->Id
= dwPropID
;
1157 Property
->Flags
= KSPROPERTY_TYPE_SET
;
1159 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1161 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1162 CoTaskMemFree(Property
);
1167 KSPROPERTY Property
;
1169 Property
.Set
= guidPropSet
;
1170 Property
.Id
= dwPropID
;
1171 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1173 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1181 REFGUID guidPropSet
,
1183 LPVOID pInstanceData
,
1184 DWORD cbInstanceData
,
1189 ULONG BytesReturned
;
1193 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1195 return E_OUTOFMEMORY
;
1197 Property
->Set
= guidPropSet
;
1198 Property
->Id
= dwPropID
;
1199 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1201 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1203 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1204 CoTaskMemFree(Property
);
1209 KSPROPERTY Property
;
1211 Property
.Set
= guidPropSet
;
1212 Property
.Id
= dwPropID
;
1213 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1215 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1222 COutputPin::QuerySupported(
1223 REFGUID guidPropSet
,
1225 DWORD
*pTypeSupport
)
1227 KSPROPERTY Property
;
1228 ULONG BytesReturned
;
1230 OutputDebugStringW(L
"COutputPin::QuerySupported\n");
1232 Property
.Set
= guidPropSet
;
1233 Property
.Id
= dwPropID
;
1234 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1236 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1240 //-------------------------------------------------------------------
1245 COutputPin::Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
)
1248 ALLOCATOR_PROPERTIES Properties
;
1249 IMemAllocatorCallbackTemp
*pMemCallback
;
1252 OutputDebugStringW(L
"COutputPin::Connect called\n");
1255 hr
= pReceivePin
->QueryAccept(pmt
);
1262 hr
= pReceivePin
->QueryAccept(&m_MediaFormat
);
1266 pmt
= &m_MediaFormat
;
1269 // query for IMemInput interface
1270 hr
= pReceivePin
->QueryInterface(IID_IMemInputPin
, (void**)&m_MemInputPin
);
1273 OutputDebugStringW(L
"COutputPin::Connect no IMemInputPin interface\n");
1278 // get input pin allocator properties
1279 ZeroMemory(&Properties
, sizeof(ALLOCATOR_PROPERTIES
));
1280 m_MemInputPin
->GetAllocatorRequirements(&Properties
);
1282 //FIXME determine allocator properties
1283 Properties
.cBuffers
= 16;
1284 Properties
.cbBuffer
= 2048 * 188; //2048 frames * MPEG2 TS Payload size
1285 Properties
.cbAlign
= 4;
1287 // get input pin allocator
1288 hr
= m_MemInputPin
->GetAllocator(&m_MemAllocator
);
1291 // set allocator properties
1292 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1294 m_MemAllocator
->Release();
1299 hr
= CKsAllocator_Constructor(NULL
, IID_IMemAllocator
, (void**)&m_MemAllocator
);
1303 // set allocator properties
1304 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1307 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::SetProperties failed with hr %lx\n", hr
);
1308 OutputDebugStringW(Buffer
);
1309 m_MemAllocator
->Release();
1310 m_MemInputPin
->Release();
1315 // commit property changes
1316 hr
= m_MemAllocator
->Commit();
1319 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::Commit failed with hr %lx\n", hr
);
1320 OutputDebugStringW(Buffer
);
1321 m_MemAllocator
->Release();
1322 m_MemInputPin
->Release();
1326 // get callback interface
1327 hr
= m_MemAllocator
->QueryInterface(IID_IMemAllocatorCallbackTemp
, (void**)&pMemCallback
);
1330 swprintf(Buffer
, L
"COutputPin::Connect No IMemAllocatorCallbackTemp interface hr %lx\n", hr
);
1331 OutputDebugStringW(Buffer
);
1332 m_MemAllocator
->Release();
1333 m_MemInputPin
->Release();
1337 // set notification routine
1338 hr
= pMemCallback
->SetNotify((IMemAllocatorNotifyCallbackTemp
*)this);
1340 // release IMemAllocatorNotifyCallbackTemp interface
1341 pMemCallback
->Release();
1345 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocatorNotifyCallbackTemp::SetNotify failed hr %lx\n", hr
);
1346 OutputDebugStringW(Buffer
);
1347 m_MemAllocator
->Release();
1348 m_MemInputPin
->Release();
1352 // now set allocator
1353 hr
= m_MemInputPin
->NotifyAllocator(m_MemAllocator
, TRUE
);
1356 swprintf(Buffer
, L
"COutputPin::Connect IMemInputPin::NotifyAllocator failed with hr %lx\n", hr
);
1357 OutputDebugStringW(Buffer
);
1358 m_MemAllocator
->Release();
1359 m_MemInputPin
->Release();
1365 //FIXME create pin handle
1369 // receive connection;
1370 hr
= pReceivePin
->ReceiveConnection((IPin
*)this, pmt
);
1373 // increment reference count
1374 pReceivePin
->AddRef();
1375 m_Pin
= pReceivePin
;
1376 OutputDebugStringW(L
"COutputPin::Connect success\n");
1380 m_MemInputPin
->Release();
1381 m_MemAllocator
->Release();
1389 COutputPin::ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
)
1391 return E_UNEXPECTED
;
1395 COutputPin::Disconnect( void)
1397 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1401 // pin was not connected
1406 //check if filter is active
1410 m_MemInputPin
->Release();
1411 m_MemAllocator
->Release();
1413 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1418 COutputPin::ConnectedTo(IPin
**pPin
)
1420 OutputDebugStringW(L
"COutputPin::ConnectedTo\n");
1427 // increment reference count
1434 return VFW_E_NOT_CONNECTED
;
1438 COutputPin::ConnectionMediaType(AM_MEDIA_TYPE
*pmt
)
1440 OutputDebugStringW(L
"COutputPin::ConnectionMediaType called\n");
1445 COutputPin::QueryPinInfo(PIN_INFO
*pInfo
)
1447 OutputDebugStringW(L
"COutputPin::QueryPinInfo\n");
1449 wcscpy(pInfo
->achName
, m_PinName
);
1450 pInfo
->dir
= PINDIR_OUTPUT
;
1451 pInfo
->pFilter
= m_ParentFilter
;
1452 m_ParentFilter
->AddRef();
1458 COutputPin::QueryDirection(PIN_DIRECTION
*pPinDir
)
1460 OutputDebugStringW(L
"COutputPin::QueryDirection\n");
1464 *pPinDir
= PINDIR_OUTPUT
;
1472 COutputPin::QueryId(LPWSTR
*Id
)
1474 OutputDebugStringW(L
"COutputPin::QueryId\n");
1476 *Id
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_PinName
)+1)*sizeof(WCHAR
));
1478 return E_OUTOFMEMORY
;
1480 wcscpy(*Id
, m_PinName
);
1485 COutputPin::QueryAccept(const AM_MEDIA_TYPE
*pmt
)
1487 OutputDebugStringW(L
"COutputPin::QueryAccept called\n");
1492 COutputPin::EnumMediaTypes(IEnumMediaTypes
**ppEnum
)
1495 ULONG MediaTypeCount
= 0, Index
;
1496 AM_MEDIA_TYPE
* MediaTypes
;
1499 OutputDebugStringW(L
"COutputPin::EnumMediaTypes called\n");
1501 if (!m_KsObjectParent
)
1504 return E_NOINTERFACE
;
1507 // get parent filter handle
1508 hFilter
= m_KsObjectParent
->KsGetObjectHandle();
1510 // query media type count
1511 hr
= KsGetMediaTypeCount(hFilter
, m_PinId
, &MediaTypeCount
);
1512 if (FAILED(hr
) || !MediaTypeCount
)
1514 OutputDebugStringW(L
"COutputPin::EnumMediaTypes failed1\n");
1518 // allocate media types
1519 MediaTypes
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1522 // not enough memory
1523 OutputDebugStringW(L
"COutputPin::EnumMediaTypes CoTaskMemAlloc\n");
1524 return E_OUTOFMEMORY
;
1528 ZeroMemory(MediaTypes
, sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1530 for(Index
= 0; Index
< MediaTypeCount
; Index
++)
1533 hr
= KsGetMediaType(Index
, &MediaTypes
[Index
], hFilter
, m_PinId
);
1537 CoTaskMemFree(MediaTypes
);
1538 OutputDebugStringW(L
"COutputPin::EnumMediaTypes failed\n");
1543 return CEnumMediaTypes_fnConstructor(MediaTypeCount
, MediaTypes
, IID_IEnumMediaTypes
, (void**)ppEnum
);
1547 COutputPin::QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
)
1549 OutputDebugStringW(L
"COutputPin::QueryInternalConnections called\n");
1554 COutputPin::EndOfStream( void)
1556 /* should be called only on input pins */
1557 return E_UNEXPECTED
;
1561 COutputPin::BeginFlush( void)
1563 /* should be called only on input pins */
1564 return E_UNEXPECTED
;
1568 COutputPin::EndFlush( void)
1570 /* should be called only on input pins */
1571 return E_UNEXPECTED
;
1575 COutputPin::NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
)
1579 // we are not connected
1580 return VFW_E_NOT_CONNECTED
;
1583 return m_Pin
->NewSegment(tStart
, tStop
, dRate
);
1586 //-------------------------------------------------------------------
1589 COutputPin::CheckFormat(
1590 const AM_MEDIA_TYPE
*pmt
)
1592 PKSMULTIPLE_ITEM MultipleItem
;
1593 PKSDATAFORMAT DataFormat
;
1599 HANDLE hFilter
= m_KsObjectParent
->KsGetObjectHandle();
1600 assert(hFilter
!= NULL
);
1602 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
1606 DataFormat
= (PKSDATAFORMAT
)(MultipleItem
+ 1);
1607 for(ULONG Index
= 0; Index
< MultipleItem
->Count
; Index
++)
1609 if (IsEqualGUID(pmt
->majortype
, DataFormat
->MajorFormat
) &&
1610 IsEqualGUID(pmt
->subtype
, DataFormat
->SubFormat
) &&
1611 IsEqualGUID(pmt
->formattype
, DataFormat
->Specifier
))
1613 // format is supported
1614 CoTaskMemFree(MultipleItem
);
1615 OutputDebugStringW(L
"COutputPin::CheckFormat format OK\n");
1618 DataFormat
= (PKSDATAFORMAT
)((ULONG_PTR
)DataFormat
+ DataFormat
->FormatSize
);
1620 //format is not supported
1621 CoTaskMemFree(MultipleItem
);
1627 COutputPin::CreatePin(
1628 const AM_MEDIA_TYPE
*pmt
)
1630 PKSMULTIPLE_ITEM MediumList
;
1631 PKSMULTIPLE_ITEM InterfaceList
;
1632 PKSPIN_MEDIUM Medium
;
1633 PKSPIN_INTERFACE Interface
;
1634 IKsInterfaceHandler
* InterfaceHandler
;
1637 // query for pin medium
1638 hr
= KsQueryMediums(&MediumList
);
1642 // query for pin interface
1643 hr
= KsQueryInterfaces(&InterfaceList
);
1647 CoTaskMemFree(MediumList
);
1651 if (MediumList
->Count
)
1653 //use first available medium
1654 Medium
= (PKSPIN_MEDIUM
)(MediumList
+ 1);
1658 // default to standard medium
1659 Medium
= &StandardPinMedium
;
1662 if (InterfaceList
->Count
)
1664 //use first available interface
1665 Interface
= (PKSPIN_INTERFACE
)(InterfaceList
+ 1);
1669 // default to standard interface
1670 Interface
= &StandardPinInterface
;
1673 if (m_Communication
!= KSPIN_COMMUNICATION_BRIDGE
&& m_Communication
!= KSPIN_COMMUNICATION_NONE
)
1676 hr
= CreatePinHandle(Medium
, Interface
, pmt
);
1679 m_InterfaceHandler
->Release();
1680 m_InterfaceHandler
= InterfaceHandler
;
1683 if (!m_InterfaceHandler
)
1685 // now load the IKsInterfaceHandler plugin
1686 hr
= CoCreateInstance(Interface
->Set
, NULL
, CLSCTX_INPROC_SERVER
, IID_IKsInterfaceHandler
, (void**)&InterfaceHandler
);
1689 // failed to load interface handler plugin
1690 OutputDebugStringW(L
"COutputPin::CreatePin failed to load InterfaceHandlerPlugin\n");
1691 CoTaskMemFree(MediumList
);
1692 CoTaskMemFree(InterfaceList
);
1698 hr
= InterfaceHandler
->KsSetPin((IKsPin
*)this);
1701 // failed to load interface handler plugin
1702 OutputDebugStringW(L
"COutputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n");
1703 InterfaceHandler
->Release();
1704 CoTaskMemFree(MediumList
);
1705 CoTaskMemFree(InterfaceList
);
1709 // store interface handler
1710 m_InterfaceHandler
= InterfaceHandler
;
1716 swprintf(Buffer
, L
"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication
, m_PinName
);
1717 OutputDebugStringW(Buffer
);
1722 // free medium / interface / dataformat
1723 CoTaskMemFree(MediumList
);
1724 CoTaskMemFree(InterfaceList
);
1731 COutputPin::CreatePinHandle(
1732 PKSPIN_MEDIUM Medium
,
1733 PKSPIN_INTERFACE Interface
,
1734 const AM_MEDIA_TYPE
*pmt
)
1736 PKSPIN_CONNECT PinConnect
;
1737 PKSDATAFORMAT DataFormat
;
1740 //KSALLOCATOR_FRAMING Framing;
1741 //KSPROPERTY Property;
1742 //ULONG BytesReturned;
1744 if (m_hPin
!= INVALID_HANDLE_VALUE
)
1746 // pin already exists
1747 //CloseHandle(m_hPin);
1748 //m_hPin = INVALID_HANDLE_VALUE;
1754 Length
= sizeof(KSPIN_CONNECT
) + sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
1756 // allocate pin connect
1757 PinConnect
= (PKSPIN_CONNECT
)CoTaskMemAlloc(Length
);
1761 return E_OUTOFMEMORY
;
1765 CopyMemory(&PinConnect
->Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
1766 CopyMemory(&PinConnect
->Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
1767 PinConnect
->PinId
= m_PinId
;
1768 PinConnect
->PinToHandle
= NULL
;
1769 PinConnect
->Priority
.PriorityClass
= KSPRIORITY_NORMAL
;
1770 PinConnect
->Priority
.PrioritySubClass
= KSPRIORITY_NORMAL
;
1772 // get dataformat offset
1773 DataFormat
= (PKSDATAFORMAT
)(PinConnect
+ 1);
1776 DataFormat
->FormatSize
= sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
1777 DataFormat
->Flags
= 0;
1778 DataFormat
->SampleSize
= pmt
->lSampleSize
;
1779 DataFormat
->Reserved
= 0;
1780 CopyMemory(&DataFormat
->MajorFormat
, &pmt
->majortype
, sizeof(GUID
));
1781 CopyMemory(&DataFormat
->SubFormat
, &pmt
->subtype
, sizeof(GUID
));
1782 CopyMemory(&DataFormat
->Specifier
, &pmt
->formattype
, sizeof(GUID
));
1786 // copy extended format
1787 CopyMemory((DataFormat
+ 1), pmt
->pbFormat
, pmt
->cbFormat
);
1790 HANDLE hFilter
= m_KsObjectParent
->KsGetObjectHandle();
1791 assert(hFilter
!= NULL
);
1794 hr
= KsCreatePin(hFilter
, PinConnect
, GENERIC_READ
, &m_hPin
);
1798 // store current interface / medium
1799 CopyMemory(&m_Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
1800 CopyMemory(&m_Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
1801 CopyMemory(&m_MediaFormat
, pmt
, sizeof(AM_MEDIA_TYPE
));
1803 LPOLESTR pMajor
, pSub
, pFormat
;
1804 StringFromIID(m_MediaFormat
.majortype
, &pMajor
);
1805 StringFromIID(m_MediaFormat
.subtype
, &pSub
);
1806 StringFromIID(m_MediaFormat
.formattype
, &pFormat
);
1808 swprintf(Buffer
, L
"COutputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor
, pSub
, pFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
1809 CoTaskMemFree(pMajor
);
1810 CoTaskMemFree(pSub
);
1811 CoTaskMemFree(pFormat
);
1812 OutputDebugStringW(Buffer
);
1816 m_MediaFormat
.pbFormat
= (BYTE
*)CoTaskMemAlloc(pmt
->cbFormat
);
1817 if (!m_MediaFormat
.pbFormat
)
1819 CoTaskMemFree(PinConnect
);
1820 m_MediaFormat
.pbFormat
= NULL
;
1821 m_MediaFormat
.cbFormat
= 0;
1822 return E_OUTOFMEMORY
;
1824 CopyMemory(m_MediaFormat
.pbFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
1827 Property
.Set
= KSPROPSETID_Connection
;
1828 Property
.Id
= KSPROPERTY_CONNECTION_ALLOCATORFRAMING
;
1829 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1831 ZeroMemory(&Framing
, sizeof(KSALLOCATOR_FRAMING
));
1832 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (PVOID
)&Framing
, sizeof(KSALLOCATOR_FRAMING
), &BytesReturned
);
1835 m_Properties
.cbAlign
= (Framing
.FileAlignment
+ 1);
1836 m_Properties
.cbBuffer
= Framing
.FrameSize
;
1837 m_Properties
.cbPrefix
= 0; //FIXME
1838 m_Properties
.cBuffers
= Framing
.Frames
;
1843 if (FAILED(InitializeIOThread()))
1845 OutputDebugStringW(L
"COutputPin::CreatePinHandle failed to initialize i/o thread\n");
1850 // connect pin pipes
1854 CoTaskMemFree(PinConnect
);
1861 COutputPin::IoProcessRoutine()
1863 IMediaSample
*Sample
;
1866 PKSSTREAM_SEGMENT StreamSegment
;
1869 IMediaSample
* Samples
[1];
1871 // first wait for the start event to signal
1872 WaitForSingleObject(m_hStartEvent
, INFINITE
);
1874 assert(m_InterfaceHandler
);
1875 REFERENCE_TIME Start
= 0;
1876 REFERENCE_TIME Stop
= 1;
1879 if (m_StopInProgress
)
1886 hr
= m_MemAllocator
->GetBuffer(&Sample
, NULL
, NULL
, AM_GBF_NOWAIT
);
1890 m_Pin
->BeginFlush();
1891 OutputDebugStringW(L
"Beginning flushing...\n");
1892 WaitForSingleObject(m_hBufferAvailable
, INFINITE
);
1900 Samples
[0] = Sample
;
1903 Sample
->SetTime(&Start
, &Stop
);
1904 hr
= m_InterfaceHandler
->KsProcessMediaSamples(NULL
, /* FIXME */
1909 if (FAILED(hr
) || !StreamSegment
)
1911 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine KsProcessMediaSamples PinName %s hr %lx StreamSegment %p\n", m_PinName
, hr
, StreamSegment
);
1912 OutputDebugStringW(Buffer
);
1916 // get completion event
1917 hEvent
= StreamSegment
->CompletionEvent
;
1919 // wait for i/o completion
1920 WaitForSingleObject(hEvent
, INFINITE
);
1922 // perform completion
1923 m_InterfaceHandler
->KsCompleteIo(StreamSegment
);
1925 // close completion event
1926 CloseHandle(hEvent
);
1930 Sample
->GetTime(&Start
, &Stop
);
1934 // now deliver the sample
1935 hr
= m_MemInputPin
->Receive(Sample
);
1937 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine IMemInputPin::Receive hr %lx Start %I64u Stop %I64u\n", hr
, Start
, Stop
);
1938 OutputDebugStringW(Buffer
);
1942 // signal end of i/o thread
1943 SetEvent(m_hStopEvent
);
1945 m_IoThreadStarted
= false;
1952 COutputPin_IoThreadStartup(
1955 COutputPin
* Pin
= (COutputPin
*)lpParameter
;
1958 return Pin
->IoProcessRoutine();
1964 COutputPin::InitializeIOThread()
1968 if (m_IoThreadStarted
)
1972 m_hStartEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1974 ResetEvent(m_hStartEvent
);
1977 return E_OUTOFMEMORY
;
1980 m_hStopEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1982 ResetEvent(m_hStopEvent
);
1985 return E_OUTOFMEMORY
;
1987 if (!m_hBufferAvailable
)
1988 m_hBufferAvailable
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1990 ResetEvent(m_hBufferAvailable
);
1992 if (!m_hBufferAvailable
)
1993 return E_OUTOFMEMORY
;
1995 m_StopInProgress
= false;
1996 m_IoThreadStarted
= true;
1998 // now create the startup thread
1999 hThread
= CreateThread(NULL
, 0, COutputPin_IoThreadStartup
, (LPVOID
)this, 0, NULL
);
2001 return E_OUTOFMEMORY
;
2004 // close thread handle
2005 CloseHandle(hThread
);
2011 COutputPin_SetState(
2016 KSPROPERTY Property
;
2019 ULONG BytesReturned
;
2021 COutputPin
* pPin
= (COutputPin
*)Pin
;
2024 Property
.Set
= KSPROPSETID_Connection
;
2025 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
2026 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2029 if (pPin
->m_State
< State
)
2031 if (pPin
->m_State
== KSSTATE_STOP
)
2033 CurState
= KSSTATE_ACQUIRE
;
2034 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2036 swprintf(Buffer
, L
"COutputPin_SetState Setting State KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2037 OutputDebugStringW(Buffer
);
2041 pPin
->m_State
= CurState
;
2043 if (pPin
->m_State
== State
)
2046 if (pPin
->m_State
== KSSTATE_ACQUIRE
)
2048 CurState
= KSSTATE_PAUSE
;
2049 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2051 swprintf(Buffer
, L
"COutputPin_SetState Setting State KSSTATE_PAUSE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2052 OutputDebugStringW(Buffer
);
2056 pPin
->m_State
= CurState
;
2058 if (pPin
->m_State
== State
)
2062 CurState
= KSSTATE_RUN
;
2063 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2065 swprintf(Buffer
, L
"COutputPin_SetState Setting State KSSTATE_RUN PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2066 OutputDebugStringW(Buffer
);
2070 // signal start event
2071 SetEvent(pPin
->m_hStartEvent
);
2074 pPin
->m_State
= CurState
;
2079 if (pPin
->m_State
== KSSTATE_RUN
)
2081 CurState
= KSSTATE_PAUSE
;
2082 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2084 swprintf(Buffer
, L
"COutputPin_SetState Setting State KSSTATE_PAUSE PinName %u hr %lx\n", pPin
->m_PinName
, hr
);
2085 OutputDebugStringW(Buffer
);
2089 pPin
->m_State
= CurState
;
2091 if (pPin
->m_State
== State
)
2094 if (pPin
->m_State
== KSSTATE_PAUSE
)
2096 CurState
= KSSTATE_ACQUIRE
;
2097 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2099 swprintf(Buffer
, L
"COutputPin_SetState Setting State KSSTATE_ACQUIRE PinName %u hr %lx\n", pPin
->m_PinName
, hr
);
2100 OutputDebugStringW(Buffer
);
2104 pPin
->m_State
= CurState
;
2106 if (pPin
->m_State
== State
)
2110 // setting pending stop flag
2111 pPin
->m_StopInProgress
= true;
2113 CurState
= KSSTATE_STOP
;
2114 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2116 swprintf(Buffer
, L
"COutputPin_SetState Setting State KSSTATE_STOP PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2117 OutputDebugStringW(Buffer
);
2121 // wait until i/o thread is done
2122 WaitForSingleObject(pPin
->m_hStopEvent
, INFINITE
);
2124 pPin
->m_State
= CurState
;
2132 COutputPin_Constructor(
2133 IBaseFilter
* ParentFilter
,
2136 KSPIN_COMMUNICATION Communication
,
2140 COutputPin
* handler
= new COutputPin(ParentFilter
, PinName
, PinId
, Communication
);
2143 return E_OUTOFMEMORY
;
2145 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
2149 return E_NOINTERFACE
;