2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/input_pin.cpp
5 * PURPOSE: InputPin of Proxy Filter
7 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
11 const GUID IID_IKsPinPipe
= {0xe539cd90, 0xa8b4, 0x11d1, {0x81, 0x89, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02}};
12 const GUID IID_IKsPinEx
= {0x7bb38260L
, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}};
14 KSPIN_INTERFACE StandardPinInterface
=
16 {STATIC_KSINTERFACESETID_Standard
},
17 KSINTERFACE_STANDARD_STREAMING
,
21 KSPIN_MEDIUM StandardPinMedium
=
23 {STATIC_KSMEDIUMSETID_Standard
},
24 KSMEDIUM_TYPE_ANYINSTANCE
,
28 class CInputPin
: public IPin
,
29 public IKsPropertySet
,
36 public IStreamBuilder
,
37 public IKsAggregateControl
,
38 public IQualityControl
,
39 public ISpecifyPropertyPages
42 typedef std::vector
<IUnknown
*>ProxyPluginVector
;
44 STDMETHODIMP
QueryInterface( REFIID InterfaceId
, PVOID
* Interface
);
46 STDMETHODIMP_(ULONG
) AddRef()
48 InterlockedIncrement(&m_Ref
);
51 STDMETHODIMP_(ULONG
) Release()
53 InterlockedDecrement(&m_Ref
);
63 HRESULT STDMETHODCALLTYPE
KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX
*FramingEx
, PFRAMING_PROP FramingProp
, FRAMING_CACHE_OPS Option
);
64 HRESULT STDMETHODCALLTYPE
KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx
, PFRAMING_PROP FramingProp
, FRAMING_CACHE_OPS Option
);
65 IPin
* STDMETHODCALLTYPE
KsGetConnectedPin();
66 IKsAllocatorEx
* STDMETHODCALLTYPE
KsGetPipe(KSPEEKOPERATION Operation
);
67 HRESULT STDMETHODCALLTYPE
KsSetPipe(IKsAllocatorEx
*KsAllocator
);
68 ULONG STDMETHODCALLTYPE
KsGetPipeAllocatorFlag();
69 HRESULT STDMETHODCALLTYPE
KsSetPipeAllocatorFlag(ULONG Flag
);
70 GUID STDMETHODCALLTYPE
KsGetPinBusCache();
71 HRESULT STDMETHODCALLTYPE
KsSetPinBusCache(GUID Bus
);
72 PWCHAR STDMETHODCALLTYPE
KsGetPinName();
73 PWCHAR STDMETHODCALLTYPE
KsGetFilterName();
76 HRESULT STDMETHODCALLTYPE
Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
);
77 HRESULT STDMETHODCALLTYPE
ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
);
78 HRESULT STDMETHODCALLTYPE
Disconnect();
79 HRESULT STDMETHODCALLTYPE
ConnectedTo(IPin
**pPin
);
80 HRESULT STDMETHODCALLTYPE
ConnectionMediaType(AM_MEDIA_TYPE
*pmt
);
81 HRESULT STDMETHODCALLTYPE
QueryPinInfo(PIN_INFO
*pInfo
);
82 HRESULT STDMETHODCALLTYPE
QueryDirection(PIN_DIRECTION
*pPinDir
);
83 HRESULT STDMETHODCALLTYPE
QueryId(LPWSTR
*Id
);
84 HRESULT STDMETHODCALLTYPE
QueryAccept(const AM_MEDIA_TYPE
*pmt
);
85 HRESULT STDMETHODCALLTYPE
EnumMediaTypes(IEnumMediaTypes
**ppEnum
);
86 HRESULT STDMETHODCALLTYPE
QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
);
87 HRESULT STDMETHODCALLTYPE
EndOfStream();
88 HRESULT STDMETHODCALLTYPE
BeginFlush();
89 HRESULT STDMETHODCALLTYPE
EndFlush();
90 HRESULT STDMETHODCALLTYPE
NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
);
92 // ISpecifyPropertyPages
93 HRESULT STDMETHODCALLTYPE
GetPages(CAUUID
*pPages
);
96 HANDLE STDMETHODCALLTYPE
KsGetObjectHandle();
99 HRESULT STDMETHODCALLTYPE
Set(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
);
100 HRESULT STDMETHODCALLTYPE
Get(REFGUID guidPropSet
, DWORD dwPropID
, LPVOID pInstanceData
, DWORD cbInstanceData
, LPVOID pPropData
, DWORD cbPropData
, DWORD
*pcbReturned
);
101 HRESULT STDMETHODCALLTYPE
QuerySupported(REFGUID guidPropSet
, DWORD dwPropID
, DWORD
*pTypeSupport
);
104 HRESULT STDMETHODCALLTYPE
KsProperty(PKSPROPERTY Property
, ULONG PropertyLength
, LPVOID PropertyData
, ULONG DataLength
, ULONG
* BytesReturned
);
105 HRESULT STDMETHODCALLTYPE
KsMethod(PKSMETHOD Method
, ULONG MethodLength
, LPVOID MethodData
, ULONG DataLength
, ULONG
* BytesReturned
);
106 HRESULT STDMETHODCALLTYPE
KsEvent(PKSEVENT Event
, ULONG EventLength
, LPVOID EventData
, ULONG DataLength
, ULONG
* BytesReturned
);
109 HRESULT STDMETHODCALLTYPE
KsQueryMediums(PKSMULTIPLE_ITEM
* MediumList
);
110 HRESULT STDMETHODCALLTYPE
KsQueryInterfaces(PKSMULTIPLE_ITEM
* InterfaceList
);
111 HRESULT STDMETHODCALLTYPE
KsCreateSinkPinHandle(KSPIN_INTERFACE
& Interface
, KSPIN_MEDIUM
& Medium
);
112 HRESULT STDMETHODCALLTYPE
KsGetCurrentCommunication(KSPIN_COMMUNICATION
*Communication
, KSPIN_INTERFACE
*Interface
, KSPIN_MEDIUM
*Medium
);
113 HRESULT STDMETHODCALLTYPE
KsPropagateAcquire();
114 HRESULT STDMETHODCALLTYPE
KsDeliver(IMediaSample
* Sample
, ULONG Flags
);
115 HRESULT STDMETHODCALLTYPE
KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
);
116 IMemAllocator
* STDMETHODCALLTYPE
KsPeekAllocator(KSPEEKOPERATION Operation
);
117 HRESULT STDMETHODCALLTYPE
KsReceiveAllocator(IMemAllocator
*MemAllocator
);
118 HRESULT STDMETHODCALLTYPE
KsRenegotiateAllocator();
119 LONG STDMETHODCALLTYPE
KsIncrementPendingIoCount();
120 LONG STDMETHODCALLTYPE
KsDecrementPendingIoCount();
121 HRESULT STDMETHODCALLTYPE
KsQualityNotify(ULONG Proportion
, REFERENCE_TIME TimeDelta
);
123 VOID STDMETHODCALLTYPE
KsNotifyError(IMediaSample
* Sample
, HRESULT hr
);
126 HRESULT STDMETHODCALLTYPE
GetAllocator(IMemAllocator
**ppAllocator
);
127 HRESULT STDMETHODCALLTYPE
NotifyAllocator(IMemAllocator
*pAllocator
, BOOL bReadOnly
);
128 HRESULT STDMETHODCALLTYPE
GetAllocatorRequirements(ALLOCATOR_PROPERTIES
*pProps
);
129 HRESULT STDMETHODCALLTYPE
Receive(IMediaSample
*pSample
);
130 HRESULT STDMETHODCALLTYPE
ReceiveMultiple(IMediaSample
**pSamples
, long nSamples
, long *nSamplesProcessed
);
131 HRESULT STDMETHODCALLTYPE
ReceiveCanBlock( void);
134 HRESULT STDMETHODCALLTYPE
KsPinFactory(ULONG
* PinFactory
);
137 HRESULT STDMETHODCALLTYPE
Render(IPin
*ppinOut
, IGraphBuilder
*pGraph
);
138 HRESULT STDMETHODCALLTYPE
Backout(IPin
*ppinOut
, IGraphBuilder
*pGraph
);
140 //IKsAggregateControl
141 HRESULT STDMETHODCALLTYPE
KsAddAggregate(IN REFGUID AggregateClass
);
142 HRESULT STDMETHODCALLTYPE
KsRemoveAggregate(REFGUID AggregateClass
);
145 HRESULT STDMETHODCALLTYPE
Notify(IBaseFilter
*pSelf
, Quality q
);
146 HRESULT STDMETHODCALLTYPE
SetSink(IQualityControl
*piqc
);
148 //---------------------------------------------------------------
149 HRESULT STDMETHODCALLTYPE
CheckFormat(const AM_MEDIA_TYPE
*pmt
);
150 HRESULT STDMETHODCALLTYPE
CreatePin(const AM_MEDIA_TYPE
*pmt
);
151 HRESULT STDMETHODCALLTYPE
CreatePinHandle(PKSPIN_MEDIUM Medium
, PKSPIN_INTERFACE Interface
, const AM_MEDIA_TYPE
*pmt
);
152 HRESULT STDMETHODCALLTYPE
GetSupportedSets(LPGUID
* pOutGuid
, PULONG NumGuids
);
153 HRESULT STDMETHODCALLTYPE
LoadProxyPlugins(LPGUID pGuids
, ULONG NumGuids
);
154 CInputPin(IBaseFilter
* ParentFilter
, LPCWSTR PinName
, ULONG PinId
, KSPIN_COMMUNICATION Communication
);
155 virtual ~CInputPin(){};
159 IBaseFilter
* m_ParentFilter
;
163 IMemAllocator
* m_MemAllocator
;
165 KSPIN_COMMUNICATION m_Communication
;
166 KSPIN_INTERFACE m_Interface
;
167 KSPIN_MEDIUM m_Medium
;
168 AM_MEDIA_TYPE m_MediaFormat
;
171 IKsInterfaceHandler
* m_InterfaceHandler
;
172 IKsAllocatorEx
* m_KsAllocatorEx
;
173 ULONG m_PipeAllocatorFlag
;
174 BOOL m_bPinBusCacheInitialized
;
177 FRAMING_PROP m_FramingProp
[4];
178 PKSALLOCATOR_FRAMING_EX m_FramingEx
[4];
179 ProxyPluginVector m_Plugins
;
182 CInputPin::CInputPin(
183 IBaseFilter
* ParentFilter
,
186 KSPIN_COMMUNICATION Communication
) : m_Ref(0),
187 m_ParentFilter(ParentFilter
),
189 m_hPin(INVALID_HANDLE_VALUE
),
193 m_Communication(Communication
),
196 m_InterfaceHandler(0),
198 m_PipeAllocatorFlag(0),
199 m_bPinBusCacheInitialized(0),
203 ZeroMemory(m_FramingProp
, sizeof(m_FramingProp
));
204 ZeroMemory(m_FramingEx
, sizeof(m_FramingEx
));
207 IKsObject
* KsObjectParent
;
210 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
213 hFilter
= KsObjectParent
->KsGetObjectHandle();
216 KsObjectParent
->Release();
219 ZeroMemory(&m_MediaFormat
, sizeof(AM_MEDIA_TYPE
));
220 hr
= KsGetMediaType(0, &m_MediaFormat
, hFilter
, m_PinId
);
226 CInputPin::QueryInterface(
234 if (IsEqualGUID(refiid
, IID_IUnknown
) ||
235 IsEqualGUID(refiid
, IID_IPin
))
237 *Output
= PVOID(this);
238 reinterpret_cast<IUnknown
*>(*Output
)->AddRef();
241 else if (IsEqualGUID(refiid
, IID_IMemInputPin
))
243 if (m_hPin
== INVALID_HANDLE_VALUE
)
245 HRESULT hr
= CreatePin(&m_MediaFormat
);
250 *Output
= (IMemInputPin
*)(this);
251 reinterpret_cast<IMemInputPin
*>(*Output
)->AddRef();
254 else if (IsEqualGUID(refiid
, IID_IKsObject
))
256 *Output
= (IKsObject
*)(this);
257 reinterpret_cast<IKsObject
*>(*Output
)->AddRef();
260 else if (IsEqualGUID(refiid
, IID_IKsPropertySet
))
262 if (m_hPin
== INVALID_HANDLE_VALUE
)
264 HRESULT hr
= CreatePin(&m_MediaFormat
);
269 *Output
= (IKsPropertySet
*)(this);
270 reinterpret_cast<IKsPropertySet
*>(*Output
)->AddRef();
273 else if (IsEqualGUID(refiid
, IID_IKsControl
))
275 *Output
= (IKsControl
*)(this);
276 reinterpret_cast<IKsControl
*>(*Output
)->AddRef();
279 else if (IsEqualGUID(refiid
, IID_IKsPin
) ||
280 IsEqualGUID(refiid
, IID_IKsPinEx
))
282 *Output
= (IKsPinEx
*)(this);
283 reinterpret_cast<IKsPinEx
*>(*Output
)->AddRef();
286 else if (IsEqualGUID(refiid
, IID_IKsPinPipe
))
288 *Output
= (IKsPinPipe
*)(this);
289 reinterpret_cast<IKsPinPipe
*>(*Output
)->AddRef();
292 else if (IsEqualGUID(refiid
, IID_IKsPinFactory
))
294 *Output
= (IKsPinFactory
*)(this);
295 reinterpret_cast<IKsPinFactory
*>(*Output
)->AddRef();
299 else if (IsEqualGUID(refiid
, IID_IStreamBuilder
))
301 *Output
= (IStreamBuilder
*)(this);
302 reinterpret_cast<IStreamBuilder
*>(*Output
)->AddRef();
306 else if (IsEqualGUID(refiid
, IID_IKsAggregateControl
))
308 *Output
= (IKsAggregateControl
*)(this);
309 reinterpret_cast<IKsAggregateControl
*>(*Output
)->AddRef();
312 else if (IsEqualGUID(refiid
, IID_IQualityControl
))
314 *Output
= (IQualityControl
*)(this);
315 reinterpret_cast<IQualityControl
*>(*Output
)->AddRef();
318 else if (IsEqualGUID(refiid
, IID_ISpecifyPropertyPages
))
320 *Output
= (ISpecifyPropertyPages
*)(this);
321 reinterpret_cast<ISpecifyPropertyPages
*>(*Output
)->AddRef();
326 StringFromCLSID(refiid
, &lpstr
);
327 swprintf(Buffer
, L
"CInputPin::QueryInterface: NoInterface for %s\n", lpstr
);
328 OutputDebugStringW(Buffer
);
329 CoTaskMemFree(lpstr
);
331 return E_NOINTERFACE
;
333 //-------------------------------------------------------------------
334 // IQualityControl interface
343 OutputDebugStringW(L
"CInputPin::Notify NotImplemented\n");
352 IQualityControl
*piqc
)
355 OutputDebugStringW(L
"CInputPin::SetSink NotImplemented\n");
362 //-------------------------------------------------------------------
363 // IKsAggregateControl interface
367 CInputPin::KsAddAggregate(
368 IN REFGUID AggregateClass
)
371 OutputDebugStringW(L
"CInputPin::KsAddAggregate NotImplemented\n");
379 CInputPin::KsRemoveAggregate(
380 REFGUID AggregateClass
)
383 OutputDebugStringW(L
"CInputPin::KsRemoveAggregate NotImplemented\n");
389 //-------------------------------------------------------------------
397 IGraphBuilder
*pGraph
)
399 OutputDebugStringW(L
"CInputPin::Render\n");
407 IGraphBuilder
*pGraph
)
410 OutputDebugStringW(L
"CInputPin::Backout\n");
416 //-------------------------------------------------------------------
422 CInputPin::KsPinFactory(
426 OutputDebugStringW(L
"CInputPin::KsPinFactory\n");
429 *PinFactory
= m_PinId
;
433 //-------------------------------------------------------------------
439 CInputPin::KsGetPinFramingCache(
440 PKSALLOCATOR_FRAMING_EX
*FramingEx
,
441 PFRAMING_PROP FramingProp
,
442 FRAMING_CACHE_OPS Option
)
444 if (Option
> Framing_Cache_Write
|| Option
< Framing_Cache_ReadLast
)
450 // get framing properties
451 *FramingProp
= m_FramingProp
[Option
];
452 *FramingEx
= m_FramingEx
[Option
];
459 CInputPin::KsSetPinFramingCache(
460 PKSALLOCATOR_FRAMING_EX FramingEx
,
461 PFRAMING_PROP FramingProp
,
462 FRAMING_CACHE_OPS Option
)
467 if (m_FramingEx
[Option
])
469 for(Index
= 1; Index
< 4; Index
++)
471 if (m_FramingEx
[Index
] == m_FramingEx
[Option
])
477 // existing framing is only used once
478 CoTaskMemFree(m_FramingEx
[Option
]);
483 m_FramingEx
[Option
] = FramingEx
;
484 m_FramingProp
[Option
] = *FramingProp
;
491 CInputPin::KsGetConnectedPin()
498 CInputPin::KsGetPipe(
499 KSPEEKOPERATION Operation
)
501 if (Operation
== KsPeekOperation_AddRef
)
504 m_KsAllocatorEx
->AddRef();
506 return m_KsAllocatorEx
;
511 CInputPin::KsSetPipe(
512 IKsAllocatorEx
*KsAllocator
)
515 KsAllocator
->AddRef();
518 m_KsAllocatorEx
->Release();
520 m_KsAllocatorEx
= KsAllocator
;
526 CInputPin::KsGetPipeAllocatorFlag()
528 return m_PipeAllocatorFlag
;
534 CInputPin::KsSetPipeAllocatorFlag(
537 m_PipeAllocatorFlag
= Flag
;
543 CInputPin::KsGetPinBusCache()
545 if (!m_bPinBusCacheInitialized
)
547 CopyMemory(&m_PinBusCache
, &m_Medium
.Set
, sizeof(GUID
));
548 m_bPinBusCacheInitialized
= TRUE
;
551 return m_PinBusCache
;
556 CInputPin::KsSetPinBusCache(
559 CopyMemory(&m_PinBusCache
, &Bus
, sizeof(GUID
));
565 CInputPin::KsGetPinName()
567 return (PWCHAR
)m_PinName
;
573 CInputPin::KsGetFilterName()
578 //-------------------------------------------------------------------
579 // ISpecifyPropertyPages
584 CInputPin::GetPages(CAUUID
*pPages
)
590 pPages
->pElems
= NULL
;
595 //-------------------------------------------------------------------
602 CInputPin::GetAllocator(IMemAllocator
**ppAllocator
)
605 OutputDebugStringW(L
"CInputPin::GetAllocator\n");
608 return VFW_E_NO_ALLOCATOR
;
613 CInputPin::NotifyAllocator(IMemAllocator
*pAllocator
, BOOL bReadOnly
)
616 ALLOCATOR_PROPERTIES Properties
;
618 hr
= pAllocator
->GetProperties(&Properties
);
622 swprintf(Buffer
, L
"CInputPin::NotifyAllocator hr %lx bReadOnly, %u cbAlign %u cbBuffer %u cbPrefix %u cBuffers %u\n", hr
, bReadOnly
, Properties
.cbAlign
, Properties
.cbBuffer
, Properties
.cbPrefix
, Properties
.cBuffers
);
623 OutputDebugStringW(Buffer
);
628 pAllocator
->AddRef();
633 m_MemAllocator
->Release();
636 m_MemAllocator
= pAllocator
;
637 m_ReadOnly
= bReadOnly
;
643 CInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES
*pProps
)
645 KSALLOCATOR_FRAMING Framing
;
650 Property
.Set
= KSPROPSETID_Connection
;
651 Property
.Id
= KSPROPERTY_CONNECTION_ALLOCATORFRAMING
;
652 Property
.Flags
= KSPROPERTY_TYPE_SET
;
654 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (PVOID
)&Framing
, sizeof(KSALLOCATOR_FRAMING
), &BytesReturned
);
657 pProps
->cBuffers
= Framing
.Frames
;
658 pProps
->cbBuffer
= Framing
.FrameSize
;
659 pProps
->cbAlign
= Framing
.FileAlignment
;
660 pProps
->cbPrefix
= 0;
667 swprintf(Buffer
, L
"CInputPin::GetAllocatorRequirements hr %lx m_hPin %p cBuffers %u cbBuffer %u cbAlign %u cbPrefix %u\n", hr
, m_hPin
, pProps
->cBuffers
, pProps
->cbBuffer
, pProps
->cbAlign
, pProps
->cbPrefix
);
668 OutputDebugStringW(Buffer
);
676 CInputPin::Receive(IMediaSample
*pSample
)
679 OutputDebugStringW(L
"CInputPin::Receive NotImplemented\n");
687 CInputPin::ReceiveMultiple(IMediaSample
**pSamples
, long nSamples
, long *nSamplesProcessed
)
690 OutputDebugStringW(L
"CInputPin::ReceiveMultiple NotImplemented\n");
698 CInputPin::ReceiveCanBlock( void)
701 OutputDebugStringW(L
"CInputPin::ReceiveCanBlock NotImplemented\n");
707 //-------------------------------------------------------------------
713 CInputPin::KsQueryMediums(
714 PKSMULTIPLE_ITEM
* MediumList
)
717 IKsObject
* KsObjectParent
;
720 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
724 hFilter
= KsObjectParent
->KsGetObjectHandle();
726 KsObjectParent
->Release();
731 return KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_MEDIUMS
, (PVOID
*)MediumList
);
736 CInputPin::KsQueryInterfaces(
737 PKSMULTIPLE_ITEM
* InterfaceList
)
740 IKsObject
* KsObjectParent
;
743 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
747 hFilter
= KsObjectParent
->KsGetObjectHandle();
749 KsObjectParent
->Release();
754 return KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_INTERFACES
, (PVOID
*)InterfaceList
);
759 CInputPin::KsCreateSinkPinHandle(
760 KSPIN_INTERFACE
& Interface
,
761 KSPIN_MEDIUM
& Medium
)
763 return CreatePin(&m_MediaFormat
);
768 CInputPin::KsGetCurrentCommunication(
769 KSPIN_COMMUNICATION
*Communication
,
770 KSPIN_INTERFACE
*Interface
,
771 KSPIN_MEDIUM
*Medium
)
775 *Communication
= m_Communication
;
781 return VFW_E_NOT_CONNECTED
;
783 CopyMemory(Interface
, &m_Interface
, sizeof(KSPIN_INTERFACE
));
789 return VFW_E_NOT_CONNECTED
;
791 CopyMemory(Medium
, &m_Medium
, sizeof(KSPIN_MEDIUM
));
798 CInputPin::KsPropagateAcquire()
805 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
807 Property
.Set
= KSPROPSETID_Connection
;
808 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
809 Property
.Flags
= KSPROPERTY_TYPE_SET
;
811 State
= KSSTATE_ACQUIRE
;
813 hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), (LPVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
816 //propagate to connected pin on the pipe
823 CInputPin::KsDeliver(
824 IMediaSample
* Sample
,
832 CInputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment
)
839 CInputPin::KsPeekAllocator(KSPEEKOPERATION Operation
)
841 if (Operation
== KsPeekOperation_AddRef
)
843 // add reference on allocator
844 m_MemAllocator
->AddRef();
847 return m_MemAllocator
;
852 CInputPin::KsReceiveAllocator(IMemAllocator
*MemAllocator
)
857 MemAllocator
->AddRef();
862 m_MemAllocator
->Release();
865 m_MemAllocator
= MemAllocator
;
871 CInputPin::KsRenegotiateAllocator()
878 CInputPin::KsIncrementPendingIoCount()
880 return InterlockedIncrement((volatile LONG
*)&m_IoCount
);
885 CInputPin::KsDecrementPendingIoCount()
887 return InterlockedDecrement((volatile LONG
*)&m_IoCount
);
892 CInputPin::KsQualityNotify(
894 REFERENCE_TIME TimeDelta
)
897 OutputDebugStringW(L
"CInputPin::KsQualityNotify NotImplemented\n");
903 //-------------------------------------------------------------------
909 CInputPin::KsNotifyError(
910 IMediaSample
* Sample
,
914 OutputDebugStringW(L
"CInputPin::KsNotifyError NotImplemented\n");
919 //-------------------------------------------------------------------
924 CInputPin::KsProperty(
925 PKSPROPERTY Property
,
926 ULONG PropertyLength
,
929 ULONG
* BytesReturned
)
931 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
932 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)Property
, PropertyLength
, (PVOID
)PropertyData
, DataLength
, BytesReturned
);
942 ULONG
* BytesReturned
)
944 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
945 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)Method
, MethodLength
, (PVOID
)MethodData
, DataLength
, BytesReturned
);
955 ULONG
* BytesReturned
)
957 assert(m_hPin
!= INVALID_HANDLE_VALUE
);
960 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)Event
, EventLength
, (PVOID
)EventData
, DataLength
, BytesReturned
);
962 return KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_DISABLE_EVENT
, (PVOID
)Event
, EventLength
, NULL
, 0, BytesReturned
);
966 //-------------------------------------------------------------------
974 LPVOID pInstanceData
,
975 DWORD cbInstanceData
,
983 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
985 return E_OUTOFMEMORY
;
987 Property
->Set
= guidPropSet
;
988 Property
->Id
= dwPropID
;
989 Property
->Flags
= KSPROPERTY_TYPE_SET
;
991 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
993 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
994 CoTaskMemFree(Property
);
1001 Property
.Set
= guidPropSet
;
1002 Property
.Id
= dwPropID
;
1003 Property
.Flags
= KSPROPERTY_TYPE_SET
;
1005 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1013 REFGUID guidPropSet
,
1015 LPVOID pInstanceData
,
1016 DWORD cbInstanceData
,
1021 ULONG BytesReturned
;
1025 PKSPROPERTY Property
= (PKSPROPERTY
)CoTaskMemAlloc(sizeof(KSPROPERTY
) + cbInstanceData
);
1027 return E_OUTOFMEMORY
;
1029 Property
->Set
= guidPropSet
;
1030 Property
->Id
= dwPropID
;
1031 Property
->Flags
= KSPROPERTY_TYPE_GET
;
1033 CopyMemory((Property
+1), pInstanceData
, cbInstanceData
);
1035 HRESULT hr
= KsProperty(Property
, sizeof(KSPROPERTY
) + cbInstanceData
, pPropData
, cbPropData
, &BytesReturned
);
1036 CoTaskMemFree(Property
);
1041 KSPROPERTY Property
;
1043 Property
.Set
= guidPropSet
;
1044 Property
.Id
= dwPropID
;
1045 Property
.Flags
= KSPROPERTY_TYPE_GET
;
1047 HRESULT hr
= KsProperty(&Property
, sizeof(KSPROPERTY
), pPropData
, cbPropData
, &BytesReturned
);
1054 CInputPin::QuerySupported(
1055 REFGUID guidPropSet
,
1057 DWORD
*pTypeSupport
)
1059 KSPROPERTY Property
;
1060 ULONG BytesReturned
;
1062 Property
.Set
= guidPropSet
;
1063 Property
.Id
= dwPropID
;
1064 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1066 return KsProperty(&Property
, sizeof(KSPROPERTY
), pTypeSupport
, sizeof(DWORD
), &BytesReturned
);
1070 //-------------------------------------------------------------------
1075 CInputPin::KsGetObjectHandle()
1081 //-------------------------------------------------------------------
1086 CInputPin::Connect(IPin
*pReceivePin
, const AM_MEDIA_TYPE
*pmt
)
1088 #ifdef KSPROXY_TRACE
1089 OutputDebugStringW(L
"CInputPin::Connect NotImplemented\n");
1096 CInputPin::ReceiveConnection(IPin
*pConnector
, const AM_MEDIA_TYPE
*pmt
)
1102 // already connected
1103 return VFW_E_ALREADY_CONNECTED
;
1106 // first check format
1107 hr
= CheckFormat(pmt
);
1110 // format is not supported
1114 hr
= CreatePin(pmt
);
1127 CInputPin::Disconnect( void)
1131 // pin was not connected
1136 //check if filter is active
1141 #ifdef KSPROXY_TRACE
1142 OutputDebugStringW(L
"CInputPin::Disconnect\n");
1149 CInputPin::ConnectedTo(IPin
**pPin
)
1156 // increment reference count
1163 return VFW_E_NOT_CONNECTED
;
1167 CInputPin::ConnectionMediaType(AM_MEDIA_TYPE
*pmt
)
1170 return VFW_E_NOT_CONNECTED
;
1172 #ifdef KSPROXY_TRACE
1173 OutputDebugStringW(L
"CInputPin::ConnectionMediaType NotImplemented\n");
1180 CInputPin::QueryPinInfo(PIN_INFO
*pInfo
)
1182 wcscpy(pInfo
->achName
, m_PinName
);
1183 pInfo
->dir
= PINDIR_INPUT
;
1184 pInfo
->pFilter
= m_ParentFilter
;
1185 m_ParentFilter
->AddRef();
1191 CInputPin::QueryDirection(PIN_DIRECTION
*pPinDir
)
1195 *pPinDir
= PINDIR_INPUT
;
1203 CInputPin::QueryId(LPWSTR
*Id
)
1205 *Id
= (LPWSTR
)CoTaskMemAlloc((wcslen(m_PinName
)+1)*sizeof(WCHAR
));
1207 return E_OUTOFMEMORY
;
1209 wcscpy(*Id
, m_PinName
);
1215 CInputPin::QueryAccept(
1216 const AM_MEDIA_TYPE
*pmt
)
1218 return CheckFormat(pmt
);
1222 CInputPin::EnumMediaTypes(IEnumMediaTypes
**ppEnum
)
1225 ULONG MediaTypeCount
= 0, Index
;
1226 AM_MEDIA_TYPE
* MediaTypes
;
1227 IKsObject
* KsObjectParent
;
1230 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1234 hFilter
= KsObjectParent
->KsGetObjectHandle();
1236 KsObjectParent
->Release();
1242 // query media type count
1243 hr
= KsGetMediaTypeCount(hFilter
, m_PinId
, &MediaTypeCount
);
1244 if (FAILED(hr
) || !MediaTypeCount
)
1247 // allocate media types
1248 MediaTypes
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1251 // not enough memory
1252 return E_OUTOFMEMORY
;
1256 ZeroMemory(MediaTypes
, sizeof(AM_MEDIA_TYPE
) * MediaTypeCount
);
1258 for(Index
= 0; Index
< MediaTypeCount
; Index
++)
1261 hr
= KsGetMediaType(Index
, &MediaTypes
[Index
], hFilter
, m_PinId
);
1265 CoTaskMemFree(MediaTypes
);
1270 return CEnumMediaTypes_fnConstructor(MediaTypeCount
, MediaTypes
, IID_IEnumMediaTypes
, (void**)ppEnum
);
1275 CInputPin::QueryInternalConnections(IPin
**apPin
, ULONG
*nPin
)
1277 #ifdef KSPROXY_TRACE
1278 OutputDebugStringW(L
"CInputPin::QueryInternalConnections NotImplemented\n");
1284 CInputPin::EndOfStream( void)
1286 #ifdef KSPROXY_TRACE
1287 OutputDebugStringW(L
"CInputPin::EndOfStream NotImplemented\n");
1293 CInputPin::BeginFlush( void)
1295 #ifdef KSPROXY_TRACE
1296 OutputDebugStringW(L
"CInputPin::BeginFlush NotImplemented\n");
1302 CInputPin::EndFlush( void)
1304 #ifdef KSPROXY_TRACE
1305 OutputDebugStringW(L
"CInputPin::EndFlush NotImplemented\n");
1311 CInputPin::NewSegment(REFERENCE_TIME tStart
, REFERENCE_TIME tStop
, double dRate
)
1313 #ifdef KSPROXY_TRACE
1314 OutputDebugStringW(L
"CInputPin::NewSegment NotImplemented\n");
1320 //-------------------------------------------------------------------
1323 CInputPin::CheckFormat(
1324 const AM_MEDIA_TYPE
*pmt
)
1326 PKSMULTIPLE_ITEM MultipleItem
;
1327 PKSDATAFORMAT DataFormat
;
1329 IKsObject
* KsObjectParent
;
1335 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1339 hFilter
= KsObjectParent
->KsGetObjectHandle();
1341 KsObjectParent
->Release();
1347 hr
= KsGetMultiplePinFactoryItems(hFilter
, m_PinId
, KSPROPERTY_PIN_DATARANGES
, (PVOID
*)&MultipleItem
);
1351 DataFormat
= (PKSDATAFORMAT
)(MultipleItem
+ 1);
1352 for(ULONG Index
= 0; Index
< MultipleItem
->Count
; Index
++)
1354 if (IsEqualGUID(pmt
->majortype
, DataFormat
->MajorFormat
) &&
1355 IsEqualGUID(pmt
->subtype
, DataFormat
->SubFormat
) &&
1356 IsEqualGUID(pmt
->formattype
, DataFormat
->Specifier
))
1358 // format is supported
1359 CoTaskMemFree(MultipleItem
);
1360 #ifdef KSPROXY_TRACE
1361 OutputDebugStringW(L
"CInputPin::CheckFormat format OK\n");
1365 DataFormat
= (PKSDATAFORMAT
)((ULONG_PTR
)DataFormat
+ DataFormat
->FormatSize
);
1367 //format is not supported
1368 CoTaskMemFree(MultipleItem
);
1374 CInputPin::CreatePin(
1375 const AM_MEDIA_TYPE
*pmt
)
1377 PKSMULTIPLE_ITEM MediumList
;
1378 PKSMULTIPLE_ITEM InterfaceList
;
1379 PKSPIN_MEDIUM Medium
;
1380 PKSPIN_INTERFACE Interface
;
1381 IKsInterfaceHandler
* InterfaceHandler
;
1384 // query for pin medium
1385 hr
= KsQueryMediums(&MediumList
);
1389 // query for pin interface
1390 hr
= KsQueryInterfaces(&InterfaceList
);
1394 CoTaskMemFree(MediumList
);
1398 if (MediumList
->Count
)
1400 //use first available medium
1401 Medium
= (PKSPIN_MEDIUM
)(MediumList
+ 1);
1405 // default to standard medium
1406 Medium
= &StandardPinMedium
;
1409 if (InterfaceList
->Count
)
1411 //use first available interface
1412 Interface
= (PKSPIN_INTERFACE
)(InterfaceList
+ 1);
1416 // default to standard interface
1417 Interface
= &StandardPinInterface
;
1420 if (m_Communication
!= KSPIN_COMMUNICATION_BRIDGE
&& m_Communication
!= KSPIN_COMMUNICATION_NONE
)
1422 if (!m_InterfaceHandler
)
1424 // now load the IKsInterfaceHandler plugin
1425 hr
= CoCreateInstance(Interface
->Set
, NULL
, CLSCTX_INPROC_SERVER
, IID_IKsInterfaceHandler
, (void**)&InterfaceHandler
);
1428 // failed to load interface handler plugin
1429 #ifdef KSPROXY_TRACE
1430 OutputDebugStringW(L
"CInputPin::CreatePin failed to load InterfaceHandlerPlugin\n");
1432 CoTaskMemFree(MediumList
);
1433 CoTaskMemFree(InterfaceList
);
1439 hr
= InterfaceHandler
->KsSetPin((IKsPin
*)this);
1442 // failed to load interface handler plugin
1443 #ifdef KSPROXY_TRACE
1444 OutputDebugStringW(L
"CInputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n");
1446 InterfaceHandler
->Release();
1447 CoTaskMemFree(MediumList
);
1448 CoTaskMemFree(InterfaceList
);
1452 // store interface handler
1453 m_InterfaceHandler
= InterfaceHandler
;
1457 hr
= CreatePinHandle(Medium
, Interface
, pmt
);
1460 m_InterfaceHandler
->Release();
1461 m_InterfaceHandler
= InterfaceHandler
;
1466 #ifdef KSPROXY_TRACE
1468 swprintf(Buffer
, L
"CInputPin::CreatePin unexpected communication %u %s\n", m_Communication
, m_PinName
);
1469 OutputDebugStringW(Buffer
);
1474 // free medium / interface / dataformat
1475 CoTaskMemFree(MediumList
);
1476 CoTaskMemFree(InterfaceList
);
1483 CInputPin::CreatePinHandle(
1484 PKSPIN_MEDIUM Medium
,
1485 PKSPIN_INTERFACE Interface
,
1486 const AM_MEDIA_TYPE
*pmt
)
1488 PKSPIN_CONNECT PinConnect
;
1489 PKSDATAFORMAT DataFormat
;
1492 IKsObject
* KsObjectParent
;
1498 hr
= m_ParentFilter
->QueryInterface(IID_IKsObject
, (LPVOID
*)&KsObjectParent
);
1502 hFilter
= KsObjectParent
->KsGetObjectHandle();
1504 KsObjectParent
->Release();
1510 if (m_hPin
!= INVALID_HANDLE_VALUE
)
1512 // pin already exists
1513 //CloseHandle(m_hPin);
1514 //m_hPin = INVALID_HANDLE_VALUE;
1520 Length
= sizeof(KSPIN_CONNECT
) + sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
1522 // allocate pin connect
1523 PinConnect
= (PKSPIN_CONNECT
)CoTaskMemAlloc(Length
);
1527 return E_OUTOFMEMORY
;
1531 CopyMemory(&PinConnect
->Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
1532 CopyMemory(&PinConnect
->Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
1533 PinConnect
->PinId
= m_PinId
;
1534 PinConnect
->PinToHandle
= NULL
;
1535 PinConnect
->Priority
.PriorityClass
= KSPRIORITY_NORMAL
;
1536 PinConnect
->Priority
.PrioritySubClass
= KSPRIORITY_NORMAL
;
1538 // get dataformat offset
1539 DataFormat
= (PKSDATAFORMAT
)(PinConnect
+ 1);
1542 DataFormat
->FormatSize
= sizeof(KSDATAFORMAT
) + pmt
->cbFormat
;
1543 DataFormat
->Flags
= 0;
1544 DataFormat
->SampleSize
= pmt
->lSampleSize
;
1545 DataFormat
->Reserved
= 0;
1546 CopyMemory(&DataFormat
->MajorFormat
, &pmt
->majortype
, sizeof(GUID
));
1547 CopyMemory(&DataFormat
->SubFormat
, &pmt
->subtype
, sizeof(GUID
));
1548 CopyMemory(&DataFormat
->Specifier
, &pmt
->formattype
, sizeof(GUID
));
1552 // copy extended format
1553 CopyMemory((DataFormat
+ 1), pmt
->pbFormat
, pmt
->cbFormat
);
1557 hr
= KsCreatePin(hFilter
, PinConnect
, GENERIC_WRITE
, &m_hPin
);
1561 // store current interface / medium
1562 CopyMemory(&m_Medium
, Medium
, sizeof(KSPIN_MEDIUM
));
1563 CopyMemory(&m_Interface
, Interface
, sizeof(KSPIN_INTERFACE
));
1564 CopyMemory(&m_MediaFormat
, pmt
, sizeof(AM_MEDIA_TYPE
));
1566 #ifdef KSPROXY_TRACE
1567 LPOLESTR pMajor
, pSub
, pFormat
;
1568 StringFromIID(m_MediaFormat
.majortype
, &pMajor
);
1569 StringFromIID(m_MediaFormat
.subtype
, &pSub
);
1570 StringFromIID(m_MediaFormat
.formattype
, &pFormat
);
1573 swprintf(Buffer
, L
"CInputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor
, pSub
, pFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
1574 CoTaskMemFree(pMajor
);
1575 CoTaskMemFree(pSub
);
1576 CoTaskMemFree(pFormat
);
1577 OutputDebugStringW(Buffer
);
1582 m_MediaFormat
.pbFormat
= (BYTE
*)CoTaskMemAlloc(pmt
->cbFormat
);
1583 if (!m_MediaFormat
.pbFormat
)
1585 CoTaskMemFree(PinConnect
);
1586 m_MediaFormat
.pbFormat
= NULL
;
1587 m_MediaFormat
.cbFormat
= 0;
1588 return E_OUTOFMEMORY
;
1590 CopyMemory(m_MediaFormat
.pbFormat
, pmt
->pbFormat
, pmt
->cbFormat
);
1596 // get all supported sets
1597 hr
= GetSupportedSets(&pGuid
, &NumGuids
);
1600 #ifdef KSPROXY_TRACE
1601 OutputDebugStringW(L
"CInputPin::CreatePinHandle GetSupportedSets failed\n");
1606 // load all proxy plugins
1607 hr
= LoadProxyPlugins(pGuid
, NumGuids
);
1610 #ifdef KSPROXY_TRACE
1611 OutputDebugStringW(L
"CInputPin::CreatePinHandle LoadProxyPlugins failed\n");
1617 CoTaskMemFree(pGuid
);
1621 // connect pin pipes
1626 CoTaskMemFree(PinConnect
);
1633 CInputPin::GetSupportedSets(
1637 KSPROPERTY Property
;
1639 ULONG NumProperty
= 0;
1640 ULONG NumMethods
= 0;
1641 ULONG NumEvents
= 0;
1643 ULONG BytesReturned
;
1646 Property
.Set
= GUID_NULL
;
1648 Property
.Flags
= KSPROPERTY_TYPE_SETSUPPORT
;
1650 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumProperty
);
1651 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumMethods
);
1652 KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &NumEvents
);
1654 Length
= NumProperty
+ NumMethods
+ NumEvents
;
1658 // allocate guid buffer
1659 pGuid
= (LPGUID
)CoTaskMemAlloc(Length
);
1663 return E_OUTOFMEMORY
;
1666 NumProperty
/= sizeof(GUID
);
1667 NumMethods
/= sizeof(GUID
);
1668 NumEvents
/= sizeof(GUID
);
1670 #ifdef KSPROXY_TRACE
1672 swprintf(Buffer
, L
"CInputPin::GetSupportedSets NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty
, NumMethods
, NumEvents
);
1673 OutputDebugStringW(Buffer
);
1676 // get all properties
1677 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)pGuid
, Length
, &BytesReturned
);
1680 CoTaskMemFree(pGuid
);
1683 Length
-= BytesReturned
;
1686 if (Length
&& NumMethods
)
1688 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_METHOD
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
], Length
, &BytesReturned
);
1691 CoTaskMemFree(pGuid
);
1694 Length
-= BytesReturned
;
1698 if (Length
&& NumEvents
)
1700 hr
= KsSynchronousDeviceControl(m_hPin
, IOCTL_KS_ENABLE_EVENT
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&pGuid
[NumProperty
+NumMethods
], Length
, &BytesReturned
);
1703 CoTaskMemFree(pGuid
);
1706 Length
-= BytesReturned
;
1710 *NumGuids
= NumProperty
+NumEvents
+NumMethods
;
1716 CInputPin::LoadProxyPlugins(
1724 IUnknown
* pUnknown
;
1726 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
1728 OutputDebugStringW(L
"CInputPin::LoadProxyPlugins failed to open MediaInterfaces key\n");
1732 // enumerate all sets
1733 for(Index
= 0; Index
< NumGuids
; Index
++)
1735 // convert to string
1736 hr
= StringFromCLSID(pGuids
[Index
], &pStr
);
1740 // now try open class key
1741 if (RegOpenKeyExW(hKey
, pStr
, 0, KEY_READ
, &hSubKey
) != ERROR_SUCCESS
)
1743 // no plugin for that set exists
1744 CoTaskMemFree(pStr
);
1749 hr
= CoCreateInstance(pGuids
[Index
], (IBaseFilter
*)this, CLSCTX_INPROC_SERVER
, IID_IUnknown
, (void**)&pUnknown
);
1753 m_Plugins
.push_back(pUnknown
);
1756 RegCloseKey(hSubKey
);
1759 // close media interfaces key
1766 CInputPin_Constructor(
1767 IBaseFilter
* ParentFilter
,
1771 KSPIN_COMMUNICATION Communication
,
1775 CInputPin
* handler
= new CInputPin(ParentFilter
, PinName
, PinId
, Communication
);
1778 return E_OUTOFMEMORY
;
1780 if (FAILED(handler
->QueryInterface(riid
, ppv
)))
1784 return E_NOINTERFACE
;