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
;
176 IKsAllocatorEx
* m_KsAllocatorEx
;
177 ULONG m_PipeAllocatorFlag
;
178 BOOL m_bPinBusCacheInitialized
;
181 FRAMING_PROP m_FramingProp
[4];
182 PKSALLOCATOR_FRAMING_EX m_FramingEx
[4];
184 IMemAllocator
* m_MemAllocator
;
185 IMemInputPin
* m_MemInputPin
;
187 KSPIN_COMMUNICATION m_Communication
;
188 KSPIN_INTERFACE m_Interface
;
189 KSPIN_MEDIUM m_Medium
;
190 AM_MEDIA_TYPE m_MediaFormat
;
191 ALLOCATOR_PROPERTIES m_Properties
;
192 IKsInterfaceHandler
* m_InterfaceHandler
;
194 HANDLE m_hStartEvent
;
195 HANDLE m_hBufferAvailable
;
197 BOOL m_StopInProgress
;
198 BOOL m_IoThreadStarted
;
201 CRITICAL_SECTION m_Lock
;
204 COutputPin::~COutputPin()
208 COutputPin::COutputPin(
209 IBaseFilter
* ParentFilter
,
212 KSPIN_COMMUNICATION Communication
) : m_Ref(0),
213 m_ParentFilter(ParentFilter
),
215 m_hPin(INVALID_HANDLE_VALUE
),
219 m_PipeAllocatorFlag(0),
220 m_bPinBusCacheInitialized(0),
225 m_Communication(Communication
),
226 m_InterfaceHandler(0),
228 m_hBufferAvailable(0),
231 m_IoThreadStarted(0),
232 m_State(KSSTATE_STOP
)
235 IKsObject
* KsObjectParent
;
237 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
240 ZeroMemory(m_FramingProp
, sizeof(m_FramingProp
));
241 ZeroMemory(m_FramingEx
, sizeof(m_FramingEx
));
243 hr
= KsGetMediaType(0, &m_MediaFormat
, KsObjectParent
->KsGetObjectHandle(), m_PinId
);
246 InitializeCriticalSection(&m_Lock
);
248 KsObjectParent
->Release();
253 COutputPin::QueryInterface(
258 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
259 IsEqualGUID(refiid
, IID_IPin
))
262 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IPin\n");
264 *Output
= PVOID(this);
265 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
268 else if (IsEqualGUID(refiid
, IID_IKsObject
))
270 if (m_hPin
== INVALID_HANDLE_VALUE
)
272 HRESULT hr
= CreatePin(&m_MediaFormat
);
277 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsObject\n");
279 *Output
= (IKsObject
*)(this);
280 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
283 else if (IsEqualGUID(refiid
, IID_IKsPin
) || IsEqualGUID(refiid
, IID_IKsPinEx
))
285 *Output
= (IKsPinEx
*)(this);
286 reinterpret_cast<IKsPinEx
*>(*Output
)->AddRef();
289 else if (IsEqualGUID(refiid
, IID_IKsPinPipe
))
291 *Output
= (IKsPinPipe
*)(this);
292 reinterpret_cast<IKsPinPipe
*>(*Output
)->AddRef();
295 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
297 *Output
= (IKsAggregateControl
*)(this);
298 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
301 else if (IsEqualGUID(refiid
, IID_IQualityControl
))
303 *Output
= (IQualityControl
*)(this);
304 reinterpret_cast<IQualityControl
*>(*Output
)->AddRef();
307 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
309 if (m_hPin
== INVALID_HANDLE_VALUE
)
311 HRESULT hr
= CreatePin(&m_MediaFormat
);
316 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPropertySet\n");
318 *Output
= (IKsPropertySet
*)(this);
319 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
322 else if (IsEqualGUID(refiid
, IID_IKsControl
))
325 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsControl\n");
327 *Output
= (IKsControl
*)(this);
328 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
332 else if (IsEqualGUID(refiid
, IID_IStreamBuilder
))
334 *Output
= (IStreamBuilder
*)(this);
335 reinterpret_cast<IStreamBuilder
*>(*Output
)->AddRef();
339 else if (IsEqualGUID(refiid
, IID_IKsPinFactory
))
342 OutputDebugStringW(L
"COutputPin::QueryInterface IID_IKsPinFactory\n");
344 *Output
= (IKsPinFactory
*)(this);
345 reinterpret_cast<IKsPinFactory
*>(*Output
)->AddRef();
348 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
351 OutputDebugStringW(L
"COutputPin::QueryInterface IID_ISpecifyPropertyPages\n");
353 *Output
= (ISpecifyPropertyPages
*)(this);
354 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
357 else if (IsEqualGUID(refiid
, IID_IMediaSeeking
))
359 *Output
= (IMediaSeeking
*)(this);
360 reinterpret_cast<IMediaSeeking
*>(*Output
)->AddRef();
363 else if (IsEqualGUID(refiid
, IID_IAMBufferNegotiation
))
365 *Output
= (IAMBufferNegotiation
*)(this);
366 reinterpret_cast<IAMBufferNegotiation
*>(*Output
)->AddRef();
369 else if (IsEqualGUID(refiid
, IID_IAMStreamConfig
))
371 *Output
= (IAMStreamConfig
*)(this);
372 reinterpret_cast<IAMStreamConfig
*>(*Output
)->AddRef();
375 else if (IsEqualGUID(refiid
, IID_IMemAllocatorNotifyCallbackTemp
))
377 *Output
= (IMemAllocatorNotifyCallbackTemp
*)(this);
378 reinterpret_cast<IMemAllocatorNotifyCallbackTemp
*>(*Output
)->AddRef();
383 WCHAR Buffer
[MAX_PATH
];
385 StringFromCLSID(refiid
, &lpstr
);
386 swprintf(Buffer
, L
"COutputPin::QueryInterface: NoInterface for %s PinId %u PinName %s\n", lpstr
, m_PinId
, m_PinName
);
387 OutputDebugStringW(Buffer
);
388 CoTaskMemFree(lpstr
);
391 return E_NOINTERFACE
;
394 //-------------------------------------------------------------------
395 // IAMBufferNegotiation interface
399 COutputPin::SuggestAllocatorProperties(
400 const ALLOCATOR_PROPERTIES
*pprop
)
403 OutputDebugStringW(L
"COutputPin::SuggestAllocatorProperties\n");
408 // pin is already connected
409 return VFW_E_ALREADY_CONNECTED
;
412 CopyMemory(&m_Properties
, pprop
, sizeof(ALLOCATOR_PROPERTIES
));
418 COutputPin::GetAllocatorProperties(
419 ALLOCATOR_PROPERTIES
*pprop
)
422 OutputDebugStringW(L
"COutputPin::GetAllocatorProperties\n");
427 // you should call this method AFTER you connected
431 if (!m_KsAllocatorEx
)
433 // something went wrong while creating the allocator
437 CopyMemory(pprop
, &m_Properties
, sizeof(ALLOCATOR_PROPERTIES
));
441 //-------------------------------------------------------------------
442 // IAMStreamConfig interface
446 COutputPin::SetFormat(
450 OutputDebugStringW(L
"COutputPin::SetFormat NotImplemented\n");
457 COutputPin::GetFormat(AM_MEDIA_TYPE
**ppmt
)
460 OutputDebugStringW(L
"COutputPin::GetFormat NotImplemented\n");
467 COutputPin::GetNumberOfCapabilities(
472 OutputDebugStringW(L
"COutputPin::GetNumberOfCapabilities NotImplemented\n");
479 COutputPin::GetStreamCaps(
481 AM_MEDIA_TYPE
**ppmt
,
485 OutputDebugStringW(L
"COutputPin::GetStreamCaps NotImplemented\n");
490 //-------------------------------------------------------------------
491 // IMemAllocatorNotifyCallbackTemp interface
495 COutputPin::NotifyRelease()
498 OutputDebugStringW(L
"COutputPin::NotifyRelease\n");
501 // notify thread of new available sample
502 SetEvent(m_hBufferAvailable
);
507 //-------------------------------------------------------------------
508 // IMediaSeeking interface
512 COutputPin::GetCapabilities(
513 DWORD
*pCapabilities
)
515 IMediaSeeking
* FilterMediaSeeking
;
518 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
522 hr
= FilterMediaSeeking
->GetCapabilities(pCapabilities
);
524 FilterMediaSeeking
->Release();
530 COutputPin::CheckCapabilities(
531 DWORD
*pCapabilities
)
533 IMediaSeeking
* FilterMediaSeeking
;
536 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
540 hr
= FilterMediaSeeking
->CheckCapabilities(pCapabilities
);
542 FilterMediaSeeking
->Release();
548 COutputPin::IsFormatSupported(
551 IMediaSeeking
* FilterMediaSeeking
;
554 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
558 hr
= FilterMediaSeeking
->IsFormatSupported(pFormat
);
560 FilterMediaSeeking
->Release();
566 COutputPin::QueryPreferredFormat(
569 IMediaSeeking
* FilterMediaSeeking
;
572 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
576 hr
= FilterMediaSeeking
->QueryPreferredFormat(pFormat
);
578 FilterMediaSeeking
->Release();
584 COutputPin::GetTimeFormat(
587 IMediaSeeking
* FilterMediaSeeking
;
590 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
594 hr
= FilterMediaSeeking
->GetTimeFormat(pFormat
);
596 FilterMediaSeeking
->Release();
602 COutputPin::IsUsingTimeFormat(
605 IMediaSeeking
* FilterMediaSeeking
;
608 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
612 hr
= FilterMediaSeeking
->IsUsingTimeFormat(pFormat
);
614 FilterMediaSeeking
->Release();
620 COutputPin::SetTimeFormat(
623 IMediaSeeking
* FilterMediaSeeking
;
626 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
630 hr
= FilterMediaSeeking
->SetTimeFormat(pFormat
);
632 FilterMediaSeeking
->Release();
638 COutputPin::GetDuration(
641 IMediaSeeking
* FilterMediaSeeking
;
644 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
648 hr
= FilterMediaSeeking
->GetDuration(pDuration
);
650 FilterMediaSeeking
->Release();
656 COutputPin::GetStopPosition(
659 IMediaSeeking
* FilterMediaSeeking
;
662 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
666 hr
= FilterMediaSeeking
->GetStopPosition(pStop
);
668 FilterMediaSeeking
->Release();
675 COutputPin::GetCurrentPosition(
678 IMediaSeeking
* FilterMediaSeeking
;
681 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
685 hr
= FilterMediaSeeking
->GetCurrentPosition(pCurrent
);
687 FilterMediaSeeking
->Release();
693 COutputPin::ConvertTimeFormat(
695 const GUID
*pTargetFormat
,
697 const GUID
*pSourceFormat
)
699 IMediaSeeking
* FilterMediaSeeking
;
702 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
706 hr
= FilterMediaSeeking
->ConvertTimeFormat(pTarget
, pTargetFormat
, Source
, pSourceFormat
);
708 FilterMediaSeeking
->Release();
714 COutputPin::SetPositions(
716 DWORD dwCurrentFlags
,
720 IMediaSeeking
* FilterMediaSeeking
;
723 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
727 hr
= FilterMediaSeeking
->SetPositions(pCurrent
, dwCurrentFlags
, pStop
, dwStopFlags
);
729 FilterMediaSeeking
->Release();
735 COutputPin::GetPositions(
739 IMediaSeeking
* FilterMediaSeeking
;
742 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
746 hr
= FilterMediaSeeking
->GetPositions(pCurrent
, pStop
);
748 FilterMediaSeeking
->Release();
754 COutputPin::GetAvailable(
758 IMediaSeeking
* FilterMediaSeeking
;
761 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
765 hr
= FilterMediaSeeking
->GetAvailable(pEarliest
, pLatest
);
767 FilterMediaSeeking
->Release();
776 IMediaSeeking
* FilterMediaSeeking
;
779 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
783 hr
= FilterMediaSeeking
->SetRate(dRate
);
785 FilterMediaSeeking
->Release();
794 IMediaSeeking
* FilterMediaSeeking
;
797 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
801 hr
= FilterMediaSeeking
->GetRate(pdRate
);
803 FilterMediaSeeking
->Release();
809 COutputPin::GetPreroll(
810 LONGLONG
*pllPreroll
)
812 IMediaSeeking
* FilterMediaSeeking
;
815 hr
= m_ParentFilter
->QueryInterface(IID_IMediaSeeking
, (LPVOID
*)&FilterMediaSeeking
);
819 hr
= FilterMediaSeeking
->GetPreroll(pllPreroll
);
821 FilterMediaSeeking
->Release();
825 //-------------------------------------------------------------------
826 // IQualityControl interface
835 OutputDebugStringW(L
"COutputPin::Notify NotImplemented\n");
843 IQualityControl
*piqc
)
846 OutputDebugStringW(L
"COutputPin::SetSink NotImplemented\n");
852 //-------------------------------------------------------------------
853 // IKsAggregateControl interface
857 COutputPin::KsAddAggregate(
858 IN REFGUID AggregateClass
)
861 OutputDebugStringW(L
"COutputPin::KsAddAggregate NotImplemented\n");
868 COutputPin::KsRemoveAggregate(
869 REFGUID AggregateClass
)
872 OutputDebugStringW(L
"COutputPin::KsRemoveAggregate NotImplemented\n");
878 //-------------------------------------------------------------------
884 COutputPin::KsQueryMediums(
885 PKSMULTIPLE_ITEM
* MediumList
)
889 IKsObject
* KsObjectParent
;
891 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
893 return E_NOINTERFACE
;
895 hFilter
= KsObjectParent
->KsGetObjectHandle();
898 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_MEDIUMS
, (PVOID
*)MediumList
);
902 KsObjectParent
->Release();
909 COutputPin::KsQueryInterfaces(
910 PKSMULTIPLE_ITEM
* InterfaceList
)
914 IKsObject
* KsObjectParent
;
916 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
920 hFilter
= KsObjectParent
->KsGetObjectHandle();
923 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_INTERFACES
, (PVOID
*)InterfaceList
);
927 KsObjectParent
->Release();
934 COutputPin::KsCreateSinkPinHandle(
935 KSPIN_INTERFACE
& Interface
,
936 KSPIN_MEDIUM
& Medium
)
939 OutputDebugStringW(L
"COutputPin::KsCreateSinkPinHandle NotImplemented\n");
946 COutputPin::KsGetCurrentCommunication(
947 KSPIN_COMMUNICATION
*Communication
,
948 KSPIN_INTERFACE
*Interface
,
949 KSPIN_MEDIUM
*Medium
)
953 *Communication
= m_Communication
;
959 return VFW_E_NOT_CONNECTED
;
961 CopyMemory(Interface
, &m_Interface
, sizeof(KSPIN_INTERFACE
));
967 return VFW_E_NOT_CONNECTED
;
969 CopyMemory(Medium
, &m_Medium
, sizeof(KSPIN_MEDIUM
));
976 COutputPin::KsPropagateAcquire()
984 OutputDebugStringW(L
"COutputPin::KsPropagateAcquire\n");
987 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
989 Property
.Set
= KSPROPSETID_Connection
;
990 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
991 Property
.Flags
= KSPROPERTY_TYPE_SET
;
993 State
= KSSTATE_ACQUIRE
;
995 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (LPVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
1002 //propagate to connected pin on the pipe
1009 COutputPin::KsDeliver(
1010 IMediaSample
* Sample
,
1018 COutputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
)
1025 COutputPin::KsPeekAllocator(KSPEEKOPERATION Operation
)
1027 if (Operation
== KsPeekOperation_AddRef
)
1029 // add reference on allocator
1030 m_MemAllocator
->AddRef();
1033 return m_MemAllocator
;
1038 COutputPin::KsReceiveAllocator(IMemAllocator
*MemAllocator
)
1042 MemAllocator
->AddRef();
1047 m_MemAllocator
->Release();
1050 m_MemAllocator
= MemAllocator
;
1056 COutputPin::KsRenegotiateAllocator()
1063 COutputPin::KsIncrementPendingIoCount()
1065 return InterlockedIncrement((volatile LONG
*)&m_IoCount
);
1070 COutputPin::KsDecrementPendingIoCount()
1072 return InterlockedDecrement((volatile LONG
*)&m_IoCount
);
1077 COutputPin::KsQualityNotify(
1079 REFERENCE_TIME TimeDelta
)
1081 #ifdef KSPROXY_TRACE
1082 OutputDebugStringW(L
"COutputPin::KsQualityNotify NotImplemented\n");
1087 //-------------------------------------------------------------------
1093 COutputPin::KsNotifyError(
1094 IMediaSample
* Sample
,
1097 #ifdef KSPROXY_TRACE
1098 OutputDebugStringW(L
"COutputPin::KsNotifyError NotImplemented\n");
1103 //-------------------------------------------------------------------
1109 COutputPin::KsGetPinFramingCache(
1110 PKSALLOCATOR_FRAMING_EX
*FramingEx
,
1111 PFRAMING_PROP FramingProp
,
1112 FRAMING_CACHE_OPS Option
)
1114 if (Option
> Framing_Cache_Write
|| Option
< Framing_Cache_ReadLast
)
1117 return E_INVALIDARG
;
1120 // get framing properties
1121 *FramingProp
= m_FramingProp
[Option
];
1122 *FramingEx
= m_FramingEx
[Option
];
1129 COutputPin::KsSetPinFramingCache(
1130 PKSALLOCATOR_FRAMING_EX FramingEx
,
1131 PFRAMING_PROP FramingProp
,
1132 FRAMING_CACHE_OPS Option
)
1137 if (m_FramingEx
[Option
])
1139 for(Index
= 1; Index
< 4; Index
++)
1141 if (m_FramingEx
[Index
] == m_FramingEx
[Option
])
1147 // existing framing is only used once
1148 CoTaskMemFree(m_FramingEx
[Option
]);
1153 m_FramingEx
[Option
] = FramingEx
;
1154 m_FramingProp
[Option
] = *FramingProp
;
1161 COutputPin::KsGetConnectedPin()
1168 COutputPin::KsGetPipe(
1169 KSPEEKOPERATION Operation
)
1171 if (Operation
== KsPeekOperation_AddRef
)
1173 if (m_KsAllocatorEx
)
1174 m_KsAllocatorEx
->AddRef();
1176 return m_KsAllocatorEx
;
1181 COutputPin::KsSetPipe(
1182 IKsAllocatorEx
*KsAllocator
)
1185 KsAllocator
->AddRef();
1187 if (m_KsAllocatorEx
)
1188 m_KsAllocatorEx
->Release();
1190 m_KsAllocatorEx
= KsAllocator
;
1196 COutputPin::KsGetPipeAllocatorFlag()
1198 return m_PipeAllocatorFlag
;
1204 COutputPin::KsSetPipeAllocatorFlag(
1207 m_PipeAllocatorFlag
= Flag
;
1213 COutputPin::KsGetPinBusCache()
1215 if (!m_bPinBusCacheInitialized
)
1217 CopyMemory(&m_PinBusCache
, &m_Medium
.Set
, sizeof(GUID
));
1218 m_bPinBusCacheInitialized
= TRUE
;
1221 return m_PinBusCache
;
1226 COutputPin::KsSetPinBusCache(
1229 CopyMemory(&m_PinBusCache
, &Bus
, sizeof(GUID
));
1235 COutputPin::KsGetPinName()
1237 return (PWCHAR
)m_PinName
;
1243 COutputPin::KsGetFilterName()
1245 return m_FilterName
;
1248 //-------------------------------------------------------------------
1249 // ISpecifyPropertyPages
1254 COutputPin::GetPages(CAUUID
*pPages
)
1256 #ifdef KSPROXY_TRACE
1257 OutputDebugStringW(L
"COutputPin::GetPages NotImplemented\n");
1264 pPages
->pElems
= NULL
;
1269 //-------------------------------------------------------------------
1275 COutputPin::KsPinFactory(
1278 #ifdef KSPROXY_TRACE
1279 OutputDebugStringW(L
"COutputPin::KsPinFactory\n");
1282 *PinFactory
= m_PinId
;
1287 //-------------------------------------------------------------------
1295 IGraphBuilder
*pGraph
)
1297 #ifdef KSPROXY_TRACE
1298 OutputDebugStringW(L
"COutputPin::Render\n");
1305 COutputPin::Backout(
1307 IGraphBuilder
*pGraph
)
1309 #ifdef KSPROXY_TRACE
1310 OutputDebugStringW(L
"COutputPin::Backout\n");
1315 //-------------------------------------------------------------------
1320 COutputPin::KsGetObjectHandle()
1322 #ifdef KSPROXY_TRACE
1323 OutputDebugStringW(L
"COutputPin::KsGetObjectHandle\n");
1326 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1330 //-------------------------------------------------------------------
1335 COutputPin::KsProperty(
1336 PKSPROPERTY Property
,
1337 ULONG PropertyLength
,
1338 LPVOID PropertyData
,
1340 ULONG
* BytesReturned
)
1344 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1346 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
1347 #ifdef KSPROXY_TRACE
1350 StringFromCLSID(Property
->Set
, &pstr
);
1351 swprintf(Buffer
, L
"COutputPin::KsProperty Set %s Id %lu Flags %x hr %x\n", pstr
, Property
->Id
, Property
->Flags
, hr
);
1352 OutputDebugStringW(Buffer
);
1360 COutputPin::KsMethod(
1365 ULONG
* BytesReturned
)
1367 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1368 #ifdef KSPROXY_TRACE
1369 OutputDebugStringW(L
"COutputPin::KsMethod\n");
1371 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
1376 COutputPin::KsEvent(
1381 ULONG
* BytesReturned
)
1383 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
1385 #ifdef KSPROXY_TRACE
1386 OutputDebugStringW(L
"COutputPin::KsEvent\n");
1390 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
1392 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
1396 //-------------------------------------------------------------------
1402 REFGUID guidPropSet
,
1404 LPVOID pInstanceData
,
1405 DWORD cbInstanceData
,
1409 ULONG BytesReturned
;
1413 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1415 return E_OUTOFMEMORY
;
1417 Property
->Set
= guidPropSet
;
1418 Property
->Id
= dwPropID
;
1419 Property
->Flags
= KSPROPERTY_TYPE_SET
;
1421 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1423 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1424 CoTaskMemFree(Property
);
1429 KSPROPERTY Property
;
1431 Property
.Set
= guidPropSet
;
1432 Property
.Id
= dwPropID
;
1433 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1435 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1443 REFGUID guidPropSet
,
1445 LPVOID pInstanceData
,
1446 DWORD cbInstanceData
,
1451 ULONG BytesReturned
;
1455 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1457 return E_OUTOFMEMORY
;
1459 Property
->Set
= guidPropSet
;
1460 Property
->Id
= dwPropID
;
1461 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1463 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1465 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1466 CoTaskMemFree(Property
);
1471 KSPROPERTY Property
;
1473 Property
.Set
= guidPropSet
;
1474 Property
.Id
= dwPropID
;
1475 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1477 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1484 COutputPin::QuerySupported(
1485 REFGUID guidPropSet
,
1487 DWORD
*pTypeSupport
)
1489 KSPROPERTY Property
;
1490 ULONG BytesReturned
;
1492 #ifdef KSPROXY_TRACE
1493 OutputDebugStringW(L
"COutputPin::QuerySupported\n");
1496 Property
.Set
= guidPropSet
;
1497 Property
.Id
= dwPropID
;
1498 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1500 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1504 //-------------------------------------------------------------------
1509 COutputPin::Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
)
1512 ALLOCATOR_PROPERTIES Properties
;
1513 IMemAllocatorCallbackTemp
*pMemCallback
;
1515 #ifdef KSPROXY_TRACE
1517 OutputDebugStringW(L
"COutputPin::Connect called\n");
1522 hr
= pReceivePin
->QueryAccept(pmt
);
1529 hr
= pReceivePin
->QueryAccept(&m_MediaFormat
);
1533 pmt
= &m_MediaFormat
;
1536 // query for IMemInput interface
1537 hr
= pReceivePin
->QueryInterface(IID_IMemInputPin
, (void**)&m_MemInputPin
);
1540 #ifdef KSPROXY_TRACE
1541 OutputDebugStringW(L
"COutputPin::Connect no IMemInputPin interface\n");
1548 // get input pin allocator properties
1549 ZeroMemory(&Properties
, sizeof(ALLOCATOR_PROPERTIES
));
1550 m_MemInputPin
->GetAllocatorRequirements(&Properties
);
1552 //FIXME determine allocator properties
1553 Properties
.cBuffers
= 32;
1554 Properties
.cbBuffer
= 2048 * 188; //2048 frames * MPEG2 TS Payload size
1555 Properties
.cbAlign
= 4;
1557 // get input pin allocator
1559 hr
= m_MemInputPin
->GetAllocator(&m_MemAllocator
);
1562 // set allocator properties
1563 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1565 m_MemAllocator
->Release();
1571 hr
= CKsAllocator_Constructor(NULL
, IID_IMemAllocator
, (void**)&m_MemAllocator
);
1575 // set allocator properties
1576 hr
= m_MemAllocator
->SetProperties(&Properties
, &m_Properties
);
1579 #ifdef KSPROXY_TRACE
1580 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::SetProperties failed with hr %lx\n", hr
);
1581 OutputDebugStringW(Buffer
);
1583 m_MemAllocator
->Release();
1584 m_MemInputPin
->Release();
1589 // commit property changes
1590 hr
= m_MemAllocator
->Commit();
1593 #ifdef KSPROXY_TRACE
1594 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocator::Commit failed with hr %lx\n", hr
);
1595 OutputDebugStringW(Buffer
);
1597 m_MemAllocator
->Release();
1598 m_MemInputPin
->Release();
1602 // get callback interface
1603 hr
= m_MemAllocator
->QueryInterface(IID_IMemAllocatorCallbackTemp
, (void**)&pMemCallback
);
1606 #ifdef KSPROXY_TRACE
1607 swprintf(Buffer
, L
"COutputPin::Connect No IMemAllocatorCallbackTemp interface hr %lx\n", hr
);
1608 OutputDebugStringW(Buffer
);
1610 m_MemAllocator
->Release();
1611 m_MemInputPin
->Release();
1615 // set notification routine
1616 hr
= pMemCallback
->SetNotify((IMemAllocatorNotifyCallbackTemp
*)this);
1618 // release IMemAllocatorNotifyCallbackTemp interface
1619 pMemCallback
->Release();
1623 #ifdef KSPROXY_TRACE
1624 swprintf(Buffer
, L
"COutputPin::Connect IMemAllocatorNotifyCallbackTemp::SetNotify failed hr %lx\n", hr
);
1625 OutputDebugStringW(Buffer
);
1627 m_MemAllocator
->Release();
1628 m_MemInputPin
->Release();
1632 // now set allocator
1633 hr
= m_MemInputPin
->NotifyAllocator(m_MemAllocator
, TRUE
);
1636 #ifdef KSPROXY_TRACE
1637 swprintf(Buffer
, L
"COutputPin::Connect IMemInputPin::NotifyAllocator failed with hr %lx\n", hr
);
1638 OutputDebugStringW(Buffer
);
1640 m_MemAllocator
->Release();
1641 m_MemInputPin
->Release();
1647 //FIXME create pin handle
1651 // receive connection;
1652 hr
= pReceivePin
->ReceiveConnection((IPin
*)this, pmt
);
1655 // increment reference count
1656 pReceivePin
->AddRef();
1657 m_Pin
= pReceivePin
;
1658 #ifdef KSPROXY_TRACE
1659 OutputDebugStringW(L
"COutputPin::Connect success\n");
1664 m_MemInputPin
->Release();
1665 m_MemAllocator
->Release();
1673 COutputPin::ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
)
1675 return E_UNEXPECTED
;
1679 COutputPin::Disconnect( void)
1681 #ifdef KSPROXY_TRACE
1682 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1687 // pin was not connected
1692 //check if filter is active
1696 m_MemInputPin
->Release();
1697 m_MemAllocator
->Release();
1699 CloseHandle(m_hPin
);
1700 m_hPin
= INVALID_HANDLE_VALUE
;
1702 #ifdef KSPROXY_TRACE
1703 OutputDebugStringW(L
"COutputPin::Disconnect\n");
1709 COutputPin::ConnectedTo(IPin
**pPin
)
1711 #ifdef KSPROXY_TRACE
1712 OutputDebugStringW(L
"COutputPin::ConnectedTo\n");
1720 // increment reference count
1727 return VFW_E_NOT_CONNECTED
;
1731 COutputPin::ConnectionMediaType(AM_MEDIA_TYPE
*pmt
)
1733 #ifdef KSPROXY_TRACE
1734 OutputDebugStringW(L
"COutputPin::ConnectionMediaType called\n");
1741 COutputPin::QueryPinInfo(PIN_INFO
*pInfo
)
1743 wcscpy(pInfo
->achName
, m_PinName
);
1744 pInfo
->dir
= PINDIR_OUTPUT
;
1745 pInfo
->pFilter
= m_ParentFilter
;
1746 m_ParentFilter
->AddRef();
1752 COutputPin::QueryDirection(PIN_DIRECTION
*pPinDir
)
1756 *pPinDir
= PINDIR_OUTPUT
;
1764 COutputPin::QueryId(LPWSTR
*Id
)
1766 *Id
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_PinName
)+1)*sizeof(WCHAR
));
1768 return E_OUTOFMEMORY
;
1770 wcscpy(*Id
, m_PinName
);
1775 COutputPin::QueryAccept(const AM_MEDIA_TYPE
*pmt
)
1777 #ifdef KSPROXY_TRACE
1778 OutputDebugStringW(L
"COutputPin::QueryAccept called\n");
1785 COutputPin::EnumMediaTypes(IEnumMediaTypes
**ppEnum
)
1788 ULONG MediaTypeCount
= 0, Index
;
1789 AM_MEDIA_TYPE
* MediaTypes
;
1791 IKsObject
* KsObjectParent
;
1793 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1797 // get parent filter handle
1798 hFilter
= KsObjectParent
->KsGetObjectHandle();
1800 // release IKsObject
1801 KsObjectParent
->Release();
1803 // query media type count
1804 hr
= KsGetMediaTypeCount(hFilter
, m_PinId
, &MediaTypeCount
);
1805 if (FAILED(hr
) || !MediaTypeCount
)
1810 // allocate media types
1811 MediaTypes
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1814 // not enough memory
1815 return E_OUTOFMEMORY
;
1819 ZeroMemory(MediaTypes
, sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1821 for(Index
= 0; Index
< MediaTypeCount
; Index
++)
1824 hr
= KsGetMediaType(Index
, &MediaTypes
[Index
], hFilter
, m_PinId
);
1828 CoTaskMemFree(MediaTypes
);
1833 return CEnumMediaTypes_fnConstructor(MediaTypeCount
, MediaTypes
, IID_IEnumMediaTypes
, (void**)ppEnum
);
1837 COutputPin::QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
)
1843 COutputPin::EndOfStream( void)
1845 /* should be called only on input pins */
1846 return E_UNEXPECTED
;
1850 COutputPin::BeginFlush( void)
1852 /* should be called only on input pins */
1853 return E_UNEXPECTED
;
1857 COutputPin::EndFlush( void)
1859 /* should be called only on input pins */
1860 return E_UNEXPECTED
;
1864 COutputPin::NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
)
1868 // we are not connected
1869 return VFW_E_NOT_CONNECTED
;
1872 return m_Pin
->NewSegment(tStart
, tStop
, dRate
);
1875 //-------------------------------------------------------------------
1878 COutputPin::CheckFormat(
1879 const AM_MEDIA_TYPE
*pmt
)
1881 PKSMULTIPLE_ITEM MultipleItem
;
1882 PKSDATAFORMAT DataFormat
;
1884 IKsObject
* KsObjectParent
;
1890 // get IKsObject interface
1891 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1895 // get parent filter handle
1896 hFilter
= KsObjectParent
->KsGetObjectHandle();
1898 // release IKsObject
1899 KsObjectParent
->Release();
1905 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
1909 DataFormat
= (PKSDATAFORMAT
)(MultipleItem
+ 1);
1910 for(ULONG Index
= 0; Index
< MultipleItem
->Count
; Index
++)
1912 if (IsEqualGUID(pmt
->majortype
, DataFormat
->MajorFormat
) &&
1913 IsEqualGUID(pmt
->subtype
, DataFormat
->SubFormat
) &&
1914 IsEqualGUID(pmt
->formattype
, DataFormat
->Specifier
))
1916 // format is supported
1917 CoTaskMemFree(MultipleItem
);
1920 DataFormat
= (PKSDATAFORMAT
)((ULONG_PTR
)DataFormat
+ DataFormat
->FormatSize
);
1922 //format is not supported
1923 CoTaskMemFree(MultipleItem
);
1929 COutputPin::CreatePin(
1930 const AM_MEDIA_TYPE
*pmt
)
1932 PKSMULTIPLE_ITEM MediumList
;
1933 PKSMULTIPLE_ITEM InterfaceList
;
1934 PKSPIN_MEDIUM Medium
;
1935 PKSPIN_INTERFACE Interface
;
1936 IKsInterfaceHandler
* InterfaceHandler
;
1939 // query for pin medium
1940 hr
= KsQueryMediums(&MediumList
);
1944 // query for pin interface
1945 hr
= KsQueryInterfaces(&InterfaceList
);
1949 CoTaskMemFree(MediumList
);
1953 if (MediumList
->Count
)
1955 //use first available medium
1956 Medium
= (PKSPIN_MEDIUM
)(MediumList
+ 1);
1960 // default to standard medium
1961 Medium
= &StandardPinMedium
;
1964 if (InterfaceList
->Count
)
1966 //use first available interface
1967 Interface
= (PKSPIN_INTERFACE
)(InterfaceList
+ 1);
1971 // default to standard interface
1972 Interface
= &StandardPinInterface
;
1975 if (m_Communication
!= KSPIN_COMMUNICATION_BRIDGE
&& m_Communication
!= KSPIN_COMMUNICATION_NONE
)
1978 hr
= CreatePinHandle(Medium
, Interface
, pmt
);
1981 m_InterfaceHandler
->Release();
1982 m_InterfaceHandler
= InterfaceHandler
;
1985 if (!m_InterfaceHandler
)
1987 // now load the IKsInterfaceHandler plugin
1988 hr
= CoCreateInstance(Interface
->Set
, NULL
, CLSCTX_INPROC_SERVER
, IID_IKsInterfaceHandler
, (void**)&InterfaceHandler
);
1991 // failed to load interface handler plugin
1992 CoTaskMemFree(MediumList
);
1993 CoTaskMemFree(InterfaceList
);
1999 hr
= InterfaceHandler
->KsSetPin((IKsPin
*)this);
2002 // failed to load interface handler plugin
2003 InterfaceHandler
->Release();
2004 CoTaskMemFree(MediumList
);
2005 CoTaskMemFree(InterfaceList
);
2009 // store interface handler
2010 m_InterfaceHandler
= InterfaceHandler
;
2015 #ifdef KSPROXY_TRACE
2017 swprintf(Buffer
, L
"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication
, m_PinName
);
2018 OutputDebugStringW(Buffer
);
2025 // free medium / interface / dataformat
2026 CoTaskMemFree(MediumList
);
2027 CoTaskMemFree(InterfaceList
);
2034 COutputPin::CreatePinHandle(
2035 PKSPIN_MEDIUM Medium
,
2036 PKSPIN_INTERFACE Interface
,
2037 const AM_MEDIA_TYPE
*pmt
)
2039 PKSPIN_CONNECT PinConnect
;
2040 PKSDATAFORMAT DataFormat
;
2044 IKsObject
* KsObjectParent
;
2046 //KSALLOCATOR_FRAMING Framing;
2047 //KSPROPERTY Property;
2048 //ULONG BytesReturned;
2050 if (m_hPin
!= INVALID_HANDLE_VALUE
)
2052 // pin already exists
2053 //CloseHandle(m_hPin);
2054 //m_hPin = INVALID_HANDLE_VALUE;
2060 Length
= sizeof(KSPIN_CONNECT
) + sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
2062 // allocate pin connect
2063 PinConnect
= (PKSPIN_CONNECT
)CoTaskMemAlloc(Length
);
2067 return E_OUTOFMEMORY
;
2071 CopyMemory(&PinConnect
->Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
2072 CopyMemory(&PinConnect
->Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
2073 PinConnect
->PinId
= m_PinId
;
2074 PinConnect
->PinToHandle
= NULL
;
2075 PinConnect
->Priority
.PriorityClass
= KSPRIORITY_NORMAL
;
2076 PinConnect
->Priority
.PrioritySubClass
= KSPRIORITY_NORMAL
;
2078 // get dataformat offset
2079 DataFormat
= (PKSDATAFORMAT
)(PinConnect
+ 1);
2082 DataFormat
->FormatSize
= sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
2083 DataFormat
->Flags
= 0;
2084 DataFormat
->SampleSize
= pmt
->lSampleSize
;
2085 DataFormat
->Reserved
= 0;
2086 CopyMemory(&DataFormat
->MajorFormat
, &pmt
->majortype
, sizeof(GUID
));
2087 CopyMemory(&DataFormat
->SubFormat
, &pmt
->subtype
, sizeof(GUID
));
2088 CopyMemory(&DataFormat
->Specifier
, &pmt
->formattype
, sizeof(GUID
));
2092 // copy extended format
2093 CopyMemory((DataFormat
+ 1), pmt
->pbFormat
, pmt
->cbFormat
);
2096 // get IKsObject interface
2097 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
2101 // get parent filter handle
2102 hFilter
= KsObjectParent
->KsGetObjectHandle();
2104 // release IKsObject
2105 KsObjectParent
->Release();
2111 hr
= KsCreatePin(hFilter
, PinConnect
, GENERIC_READ
, &m_hPin
);
2115 // store current interface / medium
2116 CopyMemory(&m_Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
2117 CopyMemory(&m_Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
2118 CopyMemory(&m_MediaFormat
, pmt
, sizeof(AM_MEDIA_TYPE
));
2120 #ifdef KSPROXY_TRACE
2121 LPOLESTR pMajor
, pSub
, pFormat
;
2122 StringFromIID(m_MediaFormat
.majortype
, &pMajor
);
2123 StringFromIID(m_MediaFormat
.subtype
, &pSub
);
2124 StringFromIID(m_MediaFormat
.formattype
, &pFormat
);
2126 swprintf(Buffer
, L
"COutputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor
, pSub
, pFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
2127 CoTaskMemFree(pMajor
);
2128 CoTaskMemFree(pSub
);
2129 CoTaskMemFree(pFormat
);
2130 OutputDebugStringW(Buffer
);
2135 m_MediaFormat
.pbFormat
= (BYTE
*)CoTaskMemAlloc(pmt
->cbFormat
);
2136 if (!m_MediaFormat
.pbFormat
)
2138 CoTaskMemFree(PinConnect
);
2139 m_MediaFormat
.pbFormat
= NULL
;
2140 m_MediaFormat
.cbFormat
= 0;
2141 return E_OUTOFMEMORY
;
2143 CopyMemory(m_MediaFormat
.pbFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
2146 Property
.Set
= KSPROPSETID_Connection
;
2147 Property
.Id
= KSPROPERTY_CONNECTION_ALLOCATORFRAMING
;
2148 Property
.Flags
= KSPROPERTY_TYPE_GET
;
2150 ZeroMemory(&Framing
, sizeof(KSALLOCATOR_FRAMING
));
2151 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (PVOID
)&Framing
, sizeof(KSALLOCATOR_FRAMING
), &BytesReturned
);
2154 m_Properties
.cbAlign
= (Framing
.FileAlignment
+ 1);
2155 m_Properties
.cbBuffer
= Framing
.FrameSize
;
2156 m_Properties
.cbPrefix
= 0; //FIXME
2157 m_Properties
.cBuffers
= Framing
.Frames
;
2162 if (FAILED(InitializeIOThread()))
2164 OutputDebugStringW(L
"COutputPin::CreatePinHandle failed to initialize i/o thread\n");
2169 // connect pin pipes
2173 CoTaskMemFree(PinConnect
);
2180 COutputPin::IoProcessRoutine()
2182 IMediaSample
*Sample
;
2185 PKSSTREAM_SEGMENT StreamSegment
;
2187 IMediaSample
* Samples
[1];
2189 #ifdef KSPROXY_TRACE
2193 // first wait for the start event to signal
2194 WaitForSingleObject(m_hStartEvent
, INFINITE
);
2196 assert(m_InterfaceHandler
);
2199 if (m_StopInProgress
)
2205 assert(m_State
== KSSTATE_RUN
);
2206 assert(m_MemAllocator
);
2209 hr
= m_MemAllocator
->GetBuffer(&Sample
, NULL
, NULL
, AM_GBF_NOWAIT
);
2213 WaitForSingleObject(m_hBufferAvailable
, INFINITE
);
2220 Samples
[0] = Sample
;
2222 Sample
->SetTime(NULL
, NULL
);
2223 hr
= m_InterfaceHandler
->KsProcessMediaSamples(NULL
, /* FIXME */
2228 if (FAILED(hr
) || !StreamSegment
)
2230 #ifdef KSPROXY_TRACE
2231 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine KsProcessMediaSamples FAILED PinName %s hr %lx\n", m_PinName
, hr
);
2232 OutputDebugStringW(Buffer
);
2237 // get completion event
2238 hEvent
= StreamSegment
->CompletionEvent
;
2240 // wait for i/o completion
2241 WaitForSingleObject(hEvent
, INFINITE
);
2243 // perform completion
2244 m_InterfaceHandler
->KsCompleteIo(StreamSegment
);
2246 // close completion event
2247 CloseHandle(hEvent
);
2251 assert(m_MemInputPin
);
2253 // now deliver the sample
2254 hr
= m_MemInputPin
->Receive(Sample
);
2256 #ifdef KSPROXY_TRACE
2257 swprintf(Buffer
, L
"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName
, hr
, Sample
, m_MemAllocator
);
2258 OutputDebugStringW(Buffer
);
2268 // signal end of i/o thread
2269 SetEvent(m_hStopEvent
);
2271 m_IoThreadStarted
= false;
2278 COutputPin_IoThreadStartup(
2281 COutputPin
* Pin
= (COutputPin
*)lpParameter
;
2284 return Pin
->IoProcessRoutine();
2290 COutputPin::InitializeIOThread()
2294 if (m_IoThreadStarted
)
2298 m_hStartEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2301 return E_OUTOFMEMORY
;
2304 m_hStopEvent
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2307 return E_OUTOFMEMORY
;
2309 if (!m_hBufferAvailable
)
2310 m_hBufferAvailable
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
2312 if (!m_hBufferAvailable
)
2313 return E_OUTOFMEMORY
;
2315 m_StopInProgress
= false;
2316 m_IoThreadStarted
= true;
2318 // now create the startup thread
2319 hThread
= CreateThread(NULL
, 0, COutputPin_IoThreadStartup
, (LPVOID
)this, 0, NULL
);
2321 return E_OUTOFMEMORY
;
2324 // close thread handle
2325 CloseHandle(hThread
);
2331 COutputPin_SetState(
2336 KSPROPERTY Property
;
2338 ULONG BytesReturned
;
2339 COutputPin
* pPin
= (COutputPin
*)Pin
;
2341 #ifdef KSPROXY_TRACE
2345 Property
.Set
= KSPROPSETID_Connection
;
2346 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
2347 Property
.Flags
= KSPROPERTY_TYPE_SET
;
2349 EnterCriticalSection(&pPin
->m_Lock
);
2351 if (pPin
->m_State
<= State
)
2353 if (pPin
->m_State
== KSSTATE_STOP
)
2355 hr
= pPin
->InitializeIOThread();
2358 // failed to initialize I/O thread
2359 #ifdef KSPROXY_TRACE
2360 OutputDebugStringW(L
"Failed to initialize I/O Thread\n");
2362 LeaveCriticalSection(&pPin
->m_Lock
);
2365 CurState
= KSSTATE_ACQUIRE
;
2366 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2368 #ifdef KSPROXY_TRACE
2369 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_STOP KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2370 OutputDebugStringW(Buffer
);
2375 LeaveCriticalSection(&pPin
->m_Lock
);
2379 pPin
->m_State
= CurState
;
2381 if (pPin
->m_State
== State
)
2383 LeaveCriticalSection(&pPin
->m_Lock
);
2387 if (pPin
->m_State
== KSSTATE_ACQUIRE
)
2389 CurState
= KSSTATE_PAUSE
;
2390 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2392 #ifdef KSPROXY_TRACE
2393 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState KSSTATE_ACQUIRE KSSTATE_PAUSE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2394 OutputDebugStringW(Buffer
);
2399 LeaveCriticalSection(&pPin
->m_Lock
);
2403 pPin
->m_State
= CurState
;
2405 if (pPin
->m_State
== State
)
2407 LeaveCriticalSection(&pPin
->m_Lock
);
2411 if (State
== KSSTATE_RUN
&& pPin
->m_State
== KSSTATE_PAUSE
)
2413 CurState
= KSSTATE_RUN
;
2414 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2416 #ifdef KSPROXY_TRACE
2417 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_RUN PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2418 OutputDebugStringW(Buffer
);
2423 pPin
->m_State
= CurState
;
2424 // signal start event
2425 SetEvent(pPin
->m_hStartEvent
);
2429 LeaveCriticalSection(&pPin
->m_Lock
);
2434 if (pPin
->m_State
== KSSTATE_RUN
)
2436 // setting pending stop flag
2437 pPin
->m_StopInProgress
= true;
2439 // release any waiting threads
2440 SetEvent(pPin
->m_hBufferAvailable
);
2442 // wait until i/o thread is done
2443 WaitForSingleObject(pPin
->m_hStopEvent
, INFINITE
);
2445 CurState
= KSSTATE_PAUSE
;
2446 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2448 #ifdef KSPROXY_TRACE
2449 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_RUN KSSTATE_PAUSE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2450 OutputDebugStringW(Buffer
);
2455 LeaveCriticalSection(&pPin
->m_Lock
);
2459 pPin
->m_State
= CurState
;
2463 LeaveCriticalSection(&pPin
->m_Lock
);
2467 if (pPin
->m_State
== KSSTATE_PAUSE
)
2469 CurState
= KSSTATE_ACQUIRE
;
2470 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2472 #ifdef KSPROXY_TRACE
2473 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2474 OutputDebugStringW(Buffer
);
2479 LeaveCriticalSection(&pPin
->m_Lock
);
2483 pPin
->m_State
= CurState
;
2485 if (pPin
->m_State
== State
)
2487 LeaveCriticalSection(&pPin
->m_Lock
);
2492 CloseHandle(pPin
->m_hStopEvent
);
2493 CloseHandle(pPin
->m_hStartEvent
);
2494 CloseHandle(pPin
->m_hBufferAvailable
);
2496 /* close event handles */
2497 pPin
->m_hStopEvent
= NULL
;
2498 pPin
->m_hStartEvent
= NULL
;
2499 pPin
->m_hBufferAvailable
= NULL
;
2501 CurState
= KSSTATE_STOP
;
2502 hr
= pPin
->KsProperty(&Property
, sizeof(KSPROPERTY
), &CurState
, sizeof(KSSTATE
), &BytesReturned
);
2504 #ifdef KSPROXY_TRACE
2505 swprintf(Buffer
, L
"COutputPin_SetState Setting State CurState: KSSTATE_ACQUIRE KSSTATE_STOP PinName %s hr %lx\n", pPin
->m_PinName
, hr
);
2506 OutputDebugStringW(Buffer
);
2512 pPin
->m_State
= CurState
;
2515 // unset pending stop flag
2516 pPin
->m_StopInProgress
= false;
2518 LeaveCriticalSection(&pPin
->m_Lock
);
2525 COutputPin_Constructor(
2526 IBaseFilter
* ParentFilter
,
2529 KSPIN_COMMUNICATION Communication
,
2533 COutputPin
* handler
= new COutputPin(ParentFilter
, PinName
, PinId
, Communication
);
2536 return E_OUTOFMEMORY
;
2538 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
2542 return E_NOINTERFACE
;