1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3*c2c66affSColin Finck * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4*c2c66affSColin Finck * FILE: dll/directx/ksproxy/output_pin.cpp
5*c2c66affSColin Finck * PURPOSE: OutputPin of Proxy Filter
6*c2c66affSColin Finck *
7*c2c66affSColin Finck * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
8*c2c66affSColin Finck */
9*c2c66affSColin Finck #include "precomp.h"
10*c2c66affSColin Finck
11*c2c66affSColin Finck class COutputPin : public IPin,
12*c2c66affSColin Finck public IKsObject,
13*c2c66affSColin Finck public IKsPropertySet,
14*c2c66affSColin Finck public IStreamBuilder,
15*c2c66affSColin Finck public IKsPinFactory,
16*c2c66affSColin Finck public ISpecifyPropertyPages,
17*c2c66affSColin Finck public IKsPinEx,
18*c2c66affSColin Finck public IKsPinPipe,
19*c2c66affSColin Finck public IKsControl,
20*c2c66affSColin Finck public IKsAggregateControl,
21*c2c66affSColin Finck public IQualityControl,
22*c2c66affSColin Finck public IMediaSeeking,
23*c2c66affSColin Finck public IAMBufferNegotiation,
24*c2c66affSColin Finck public IAMStreamConfig,
25*c2c66affSColin Finck public IMemAllocatorNotifyCallbackTemp
26*c2c66affSColin Finck
27*c2c66affSColin Finck {
28*c2c66affSColin Finck public:
29*c2c66affSColin Finck typedef std::vector<IUnknown *>ProxyPluginVector;
30*c2c66affSColin Finck
31*c2c66affSColin Finck STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
32*c2c66affSColin Finck
AddRef()33*c2c66affSColin Finck STDMETHODIMP_(ULONG) AddRef()
34*c2c66affSColin Finck {
35*c2c66affSColin Finck InterlockedIncrement(&m_Ref);
36*c2c66affSColin Finck return m_Ref;
37*c2c66affSColin Finck }
Release()38*c2c66affSColin Finck STDMETHODIMP_(ULONG) Release()
39*c2c66affSColin Finck {
40*c2c66affSColin Finck InterlockedDecrement(&m_Ref);
41*c2c66affSColin Finck if (!m_Ref)
42*c2c66affSColin Finck {
43*c2c66affSColin Finck //delete this;
44*c2c66affSColin Finck return 0;
45*c2c66affSColin Finck }
46*c2c66affSColin Finck return m_Ref;
47*c2c66affSColin Finck }
48*c2c66affSColin Finck
49*c2c66affSColin Finck //IKsPin
50*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsQueryMediums(PKSMULTIPLE_ITEM* MediumList);
51*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsQueryInterfaces(PKSMULTIPLE_ITEM* InterfaceList);
52*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsCreateSinkPinHandle(KSPIN_INTERFACE& Interface, KSPIN_MEDIUM& Medium);
53*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsGetCurrentCommunication(KSPIN_COMMUNICATION *Communication, KSPIN_INTERFACE *Interface, KSPIN_MEDIUM *Medium);
54*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsPropagateAcquire();
55*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsDeliver(IMediaSample* Sample, ULONG Flags);
56*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment);
57*c2c66affSColin Finck IMemAllocator * STDMETHODCALLTYPE KsPeekAllocator(KSPEEKOPERATION Operation);
58*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsReceiveAllocator(IMemAllocator *MemAllocator);
59*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsRenegotiateAllocator();
60*c2c66affSColin Finck LONG STDMETHODCALLTYPE KsIncrementPendingIoCount();
61*c2c66affSColin Finck LONG STDMETHODCALLTYPE KsDecrementPendingIoCount();
62*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsQualityNotify(ULONG Proportion, REFERENCE_TIME TimeDelta);
63*c2c66affSColin Finck // IKsPinEx
64*c2c66affSColin Finck VOID STDMETHODCALLTYPE KsNotifyError(IMediaSample* Sample, HRESULT hr);
65*c2c66affSColin Finck
66*c2c66affSColin Finck //IKsPinPipe
67*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
68*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
69*c2c66affSColin Finck IPin* STDMETHODCALLTYPE KsGetConnectedPin();
70*c2c66affSColin Finck IKsAllocatorEx* STDMETHODCALLTYPE KsGetPipe(KSPEEKOPERATION Operation);
71*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsSetPipe(IKsAllocatorEx *KsAllocator);
72*c2c66affSColin Finck ULONG STDMETHODCALLTYPE KsGetPipeAllocatorFlag();
73*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsSetPipeAllocatorFlag(ULONG Flag);
74*c2c66affSColin Finck GUID STDMETHODCALLTYPE KsGetPinBusCache();
75*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsSetPinBusCache(GUID Bus);
76*c2c66affSColin Finck PWCHAR STDMETHODCALLTYPE KsGetPinName();
77*c2c66affSColin Finck PWCHAR STDMETHODCALLTYPE KsGetFilterName();
78*c2c66affSColin Finck
79*c2c66affSColin Finck //IPin methods
80*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt);
81*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt);
82*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Disconnect();
83*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **pPin);
84*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt);
85*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo);
86*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir);
87*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id);
88*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt);
89*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum);
90*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin);
91*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE EndOfStream();
92*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE BeginFlush();
93*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE EndFlush();
94*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
95*c2c66affSColin Finck
96*c2c66affSColin Finck // ISpecifyPropertyPages
97*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
98*c2c66affSColin Finck
99*c2c66affSColin Finck //IKsObject methods
100*c2c66affSColin Finck HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
101*c2c66affSColin Finck
102*c2c66affSColin Finck //IKsPropertySet
103*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Set(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData);
104*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Get(REFGUID guidPropSet, DWORD dwPropID, LPVOID pInstanceData, DWORD cbInstanceData, LPVOID pPropData, DWORD cbPropData, DWORD *pcbReturned);
105*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE QuerySupported(REFGUID guidPropSet, DWORD dwPropID, DWORD *pTypeSupport);
106*c2c66affSColin Finck
107*c2c66affSColin Finck //IKsControl
108*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned);
109*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned);
110*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
111*c2c66affSColin Finck
112*c2c66affSColin Finck //IStreamBuilder
113*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Render(IPin *ppinOut, IGraphBuilder *pGraph);
114*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Backout(IPin *ppinOut, IGraphBuilder *pGraph);
115*c2c66affSColin Finck
116*c2c66affSColin Finck //IKsPinFactory
117*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory);
118*c2c66affSColin Finck
119*c2c66affSColin Finck //IKsAggregateControl
120*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsAddAggregate(IN REFGUID AggregateClass);
121*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsRemoveAggregate(REFGUID AggregateClass);
122*c2c66affSColin Finck
123*c2c66affSColin Finck //IQualityControl
124*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE Notify(IBaseFilter *pSelf, Quality q);
125*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE SetSink(IQualityControl *piqc);
126*c2c66affSColin Finck
127*c2c66affSColin Finck //IMediaSeeking
128*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetCapabilities(DWORD *pCapabilities);
129*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CheckCapabilities(DWORD *pCapabilities);
130*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE IsFormatSupported(const GUID *pFormat);
131*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE QueryPreferredFormat(GUID *pFormat);
132*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetTimeFormat(GUID *pFormat);
133*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE IsUsingTimeFormat(const GUID *pFormat);
134*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE SetTimeFormat(const GUID *pFormat);
135*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetDuration(LONGLONG *pDuration);
136*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetStopPosition(LONGLONG *pStop);
137*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetCurrentPosition(LONGLONG *pCurrent);
138*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat);
139*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE SetPositions(LONGLONG *pCurrent, DWORD dwCurrentFlags, LONGLONG *pStop, DWORD dwStopFlags);
140*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetPositions(LONGLONG *pCurrent, LONGLONG *pStop);
141*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest);
142*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE SetRate(double dRate);
143*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetRate(double *pdRate);
144*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetPreroll(LONGLONG *pllPreroll);
145*c2c66affSColin Finck
146*c2c66affSColin Finck //IAMBufferNegotiation
147*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE SuggestAllocatorProperties(const ALLOCATOR_PROPERTIES *pprop);
148*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetAllocatorProperties(ALLOCATOR_PROPERTIES *pprop);
149*c2c66affSColin Finck
150*c2c66affSColin Finck //IAMStreamConfig
151*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE SetFormat(AM_MEDIA_TYPE *pmt);
152*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetFormat(AM_MEDIA_TYPE **ppmt);
153*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetNumberOfCapabilities(int *piCount, int *piSize);
154*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetStreamCaps(int iIndex, AM_MEDIA_TYPE **ppmt, BYTE *pSCC);
155*c2c66affSColin Finck
156*c2c66affSColin Finck //IMemAllocatorNotifyCallbackTemp
157*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE NotifyRelease();
158*c2c66affSColin Finck
159*c2c66affSColin Finck //---------------------------------------------------------------
160*c2c66affSColin Finck COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId, KSPIN_COMMUNICATION Communication);
161*c2c66affSColin Finck virtual ~COutputPin();
162*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt);
163*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt);
164*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt);
165*c2c66affSColin Finck HRESULT WINAPI IoProcessRoutine();
166*c2c66affSColin Finck HRESULT WINAPI InitializeIOThread();
167*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE GetSupportedSets(LPGUID * pOutGuid, PULONG NumGuids);
168*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE LoadProxyPlugins(LPGUID pGuids, ULONG NumGuids);
169*c2c66affSColin Finck
170*c2c66affSColin Finck friend DWORD WINAPI COutputPin_IoThreadStartup(LPVOID lpParameter);
171*c2c66affSColin Finck friend HRESULT STDMETHODCALLTYPE COutputPin_SetState(IPin * Pin, KSSTATE State);
172*c2c66affSColin Finck
173*c2c66affSColin Finck protected:
174*c2c66affSColin Finck LONG m_Ref;
175*c2c66affSColin Finck IBaseFilter * m_ParentFilter;
176*c2c66affSColin Finck LPCWSTR m_PinName;
177*c2c66affSColin Finck HANDLE m_hPin;
178*c2c66affSColin Finck ULONG m_PinId;
179*c2c66affSColin Finck IPin * m_Pin;
180*c2c66affSColin Finck IKsAllocatorEx * m_KsAllocatorEx;
181*c2c66affSColin Finck ULONG m_PipeAllocatorFlag;
182*c2c66affSColin Finck BOOL m_bPinBusCacheInitialized;
183*c2c66affSColin Finck GUID m_PinBusCache;
184*c2c66affSColin Finck LPWSTR m_FilterName;
185*c2c66affSColin Finck FRAMING_PROP m_FramingProp[4];
186*c2c66affSColin Finck PKSALLOCATOR_FRAMING_EX m_FramingEx[4];
187*c2c66affSColin Finck
188*c2c66affSColin Finck IMemAllocator * m_MemAllocator;
189*c2c66affSColin Finck IMemInputPin * m_MemInputPin;
190*c2c66affSColin Finck LONG m_IoCount;
191*c2c66affSColin Finck KSPIN_COMMUNICATION m_Communication;
192*c2c66affSColin Finck KSPIN_INTERFACE m_Interface;
193*c2c66affSColin Finck KSPIN_MEDIUM m_Medium;
194*c2c66affSColin Finck AM_MEDIA_TYPE m_MediaFormat;
195*c2c66affSColin Finck ALLOCATOR_PROPERTIES m_Properties;
196*c2c66affSColin Finck IKsInterfaceHandler * m_InterfaceHandler;
197*c2c66affSColin Finck
198*c2c66affSColin Finck HANDLE m_hStartEvent;
199*c2c66affSColin Finck HANDLE m_hBufferAvailable;
200*c2c66affSColin Finck HANDLE m_hStopEvent;
201*c2c66affSColin Finck BOOL m_StopInProgress;
202*c2c66affSColin Finck BOOL m_IoThreadStarted;
203*c2c66affSColin Finck
204*c2c66affSColin Finck KSSTATE m_State;
205*c2c66affSColin Finck CRITICAL_SECTION m_Lock;
206*c2c66affSColin Finck
207*c2c66affSColin Finck ProxyPluginVector m_Plugins;
208*c2c66affSColin Finck };
209*c2c66affSColin Finck
~COutputPin()210*c2c66affSColin Finck COutputPin::~COutputPin()
211*c2c66affSColin Finck {
212*c2c66affSColin Finck }
213*c2c66affSColin Finck
COutputPin(IBaseFilter * ParentFilter,LPCWSTR PinName,ULONG PinId,KSPIN_COMMUNICATION Communication)214*c2c66affSColin Finck COutputPin::COutputPin(
215*c2c66affSColin Finck IBaseFilter * ParentFilter,
216*c2c66affSColin Finck LPCWSTR PinName,
217*c2c66affSColin Finck ULONG PinId,
218*c2c66affSColin Finck KSPIN_COMMUNICATION Communication) : m_Ref(0),
219*c2c66affSColin Finck m_ParentFilter(ParentFilter),
220*c2c66affSColin Finck m_PinName(PinName),
221*c2c66affSColin Finck m_hPin(INVALID_HANDLE_VALUE),
222*c2c66affSColin Finck m_PinId(PinId),
223*c2c66affSColin Finck m_Pin(0),
224*c2c66affSColin Finck m_KsAllocatorEx(0),
225*c2c66affSColin Finck m_PipeAllocatorFlag(0),
226*c2c66affSColin Finck m_bPinBusCacheInitialized(0),
227*c2c66affSColin Finck m_FilterName(0),
228*c2c66affSColin Finck m_MemAllocator(0),
229*c2c66affSColin Finck m_MemInputPin(0),
230*c2c66affSColin Finck m_IoCount(0),
231*c2c66affSColin Finck m_Communication(Communication),
232*c2c66affSColin Finck m_InterfaceHandler(0),
233*c2c66affSColin Finck m_hStartEvent(0),
234*c2c66affSColin Finck m_hBufferAvailable(0),
235*c2c66affSColin Finck m_hStopEvent(0),
236*c2c66affSColin Finck m_StopInProgress(0),
237*c2c66affSColin Finck m_IoThreadStarted(0),
238*c2c66affSColin Finck m_State(KSSTATE_STOP),
239*c2c66affSColin Finck m_Plugins()
240*c2c66affSColin Finck {
241*c2c66affSColin Finck HRESULT hr;
242*c2c66affSColin Finck IKsObject * KsObjectParent;
243*c2c66affSColin Finck
244*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
245*c2c66affSColin Finck assert(hr == S_OK);
246*c2c66affSColin Finck
247*c2c66affSColin Finck ZeroMemory(m_FramingProp, sizeof(m_FramingProp));
248*c2c66affSColin Finck ZeroMemory(m_FramingEx, sizeof(m_FramingEx));
249*c2c66affSColin Finck ZeroMemory(&m_MediaFormat, sizeof(AM_MEDIA_TYPE));
250*c2c66affSColin Finck
251*c2c66affSColin Finck hr = KsGetMediaType(0, &m_MediaFormat, KsObjectParent->KsGetObjectHandle(), m_PinId);
252*c2c66affSColin Finck
253*c2c66affSColin Finck #ifdef KSPROXY_TRACE
254*c2c66affSColin Finck WCHAR Buffer[100];
255*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::COutputPin Format %p pbFormat %lu\n", &m_MediaFormat, m_MediaFormat.cbFormat);
256*c2c66affSColin Finck OutputDebugStringW(Buffer);
257*c2c66affSColin Finck #endif
258*c2c66affSColin Finck
259*c2c66affSColin Finck assert(hr == S_OK);
260*c2c66affSColin Finck
261*c2c66affSColin Finck InitializeCriticalSection(&m_Lock);
262*c2c66affSColin Finck
263*c2c66affSColin Finck KsObjectParent->Release();
264*c2c66affSColin Finck };
265*c2c66affSColin Finck
266*c2c66affSColin Finck HRESULT
267*c2c66affSColin Finck STDMETHODCALLTYPE
QueryInterface(IN REFIID refiid,OUT PVOID * Output)268*c2c66affSColin Finck COutputPin::QueryInterface(
269*c2c66affSColin Finck IN REFIID refiid,
270*c2c66affSColin Finck OUT PVOID* Output)
271*c2c66affSColin Finck {
272*c2c66affSColin Finck *Output = NULL;
273*c2c66affSColin Finck if (IsEqualGUID(refiid, IID_IUnknown) ||
274*c2c66affSColin Finck IsEqualGUID(refiid, IID_IPin))
275*c2c66affSColin Finck {
276*c2c66affSColin Finck #ifdef KSPROXY_TRACE
277*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::QueryInterface IID_IPin\n");
278*c2c66affSColin Finck #endif
279*c2c66affSColin Finck *Output = PVOID(this);
280*c2c66affSColin Finck reinterpret_cast<IUnknown*>(*Output)->AddRef();
281*c2c66affSColin Finck return NOERROR;
282*c2c66affSColin Finck }
283*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IKsObject))
284*c2c66affSColin Finck {
285*c2c66affSColin Finck if (m_hPin == INVALID_HANDLE_VALUE)
286*c2c66affSColin Finck {
287*c2c66affSColin Finck HRESULT hr = CreatePin(&m_MediaFormat);
288*c2c66affSColin Finck if (FAILED(hr))
289*c2c66affSColin Finck return hr;
290*c2c66affSColin Finck }
291*c2c66affSColin Finck #ifdef KSPROXY_TRACE
292*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsObject\n");
293*c2c66affSColin Finck #endif
294*c2c66affSColin Finck *Output = (IKsObject*)(this);
295*c2c66affSColin Finck reinterpret_cast<IKsObject*>(*Output)->AddRef();
296*c2c66affSColin Finck return NOERROR;
297*c2c66affSColin Finck }
298*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IKsPin) || IsEqualGUID(refiid, IID_IKsPinEx))
299*c2c66affSColin Finck {
300*c2c66affSColin Finck *Output = (IKsPinEx*)(this);
301*c2c66affSColin Finck reinterpret_cast<IKsPinEx*>(*Output)->AddRef();
302*c2c66affSColin Finck return NOERROR;
303*c2c66affSColin Finck }
304*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IKsPinPipe))
305*c2c66affSColin Finck {
306*c2c66affSColin Finck *Output = (IKsPinPipe*)(this);
307*c2c66affSColin Finck reinterpret_cast<IKsPinPipe*>(*Output)->AddRef();
308*c2c66affSColin Finck return NOERROR;
309*c2c66affSColin Finck }
310*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IKsAggregateControl))
311*c2c66affSColin Finck {
312*c2c66affSColin Finck *Output = (IKsAggregateControl*)(this);
313*c2c66affSColin Finck reinterpret_cast<IKsAggregateControl*>(*Output)->AddRef();
314*c2c66affSColin Finck return NOERROR;
315*c2c66affSColin Finck }
316*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IQualityControl))
317*c2c66affSColin Finck {
318*c2c66affSColin Finck *Output = (IQualityControl*)(this);
319*c2c66affSColin Finck reinterpret_cast<IQualityControl*>(*Output)->AddRef();
320*c2c66affSColin Finck return NOERROR;
321*c2c66affSColin Finck }
322*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IKsPropertySet))
323*c2c66affSColin Finck {
324*c2c66affSColin Finck if (m_hPin == INVALID_HANDLE_VALUE)
325*c2c66affSColin Finck {
326*c2c66affSColin Finck HRESULT hr = CreatePin(&m_MediaFormat);
327*c2c66affSColin Finck if (FAILED(hr))
328*c2c66affSColin Finck return hr;
329*c2c66affSColin Finck }
330*c2c66affSColin Finck #ifdef KSPROXY_TRACE
331*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsPropertySet\n");
332*c2c66affSColin Finck #endif
333*c2c66affSColin Finck *Output = (IKsPropertySet*)(this);
334*c2c66affSColin Finck reinterpret_cast<IKsPropertySet*>(*Output)->AddRef();
335*c2c66affSColin Finck return NOERROR;
336*c2c66affSColin Finck }
337*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IKsControl))
338*c2c66affSColin Finck {
339*c2c66affSColin Finck #ifdef KSPROXY_TRACE
340*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsControl\n");
341*c2c66affSColin Finck #endif
342*c2c66affSColin Finck *Output = (IKsControl*)(this);
343*c2c66affSColin Finck reinterpret_cast<IKsControl*>(*Output)->AddRef();
344*c2c66affSColin Finck return NOERROR;
345*c2c66affSColin Finck }
346*c2c66affSColin Finck #if 0
347*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IStreamBuilder))
348*c2c66affSColin Finck {
349*c2c66affSColin Finck *Output = (IStreamBuilder*)(this);
350*c2c66affSColin Finck reinterpret_cast<IStreamBuilder*>(*Output)->AddRef();
351*c2c66affSColin Finck return NOERROR;
352*c2c66affSColin Finck }
353*c2c66affSColin Finck #endif
354*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IKsPinFactory))
355*c2c66affSColin Finck {
356*c2c66affSColin Finck #ifdef KSPROXY_TRACE
357*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsPinFactory\n");
358*c2c66affSColin Finck #endif
359*c2c66affSColin Finck *Output = (IKsPinFactory*)(this);
360*c2c66affSColin Finck reinterpret_cast<IKsPinFactory*>(*Output)->AddRef();
361*c2c66affSColin Finck return NOERROR;
362*c2c66affSColin Finck }
363*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages))
364*c2c66affSColin Finck {
365*c2c66affSColin Finck #ifdef KSPROXY_TRACE
366*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::QueryInterface IID_ISpecifyPropertyPages\n");
367*c2c66affSColin Finck #endif
368*c2c66affSColin Finck *Output = (ISpecifyPropertyPages*)(this);
369*c2c66affSColin Finck reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef();
370*c2c66affSColin Finck return NOERROR;
371*c2c66affSColin Finck }
372*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IMediaSeeking))
373*c2c66affSColin Finck {
374*c2c66affSColin Finck *Output = (IMediaSeeking*)(this);
375*c2c66affSColin Finck reinterpret_cast<IMediaSeeking*>(*Output)->AddRef();
376*c2c66affSColin Finck return NOERROR;
377*c2c66affSColin Finck }
378*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IAMBufferNegotiation))
379*c2c66affSColin Finck {
380*c2c66affSColin Finck *Output = (IAMBufferNegotiation*)(this);
381*c2c66affSColin Finck reinterpret_cast<IAMBufferNegotiation*>(*Output)->AddRef();
382*c2c66affSColin Finck return NOERROR;
383*c2c66affSColin Finck }
384*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IAMStreamConfig))
385*c2c66affSColin Finck {
386*c2c66affSColin Finck *Output = (IAMStreamConfig*)(this);
387*c2c66affSColin Finck reinterpret_cast<IAMStreamConfig*>(*Output)->AddRef();
388*c2c66affSColin Finck return NOERROR;
389*c2c66affSColin Finck }
390*c2c66affSColin Finck else if (IsEqualGUID(refiid, IID_IMemAllocatorNotifyCallbackTemp))
391*c2c66affSColin Finck {
392*c2c66affSColin Finck *Output = (IMemAllocatorNotifyCallbackTemp*)(this);
393*c2c66affSColin Finck reinterpret_cast<IMemAllocatorNotifyCallbackTemp*>(*Output)->AddRef();
394*c2c66affSColin Finck return NOERROR;
395*c2c66affSColin Finck }
396*c2c66affSColin Finck
397*c2c66affSColin Finck #ifdef KSPROXY_TRACE
398*c2c66affSColin Finck WCHAR Buffer[MAX_PATH];
399*c2c66affSColin Finck LPOLESTR lpstr;
400*c2c66affSColin Finck StringFromCLSID(refiid, &lpstr);
401*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::QueryInterface: NoInterface for %s PinId %u PinName %s\n", lpstr, m_PinId, m_PinName);
402*c2c66affSColin Finck OutputDebugStringW(Buffer);
403*c2c66affSColin Finck CoTaskMemFree(lpstr);
404*c2c66affSColin Finck #endif
405*c2c66affSColin Finck
406*c2c66affSColin Finck return E_NOINTERFACE;
407*c2c66affSColin Finck }
408*c2c66affSColin Finck
409*c2c66affSColin Finck //-------------------------------------------------------------------
410*c2c66affSColin Finck // IAMBufferNegotiation interface
411*c2c66affSColin Finck //
412*c2c66affSColin Finck HRESULT
413*c2c66affSColin Finck STDMETHODCALLTYPE
SuggestAllocatorProperties(const ALLOCATOR_PROPERTIES * pprop)414*c2c66affSColin Finck COutputPin::SuggestAllocatorProperties(
415*c2c66affSColin Finck const ALLOCATOR_PROPERTIES *pprop)
416*c2c66affSColin Finck {
417*c2c66affSColin Finck #ifdef KSPROXY_TRACE
418*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::SuggestAllocatorProperties\n");
419*c2c66affSColin Finck #endif
420*c2c66affSColin Finck
421*c2c66affSColin Finck if (m_Pin)
422*c2c66affSColin Finck {
423*c2c66affSColin Finck // pin is already connected
424*c2c66affSColin Finck return VFW_E_ALREADY_CONNECTED;
425*c2c66affSColin Finck }
426*c2c66affSColin Finck
427*c2c66affSColin Finck CopyMemory(&m_Properties, pprop, sizeof(ALLOCATOR_PROPERTIES));
428*c2c66affSColin Finck return NOERROR;
429*c2c66affSColin Finck }
430*c2c66affSColin Finck
431*c2c66affSColin Finck HRESULT
432*c2c66affSColin Finck STDMETHODCALLTYPE
GetAllocatorProperties(ALLOCATOR_PROPERTIES * pprop)433*c2c66affSColin Finck COutputPin::GetAllocatorProperties(
434*c2c66affSColin Finck ALLOCATOR_PROPERTIES *pprop)
435*c2c66affSColin Finck {
436*c2c66affSColin Finck #ifdef KSPROXY_TRACE
437*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::GetAllocatorProperties\n");
438*c2c66affSColin Finck #endif
439*c2c66affSColin Finck
440*c2c66affSColin Finck if (!m_Pin)
441*c2c66affSColin Finck {
442*c2c66affSColin Finck // you should call this method AFTER you connected
443*c2c66affSColin Finck return E_UNEXPECTED;
444*c2c66affSColin Finck }
445*c2c66affSColin Finck
446*c2c66affSColin Finck if (!m_KsAllocatorEx)
447*c2c66affSColin Finck {
448*c2c66affSColin Finck // something went wrong while creating the allocator
449*c2c66affSColin Finck return E_FAIL;
450*c2c66affSColin Finck }
451*c2c66affSColin Finck
452*c2c66affSColin Finck CopyMemory(pprop, &m_Properties, sizeof(ALLOCATOR_PROPERTIES));
453*c2c66affSColin Finck return NOERROR;
454*c2c66affSColin Finck }
455*c2c66affSColin Finck
456*c2c66affSColin Finck //-------------------------------------------------------------------
457*c2c66affSColin Finck // IAMStreamConfig interface
458*c2c66affSColin Finck //
459*c2c66affSColin Finck HRESULT
460*c2c66affSColin Finck STDMETHODCALLTYPE
SetFormat(AM_MEDIA_TYPE * pmt)461*c2c66affSColin Finck COutputPin::SetFormat(
462*c2c66affSColin Finck AM_MEDIA_TYPE *pmt)
463*c2c66affSColin Finck {
464*c2c66affSColin Finck #ifdef KSPROXY_TRACE
465*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::SetFormat NotImplemented\n");
466*c2c66affSColin Finck #endif
467*c2c66affSColin Finck return E_NOTIMPL;
468*c2c66affSColin Finck }
469*c2c66affSColin Finck
470*c2c66affSColin Finck HRESULT
471*c2c66affSColin Finck STDMETHODCALLTYPE
GetFormat(AM_MEDIA_TYPE ** ppmt)472*c2c66affSColin Finck COutputPin::GetFormat(AM_MEDIA_TYPE **ppmt)
473*c2c66affSColin Finck {
474*c2c66affSColin Finck #ifdef KSPROXY_TRACE
475*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::GetFormat NotImplemented\n");
476*c2c66affSColin Finck #endif
477*c2c66affSColin Finck return E_NOTIMPL;
478*c2c66affSColin Finck }
479*c2c66affSColin Finck
480*c2c66affSColin Finck HRESULT
481*c2c66affSColin Finck STDMETHODCALLTYPE
GetNumberOfCapabilities(int * piCount,int * piSize)482*c2c66affSColin Finck COutputPin::GetNumberOfCapabilities(
483*c2c66affSColin Finck int *piCount,
484*c2c66affSColin Finck int *piSize)
485*c2c66affSColin Finck {
486*c2c66affSColin Finck #ifdef KSPROXY_TRACE
487*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::GetNumberOfCapabilities NotImplemented\n");
488*c2c66affSColin Finck #endif
489*c2c66affSColin Finck return E_NOTIMPL;
490*c2c66affSColin Finck }
491*c2c66affSColin Finck
492*c2c66affSColin Finck HRESULT
493*c2c66affSColin Finck STDMETHODCALLTYPE
GetStreamCaps(int iIndex,AM_MEDIA_TYPE ** ppmt,BYTE * pSCC)494*c2c66affSColin Finck COutputPin::GetStreamCaps(
495*c2c66affSColin Finck int iIndex,
496*c2c66affSColin Finck AM_MEDIA_TYPE **ppmt,
497*c2c66affSColin Finck BYTE *pSCC)
498*c2c66affSColin Finck {
499*c2c66affSColin Finck #ifdef KSPROXY_TRACE
500*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::GetStreamCaps NotImplemented\n");
501*c2c66affSColin Finck #endif
502*c2c66affSColin Finck return E_NOTIMPL;
503*c2c66affSColin Finck }
504*c2c66affSColin Finck
505*c2c66affSColin Finck //-------------------------------------------------------------------
506*c2c66affSColin Finck // IMemAllocatorNotifyCallbackTemp interface
507*c2c66affSColin Finck //
508*c2c66affSColin Finck HRESULT
509*c2c66affSColin Finck STDMETHODCALLTYPE
NotifyRelease()510*c2c66affSColin Finck COutputPin::NotifyRelease()
511*c2c66affSColin Finck {
512*c2c66affSColin Finck #ifdef KSPROXY_TRACE
513*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::NotifyRelease\n");
514*c2c66affSColin Finck #endif
515*c2c66affSColin Finck
516*c2c66affSColin Finck // notify thread of new available sample
517*c2c66affSColin Finck SetEvent(m_hBufferAvailable);
518*c2c66affSColin Finck
519*c2c66affSColin Finck return NOERROR;
520*c2c66affSColin Finck }
521*c2c66affSColin Finck
522*c2c66affSColin Finck //-------------------------------------------------------------------
523*c2c66affSColin Finck // IMediaSeeking interface
524*c2c66affSColin Finck //
525*c2c66affSColin Finck HRESULT
526*c2c66affSColin Finck STDMETHODCALLTYPE
GetCapabilities(DWORD * pCapabilities)527*c2c66affSColin Finck COutputPin::GetCapabilities(
528*c2c66affSColin Finck DWORD *pCapabilities)
529*c2c66affSColin Finck {
530*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
531*c2c66affSColin Finck HRESULT hr;
532*c2c66affSColin Finck
533*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
534*c2c66affSColin Finck if (FAILED(hr))
535*c2c66affSColin Finck return hr;
536*c2c66affSColin Finck
537*c2c66affSColin Finck hr = FilterMediaSeeking->GetCapabilities(pCapabilities);
538*c2c66affSColin Finck
539*c2c66affSColin Finck FilterMediaSeeking->Release();
540*c2c66affSColin Finck return hr;
541*c2c66affSColin Finck }
542*c2c66affSColin Finck
543*c2c66affSColin Finck HRESULT
544*c2c66affSColin Finck STDMETHODCALLTYPE
CheckCapabilities(DWORD * pCapabilities)545*c2c66affSColin Finck COutputPin::CheckCapabilities(
546*c2c66affSColin Finck DWORD *pCapabilities)
547*c2c66affSColin Finck {
548*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
549*c2c66affSColin Finck HRESULT hr;
550*c2c66affSColin Finck
551*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
552*c2c66affSColin Finck if (FAILED(hr))
553*c2c66affSColin Finck return hr;
554*c2c66affSColin Finck
555*c2c66affSColin Finck hr = FilterMediaSeeking->CheckCapabilities(pCapabilities);
556*c2c66affSColin Finck
557*c2c66affSColin Finck FilterMediaSeeking->Release();
558*c2c66affSColin Finck return hr;
559*c2c66affSColin Finck }
560*c2c66affSColin Finck
561*c2c66affSColin Finck HRESULT
562*c2c66affSColin Finck STDMETHODCALLTYPE
IsFormatSupported(const GUID * pFormat)563*c2c66affSColin Finck COutputPin::IsFormatSupported(
564*c2c66affSColin Finck const GUID *pFormat)
565*c2c66affSColin Finck {
566*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
567*c2c66affSColin Finck HRESULT hr;
568*c2c66affSColin Finck
569*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
570*c2c66affSColin Finck if (FAILED(hr))
571*c2c66affSColin Finck return hr;
572*c2c66affSColin Finck
573*c2c66affSColin Finck hr = FilterMediaSeeking->IsFormatSupported(pFormat);
574*c2c66affSColin Finck
575*c2c66affSColin Finck FilterMediaSeeking->Release();
576*c2c66affSColin Finck return hr;
577*c2c66affSColin Finck }
578*c2c66affSColin Finck
579*c2c66affSColin Finck HRESULT
580*c2c66affSColin Finck STDMETHODCALLTYPE
QueryPreferredFormat(GUID * pFormat)581*c2c66affSColin Finck COutputPin::QueryPreferredFormat(
582*c2c66affSColin Finck GUID *pFormat)
583*c2c66affSColin Finck {
584*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
585*c2c66affSColin Finck HRESULT hr;
586*c2c66affSColin Finck
587*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
588*c2c66affSColin Finck if (FAILED(hr))
589*c2c66affSColin Finck return hr;
590*c2c66affSColin Finck
591*c2c66affSColin Finck hr = FilterMediaSeeking->QueryPreferredFormat(pFormat);
592*c2c66affSColin Finck
593*c2c66affSColin Finck FilterMediaSeeking->Release();
594*c2c66affSColin Finck return hr;
595*c2c66affSColin Finck }
596*c2c66affSColin Finck
597*c2c66affSColin Finck HRESULT
598*c2c66affSColin Finck STDMETHODCALLTYPE
GetTimeFormat(GUID * pFormat)599*c2c66affSColin Finck COutputPin::GetTimeFormat(
600*c2c66affSColin Finck GUID *pFormat)
601*c2c66affSColin Finck {
602*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
603*c2c66affSColin Finck HRESULT hr;
604*c2c66affSColin Finck
605*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
606*c2c66affSColin Finck if (FAILED(hr))
607*c2c66affSColin Finck return hr;
608*c2c66affSColin Finck
609*c2c66affSColin Finck hr = FilterMediaSeeking->GetTimeFormat(pFormat);
610*c2c66affSColin Finck
611*c2c66affSColin Finck FilterMediaSeeking->Release();
612*c2c66affSColin Finck return hr;
613*c2c66affSColin Finck }
614*c2c66affSColin Finck
615*c2c66affSColin Finck HRESULT
616*c2c66affSColin Finck STDMETHODCALLTYPE
IsUsingTimeFormat(const GUID * pFormat)617*c2c66affSColin Finck COutputPin::IsUsingTimeFormat(
618*c2c66affSColin Finck const GUID *pFormat)
619*c2c66affSColin Finck {
620*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
621*c2c66affSColin Finck HRESULT hr;
622*c2c66affSColin Finck
623*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
624*c2c66affSColin Finck if (FAILED(hr))
625*c2c66affSColin Finck return hr;
626*c2c66affSColin Finck
627*c2c66affSColin Finck hr = FilterMediaSeeking->IsUsingTimeFormat(pFormat);
628*c2c66affSColin Finck
629*c2c66affSColin Finck FilterMediaSeeking->Release();
630*c2c66affSColin Finck return hr;
631*c2c66affSColin Finck }
632*c2c66affSColin Finck
633*c2c66affSColin Finck HRESULT
634*c2c66affSColin Finck STDMETHODCALLTYPE
SetTimeFormat(const GUID * pFormat)635*c2c66affSColin Finck COutputPin::SetTimeFormat(
636*c2c66affSColin Finck const GUID *pFormat)
637*c2c66affSColin Finck {
638*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
639*c2c66affSColin Finck HRESULT hr;
640*c2c66affSColin Finck
641*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
642*c2c66affSColin Finck if (FAILED(hr))
643*c2c66affSColin Finck return hr;
644*c2c66affSColin Finck
645*c2c66affSColin Finck hr = FilterMediaSeeking->SetTimeFormat(pFormat);
646*c2c66affSColin Finck
647*c2c66affSColin Finck FilterMediaSeeking->Release();
648*c2c66affSColin Finck return hr;
649*c2c66affSColin Finck }
650*c2c66affSColin Finck
651*c2c66affSColin Finck HRESULT
652*c2c66affSColin Finck STDMETHODCALLTYPE
GetDuration(LONGLONG * pDuration)653*c2c66affSColin Finck COutputPin::GetDuration(
654*c2c66affSColin Finck LONGLONG *pDuration)
655*c2c66affSColin Finck {
656*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
657*c2c66affSColin Finck HRESULT hr;
658*c2c66affSColin Finck
659*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
660*c2c66affSColin Finck if (FAILED(hr))
661*c2c66affSColin Finck return hr;
662*c2c66affSColin Finck
663*c2c66affSColin Finck hr = FilterMediaSeeking->GetDuration(pDuration);
664*c2c66affSColin Finck
665*c2c66affSColin Finck FilterMediaSeeking->Release();
666*c2c66affSColin Finck return hr;
667*c2c66affSColin Finck }
668*c2c66affSColin Finck
669*c2c66affSColin Finck HRESULT
670*c2c66affSColin Finck STDMETHODCALLTYPE
GetStopPosition(LONGLONG * pStop)671*c2c66affSColin Finck COutputPin::GetStopPosition(
672*c2c66affSColin Finck LONGLONG *pStop)
673*c2c66affSColin Finck {
674*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
675*c2c66affSColin Finck HRESULT hr;
676*c2c66affSColin Finck
677*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
678*c2c66affSColin Finck if (FAILED(hr))
679*c2c66affSColin Finck return hr;
680*c2c66affSColin Finck
681*c2c66affSColin Finck hr = FilterMediaSeeking->GetStopPosition(pStop);
682*c2c66affSColin Finck
683*c2c66affSColin Finck FilterMediaSeeking->Release();
684*c2c66affSColin Finck return hr;
685*c2c66affSColin Finck }
686*c2c66affSColin Finck
687*c2c66affSColin Finck
688*c2c66affSColin Finck HRESULT
689*c2c66affSColin Finck STDMETHODCALLTYPE
GetCurrentPosition(LONGLONG * pCurrent)690*c2c66affSColin Finck COutputPin::GetCurrentPosition(
691*c2c66affSColin Finck LONGLONG *pCurrent)
692*c2c66affSColin Finck {
693*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
694*c2c66affSColin Finck HRESULT hr;
695*c2c66affSColin Finck
696*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
697*c2c66affSColin Finck if (FAILED(hr))
698*c2c66affSColin Finck return hr;
699*c2c66affSColin Finck
700*c2c66affSColin Finck hr = FilterMediaSeeking->GetCurrentPosition(pCurrent);
701*c2c66affSColin Finck
702*c2c66affSColin Finck FilterMediaSeeking->Release();
703*c2c66affSColin Finck return hr;
704*c2c66affSColin Finck }
705*c2c66affSColin Finck
706*c2c66affSColin Finck HRESULT
707*c2c66affSColin Finck STDMETHODCALLTYPE
ConvertTimeFormat(LONGLONG * pTarget,const GUID * pTargetFormat,LONGLONG Source,const GUID * pSourceFormat)708*c2c66affSColin Finck COutputPin::ConvertTimeFormat(
709*c2c66affSColin Finck LONGLONG *pTarget,
710*c2c66affSColin Finck const GUID *pTargetFormat,
711*c2c66affSColin Finck LONGLONG Source,
712*c2c66affSColin Finck const GUID *pSourceFormat)
713*c2c66affSColin Finck {
714*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
715*c2c66affSColin Finck HRESULT hr;
716*c2c66affSColin Finck
717*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
718*c2c66affSColin Finck if (FAILED(hr))
719*c2c66affSColin Finck return hr;
720*c2c66affSColin Finck
721*c2c66affSColin Finck hr = FilterMediaSeeking->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat);
722*c2c66affSColin Finck
723*c2c66affSColin Finck FilterMediaSeeking->Release();
724*c2c66affSColin Finck return hr;
725*c2c66affSColin Finck }
726*c2c66affSColin Finck
727*c2c66affSColin Finck HRESULT
728*c2c66affSColin Finck STDMETHODCALLTYPE
SetPositions(LONGLONG * pCurrent,DWORD dwCurrentFlags,LONGLONG * pStop,DWORD dwStopFlags)729*c2c66affSColin Finck COutputPin::SetPositions(
730*c2c66affSColin Finck LONGLONG *pCurrent,
731*c2c66affSColin Finck DWORD dwCurrentFlags,
732*c2c66affSColin Finck LONGLONG *pStop,
733*c2c66affSColin Finck DWORD dwStopFlags)
734*c2c66affSColin Finck {
735*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
736*c2c66affSColin Finck HRESULT hr;
737*c2c66affSColin Finck
738*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
739*c2c66affSColin Finck if (FAILED(hr))
740*c2c66affSColin Finck return hr;
741*c2c66affSColin Finck
742*c2c66affSColin Finck hr = FilterMediaSeeking->SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
743*c2c66affSColin Finck
744*c2c66affSColin Finck FilterMediaSeeking->Release();
745*c2c66affSColin Finck return hr;
746*c2c66affSColin Finck }
747*c2c66affSColin Finck
748*c2c66affSColin Finck HRESULT
749*c2c66affSColin Finck STDMETHODCALLTYPE
GetPositions(LONGLONG * pCurrent,LONGLONG * pStop)750*c2c66affSColin Finck COutputPin::GetPositions(
751*c2c66affSColin Finck LONGLONG *pCurrent,
752*c2c66affSColin Finck LONGLONG *pStop)
753*c2c66affSColin Finck {
754*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
755*c2c66affSColin Finck HRESULT hr;
756*c2c66affSColin Finck
757*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
758*c2c66affSColin Finck if (FAILED(hr))
759*c2c66affSColin Finck return hr;
760*c2c66affSColin Finck
761*c2c66affSColin Finck hr = FilterMediaSeeking->GetPositions(pCurrent, pStop);
762*c2c66affSColin Finck
763*c2c66affSColin Finck FilterMediaSeeking->Release();
764*c2c66affSColin Finck return hr;
765*c2c66affSColin Finck }
766*c2c66affSColin Finck
767*c2c66affSColin Finck HRESULT
768*c2c66affSColin Finck STDMETHODCALLTYPE
GetAvailable(LONGLONG * pEarliest,LONGLONG * pLatest)769*c2c66affSColin Finck COutputPin::GetAvailable(
770*c2c66affSColin Finck LONGLONG *pEarliest,
771*c2c66affSColin Finck LONGLONG *pLatest)
772*c2c66affSColin Finck {
773*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
774*c2c66affSColin Finck HRESULT hr;
775*c2c66affSColin Finck
776*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
777*c2c66affSColin Finck if (FAILED(hr))
778*c2c66affSColin Finck return hr;
779*c2c66affSColin Finck
780*c2c66affSColin Finck hr = FilterMediaSeeking->GetAvailable(pEarliest, pLatest);
781*c2c66affSColin Finck
782*c2c66affSColin Finck FilterMediaSeeking->Release();
783*c2c66affSColin Finck return hr;
784*c2c66affSColin Finck }
785*c2c66affSColin Finck
786*c2c66affSColin Finck HRESULT
787*c2c66affSColin Finck STDMETHODCALLTYPE
SetRate(double dRate)788*c2c66affSColin Finck COutputPin::SetRate(
789*c2c66affSColin Finck double dRate)
790*c2c66affSColin Finck {
791*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
792*c2c66affSColin Finck HRESULT hr;
793*c2c66affSColin Finck
794*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
795*c2c66affSColin Finck if (FAILED(hr))
796*c2c66affSColin Finck return hr;
797*c2c66affSColin Finck
798*c2c66affSColin Finck hr = FilterMediaSeeking->SetRate(dRate);
799*c2c66affSColin Finck
800*c2c66affSColin Finck FilterMediaSeeking->Release();
801*c2c66affSColin Finck return hr;
802*c2c66affSColin Finck }
803*c2c66affSColin Finck
804*c2c66affSColin Finck HRESULT
805*c2c66affSColin Finck STDMETHODCALLTYPE
GetRate(double * pdRate)806*c2c66affSColin Finck COutputPin::GetRate(
807*c2c66affSColin Finck double *pdRate)
808*c2c66affSColin Finck {
809*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
810*c2c66affSColin Finck HRESULT hr;
811*c2c66affSColin Finck
812*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
813*c2c66affSColin Finck if (FAILED(hr))
814*c2c66affSColin Finck return hr;
815*c2c66affSColin Finck
816*c2c66affSColin Finck hr = FilterMediaSeeking->GetRate(pdRate);
817*c2c66affSColin Finck
818*c2c66affSColin Finck FilterMediaSeeking->Release();
819*c2c66affSColin Finck return hr;
820*c2c66affSColin Finck }
821*c2c66affSColin Finck
822*c2c66affSColin Finck HRESULT
823*c2c66affSColin Finck STDMETHODCALLTYPE
GetPreroll(LONGLONG * pllPreroll)824*c2c66affSColin Finck COutputPin::GetPreroll(
825*c2c66affSColin Finck LONGLONG *pllPreroll)
826*c2c66affSColin Finck {
827*c2c66affSColin Finck IMediaSeeking * FilterMediaSeeking;
828*c2c66affSColin Finck HRESULT hr;
829*c2c66affSColin Finck
830*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&FilterMediaSeeking);
831*c2c66affSColin Finck if (FAILED(hr))
832*c2c66affSColin Finck return hr;
833*c2c66affSColin Finck
834*c2c66affSColin Finck hr = FilterMediaSeeking->GetPreroll(pllPreroll);
835*c2c66affSColin Finck
836*c2c66affSColin Finck FilterMediaSeeking->Release();
837*c2c66affSColin Finck return hr;
838*c2c66affSColin Finck }
839*c2c66affSColin Finck
840*c2c66affSColin Finck //-------------------------------------------------------------------
841*c2c66affSColin Finck // IQualityControl interface
842*c2c66affSColin Finck //
843*c2c66affSColin Finck HRESULT
844*c2c66affSColin Finck STDMETHODCALLTYPE
Notify(IBaseFilter * pSelf,Quality q)845*c2c66affSColin Finck COutputPin::Notify(
846*c2c66affSColin Finck IBaseFilter *pSelf,
847*c2c66affSColin Finck Quality q)
848*c2c66affSColin Finck {
849*c2c66affSColin Finck #ifdef KSPROXY_TRACE
850*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::Notify NotImplemented\n");
851*c2c66affSColin Finck #endif
852*c2c66affSColin Finck return E_NOTIMPL;
853*c2c66affSColin Finck }
854*c2c66affSColin Finck
855*c2c66affSColin Finck HRESULT
856*c2c66affSColin Finck STDMETHODCALLTYPE
SetSink(IQualityControl * piqc)857*c2c66affSColin Finck COutputPin::SetSink(
858*c2c66affSColin Finck IQualityControl *piqc)
859*c2c66affSColin Finck {
860*c2c66affSColin Finck #ifdef KSPROXY_TRACE
861*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::SetSink NotImplemented\n");
862*c2c66affSColin Finck #endif
863*c2c66affSColin Finck return E_NOTIMPL;
864*c2c66affSColin Finck }
865*c2c66affSColin Finck
866*c2c66affSColin Finck
867*c2c66affSColin Finck //-------------------------------------------------------------------
868*c2c66affSColin Finck // IKsAggregateControl interface
869*c2c66affSColin Finck //
870*c2c66affSColin Finck HRESULT
871*c2c66affSColin Finck STDMETHODCALLTYPE
KsAddAggregate(IN REFGUID AggregateClass)872*c2c66affSColin Finck COutputPin::KsAddAggregate(
873*c2c66affSColin Finck IN REFGUID AggregateClass)
874*c2c66affSColin Finck {
875*c2c66affSColin Finck #ifdef KSPROXY_TRACE
876*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsAddAggregate NotImplemented\n");
877*c2c66affSColin Finck #endif
878*c2c66affSColin Finck return E_NOTIMPL;
879*c2c66affSColin Finck }
880*c2c66affSColin Finck
881*c2c66affSColin Finck HRESULT
882*c2c66affSColin Finck STDMETHODCALLTYPE
KsRemoveAggregate(REFGUID AggregateClass)883*c2c66affSColin Finck COutputPin::KsRemoveAggregate(
884*c2c66affSColin Finck REFGUID AggregateClass)
885*c2c66affSColin Finck {
886*c2c66affSColin Finck #ifdef KSPROXY_TRACE
887*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsRemoveAggregate NotImplemented\n");
888*c2c66affSColin Finck #endif
889*c2c66affSColin Finck return E_NOTIMPL;
890*c2c66affSColin Finck }
891*c2c66affSColin Finck
892*c2c66affSColin Finck
893*c2c66affSColin Finck //-------------------------------------------------------------------
894*c2c66affSColin Finck // IKsPin
895*c2c66affSColin Finck //
896*c2c66affSColin Finck
897*c2c66affSColin Finck HRESULT
898*c2c66affSColin Finck STDMETHODCALLTYPE
KsQueryMediums(PKSMULTIPLE_ITEM * MediumList)899*c2c66affSColin Finck COutputPin::KsQueryMediums(
900*c2c66affSColin Finck PKSMULTIPLE_ITEM* MediumList)
901*c2c66affSColin Finck {
902*c2c66affSColin Finck HRESULT hr;
903*c2c66affSColin Finck HANDLE hFilter;
904*c2c66affSColin Finck IKsObject * KsObjectParent;
905*c2c66affSColin Finck
906*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
907*c2c66affSColin Finck if (FAILED(hr))
908*c2c66affSColin Finck return E_NOINTERFACE;
909*c2c66affSColin Finck
910*c2c66affSColin Finck hFilter = KsObjectParent->KsGetObjectHandle();
911*c2c66affSColin Finck
912*c2c66affSColin Finck if (hFilter)
913*c2c66affSColin Finck hr = KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);
914*c2c66affSColin Finck else
915*c2c66affSColin Finck hr = E_HANDLE;
916*c2c66affSColin Finck
917*c2c66affSColin Finck KsObjectParent->Release();
918*c2c66affSColin Finck
919*c2c66affSColin Finck return hr;
920*c2c66affSColin Finck }
921*c2c66affSColin Finck
922*c2c66affSColin Finck HRESULT
923*c2c66affSColin Finck STDMETHODCALLTYPE
KsQueryInterfaces(PKSMULTIPLE_ITEM * InterfaceList)924*c2c66affSColin Finck COutputPin::KsQueryInterfaces(
925*c2c66affSColin Finck PKSMULTIPLE_ITEM* InterfaceList)
926*c2c66affSColin Finck {
927*c2c66affSColin Finck HRESULT hr;
928*c2c66affSColin Finck HANDLE hFilter;
929*c2c66affSColin Finck IKsObject * KsObjectParent;
930*c2c66affSColin Finck
931*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
932*c2c66affSColin Finck if (FAILED(hr))
933*c2c66affSColin Finck return hr;
934*c2c66affSColin Finck
935*c2c66affSColin Finck hFilter = KsObjectParent->KsGetObjectHandle();
936*c2c66affSColin Finck
937*c2c66affSColin Finck if (hFilter)
938*c2c66affSColin Finck hr = KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);
939*c2c66affSColin Finck else
940*c2c66affSColin Finck hr = E_HANDLE;
941*c2c66affSColin Finck
942*c2c66affSColin Finck KsObjectParent->Release();
943*c2c66affSColin Finck
944*c2c66affSColin Finck return hr;
945*c2c66affSColin Finck }
946*c2c66affSColin Finck
947*c2c66affSColin Finck HRESULT
948*c2c66affSColin Finck STDMETHODCALLTYPE
KsCreateSinkPinHandle(KSPIN_INTERFACE & Interface,KSPIN_MEDIUM & Medium)949*c2c66affSColin Finck COutputPin::KsCreateSinkPinHandle(
950*c2c66affSColin Finck KSPIN_INTERFACE& Interface,
951*c2c66affSColin Finck KSPIN_MEDIUM& Medium)
952*c2c66affSColin Finck {
953*c2c66affSColin Finck #ifdef KSPROXY_TRACE
954*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsCreateSinkPinHandle NotImplemented\n");
955*c2c66affSColin Finck #endif
956*c2c66affSColin Finck return E_NOTIMPL;
957*c2c66affSColin Finck }
958*c2c66affSColin Finck
959*c2c66affSColin Finck HRESULT
960*c2c66affSColin Finck STDMETHODCALLTYPE
KsGetCurrentCommunication(KSPIN_COMMUNICATION * Communication,KSPIN_INTERFACE * Interface,KSPIN_MEDIUM * Medium)961*c2c66affSColin Finck COutputPin::KsGetCurrentCommunication(
962*c2c66affSColin Finck KSPIN_COMMUNICATION *Communication,
963*c2c66affSColin Finck KSPIN_INTERFACE *Interface,
964*c2c66affSColin Finck KSPIN_MEDIUM *Medium)
965*c2c66affSColin Finck {
966*c2c66affSColin Finck if (Communication)
967*c2c66affSColin Finck {
968*c2c66affSColin Finck *Communication = m_Communication;
969*c2c66affSColin Finck }
970*c2c66affSColin Finck
971*c2c66affSColin Finck if (Interface)
972*c2c66affSColin Finck {
973*c2c66affSColin Finck if (!m_hPin)
974*c2c66affSColin Finck return VFW_E_NOT_CONNECTED;
975*c2c66affSColin Finck
976*c2c66affSColin Finck CopyMemory(Interface, &m_Interface, sizeof(KSPIN_INTERFACE));
977*c2c66affSColin Finck }
978*c2c66affSColin Finck
979*c2c66affSColin Finck if (Medium)
980*c2c66affSColin Finck {
981*c2c66affSColin Finck if (!m_hPin)
982*c2c66affSColin Finck return VFW_E_NOT_CONNECTED;
983*c2c66affSColin Finck
984*c2c66affSColin Finck CopyMemory(Medium, &m_Medium, sizeof(KSPIN_MEDIUM));
985*c2c66affSColin Finck }
986*c2c66affSColin Finck return NOERROR;
987*c2c66affSColin Finck }
988*c2c66affSColin Finck
989*c2c66affSColin Finck HRESULT
990*c2c66affSColin Finck STDMETHODCALLTYPE
KsPropagateAcquire()991*c2c66affSColin Finck COutputPin::KsPropagateAcquire()
992*c2c66affSColin Finck {
993*c2c66affSColin Finck KSPROPERTY Property;
994*c2c66affSColin Finck KSSTATE State;
995*c2c66affSColin Finck ULONG BytesReturned;
996*c2c66affSColin Finck HRESULT hr;
997*c2c66affSColin Finck
998*c2c66affSColin Finck #ifdef KSPROXY_TRACE
999*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsPropagateAcquire\n");
1000*c2c66affSColin Finck #endif
1001*c2c66affSColin Finck
1002*c2c66affSColin Finck assert(m_hPin != INVALID_HANDLE_VALUE);
1003*c2c66affSColin Finck
1004*c2c66affSColin Finck Property.Set = KSPROPSETID_Connection;
1005*c2c66affSColin Finck Property.Id = KSPROPERTY_CONNECTION_STATE;
1006*c2c66affSColin Finck Property.Flags = KSPROPERTY_TYPE_SET;
1007*c2c66affSColin Finck
1008*c2c66affSColin Finck State = KSSTATE_ACQUIRE;
1009*c2c66affSColin Finck
1010*c2c66affSColin Finck hr = KsProperty(&Property, sizeof(KSPROPERTY), (LPVOID)&State, sizeof(KSSTATE), &BytesReturned);
1011*c2c66affSColin Finck if (SUCCEEDED(hr))
1012*c2c66affSColin Finck {
1013*c2c66affSColin Finck m_State = State;
1014*c2c66affSColin Finck }
1015*c2c66affSColin Finck
1016*c2c66affSColin Finck //TODO
1017*c2c66affSColin Finck //propagate to connected pin on the pipe
1018*c2c66affSColin Finck
1019*c2c66affSColin Finck return hr;
1020*c2c66affSColin Finck }
1021*c2c66affSColin Finck
1022*c2c66affSColin Finck HRESULT
1023*c2c66affSColin Finck STDMETHODCALLTYPE
KsDeliver(IMediaSample * Sample,ULONG Flags)1024*c2c66affSColin Finck COutputPin::KsDeliver(
1025*c2c66affSColin Finck IMediaSample* Sample,
1026*c2c66affSColin Finck ULONG Flags)
1027*c2c66affSColin Finck {
1028*c2c66affSColin Finck return E_FAIL;
1029*c2c66affSColin Finck }
1030*c2c66affSColin Finck
1031*c2c66affSColin Finck HRESULT
1032*c2c66affSColin Finck STDMETHODCALLTYPE
KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment)1033*c2c66affSColin Finck COutputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment)
1034*c2c66affSColin Finck {
1035*c2c66affSColin Finck return NOERROR;
1036*c2c66affSColin Finck }
1037*c2c66affSColin Finck
1038*c2c66affSColin Finck IMemAllocator *
1039*c2c66affSColin Finck STDMETHODCALLTYPE
KsPeekAllocator(KSPEEKOPERATION Operation)1040*c2c66affSColin Finck COutputPin::KsPeekAllocator(KSPEEKOPERATION Operation)
1041*c2c66affSColin Finck {
1042*c2c66affSColin Finck if (Operation == KsPeekOperation_AddRef)
1043*c2c66affSColin Finck {
1044*c2c66affSColin Finck // add reference on allocator
1045*c2c66affSColin Finck m_MemAllocator->AddRef();
1046*c2c66affSColin Finck }
1047*c2c66affSColin Finck
1048*c2c66affSColin Finck return m_MemAllocator;
1049*c2c66affSColin Finck }
1050*c2c66affSColin Finck
1051*c2c66affSColin Finck HRESULT
1052*c2c66affSColin Finck STDMETHODCALLTYPE
KsReceiveAllocator(IMemAllocator * MemAllocator)1053*c2c66affSColin Finck COutputPin::KsReceiveAllocator(IMemAllocator *MemAllocator)
1054*c2c66affSColin Finck {
1055*c2c66affSColin Finck if (MemAllocator)
1056*c2c66affSColin Finck {
1057*c2c66affSColin Finck MemAllocator->AddRef();
1058*c2c66affSColin Finck }
1059*c2c66affSColin Finck
1060*c2c66affSColin Finck if (m_MemAllocator)
1061*c2c66affSColin Finck {
1062*c2c66affSColin Finck m_MemAllocator->Release();
1063*c2c66affSColin Finck }
1064*c2c66affSColin Finck
1065*c2c66affSColin Finck m_MemAllocator = MemAllocator;
1066*c2c66affSColin Finck return NOERROR;
1067*c2c66affSColin Finck }
1068*c2c66affSColin Finck
1069*c2c66affSColin Finck HRESULT
1070*c2c66affSColin Finck STDMETHODCALLTYPE
KsRenegotiateAllocator()1071*c2c66affSColin Finck COutputPin::KsRenegotiateAllocator()
1072*c2c66affSColin Finck {
1073*c2c66affSColin Finck return E_FAIL;
1074*c2c66affSColin Finck }
1075*c2c66affSColin Finck
1076*c2c66affSColin Finck LONG
1077*c2c66affSColin Finck STDMETHODCALLTYPE
KsIncrementPendingIoCount()1078*c2c66affSColin Finck COutputPin::KsIncrementPendingIoCount()
1079*c2c66affSColin Finck {
1080*c2c66affSColin Finck return InterlockedIncrement((volatile LONG*)&m_IoCount);
1081*c2c66affSColin Finck }
1082*c2c66affSColin Finck
1083*c2c66affSColin Finck LONG
1084*c2c66affSColin Finck STDMETHODCALLTYPE
KsDecrementPendingIoCount()1085*c2c66affSColin Finck COutputPin::KsDecrementPendingIoCount()
1086*c2c66affSColin Finck {
1087*c2c66affSColin Finck return InterlockedDecrement((volatile LONG*)&m_IoCount);
1088*c2c66affSColin Finck }
1089*c2c66affSColin Finck
1090*c2c66affSColin Finck HRESULT
1091*c2c66affSColin Finck STDMETHODCALLTYPE
KsQualityNotify(ULONG Proportion,REFERENCE_TIME TimeDelta)1092*c2c66affSColin Finck COutputPin::KsQualityNotify(
1093*c2c66affSColin Finck ULONG Proportion,
1094*c2c66affSColin Finck REFERENCE_TIME TimeDelta)
1095*c2c66affSColin Finck {
1096*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1097*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsQualityNotify NotImplemented\n");
1098*c2c66affSColin Finck #endif
1099*c2c66affSColin Finck return E_NOTIMPL;
1100*c2c66affSColin Finck }
1101*c2c66affSColin Finck
1102*c2c66affSColin Finck //-------------------------------------------------------------------
1103*c2c66affSColin Finck // IKsPinEx
1104*c2c66affSColin Finck //
1105*c2c66affSColin Finck
1106*c2c66affSColin Finck VOID
1107*c2c66affSColin Finck STDMETHODCALLTYPE
KsNotifyError(IMediaSample * Sample,HRESULT hr)1108*c2c66affSColin Finck COutputPin::KsNotifyError(
1109*c2c66affSColin Finck IMediaSample* Sample,
1110*c2c66affSColin Finck HRESULT hr)
1111*c2c66affSColin Finck {
1112*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1113*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsNotifyError NotImplemented\n");
1114*c2c66affSColin Finck #endif
1115*c2c66affSColin Finck }
1116*c2c66affSColin Finck
1117*c2c66affSColin Finck
1118*c2c66affSColin Finck //-------------------------------------------------------------------
1119*c2c66affSColin Finck // IKsPinPipe
1120*c2c66affSColin Finck //
1121*c2c66affSColin Finck
1122*c2c66affSColin Finck HRESULT
1123*c2c66affSColin Finck STDMETHODCALLTYPE
KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX * FramingEx,PFRAMING_PROP FramingProp,FRAMING_CACHE_OPS Option)1124*c2c66affSColin Finck COutputPin::KsGetPinFramingCache(
1125*c2c66affSColin Finck PKSALLOCATOR_FRAMING_EX *FramingEx,
1126*c2c66affSColin Finck PFRAMING_PROP FramingProp,
1127*c2c66affSColin Finck FRAMING_CACHE_OPS Option)
1128*c2c66affSColin Finck {
1129*c2c66affSColin Finck if (Option > Framing_Cache_Write || Option < Framing_Cache_ReadLast)
1130*c2c66affSColin Finck {
1131*c2c66affSColin Finck // invalid argument
1132*c2c66affSColin Finck return E_INVALIDARG;
1133*c2c66affSColin Finck }
1134*c2c66affSColin Finck
1135*c2c66affSColin Finck // get framing properties
1136*c2c66affSColin Finck *FramingProp = m_FramingProp[Option];
1137*c2c66affSColin Finck *FramingEx = m_FramingEx[Option];
1138*c2c66affSColin Finck
1139*c2c66affSColin Finck return NOERROR;
1140*c2c66affSColin Finck }
1141*c2c66affSColin Finck
1142*c2c66affSColin Finck HRESULT
1143*c2c66affSColin Finck STDMETHODCALLTYPE
KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx,PFRAMING_PROP FramingProp,FRAMING_CACHE_OPS Option)1144*c2c66affSColin Finck COutputPin::KsSetPinFramingCache(
1145*c2c66affSColin Finck PKSALLOCATOR_FRAMING_EX FramingEx,
1146*c2c66affSColin Finck PFRAMING_PROP FramingProp,
1147*c2c66affSColin Finck FRAMING_CACHE_OPS Option)
1148*c2c66affSColin Finck {
1149*c2c66affSColin Finck ULONG Index;
1150*c2c66affSColin Finck ULONG RefCount = 0;
1151*c2c66affSColin Finck
1152*c2c66affSColin Finck if (m_FramingEx[Option])
1153*c2c66affSColin Finck {
1154*c2c66affSColin Finck for(Index = 1; Index < 4; Index++)
1155*c2c66affSColin Finck {
1156*c2c66affSColin Finck if (m_FramingEx[Index] == m_FramingEx[Option])
1157*c2c66affSColin Finck RefCount++;
1158*c2c66affSColin Finck }
1159*c2c66affSColin Finck
1160*c2c66affSColin Finck if (RefCount == 1)
1161*c2c66affSColin Finck {
1162*c2c66affSColin Finck // existing framing is only used once
1163*c2c66affSColin Finck CoTaskMemFree(m_FramingEx[Option]);
1164*c2c66affSColin Finck }
1165*c2c66affSColin Finck }
1166*c2c66affSColin Finck
1167*c2c66affSColin Finck // store framing
1168*c2c66affSColin Finck m_FramingEx[Option] = FramingEx;
1169*c2c66affSColin Finck m_FramingProp[Option] = *FramingProp;
1170*c2c66affSColin Finck
1171*c2c66affSColin Finck return S_OK;
1172*c2c66affSColin Finck }
1173*c2c66affSColin Finck
1174*c2c66affSColin Finck IPin*
1175*c2c66affSColin Finck STDMETHODCALLTYPE
KsGetConnectedPin()1176*c2c66affSColin Finck COutputPin::KsGetConnectedPin()
1177*c2c66affSColin Finck {
1178*c2c66affSColin Finck return m_Pin;
1179*c2c66affSColin Finck }
1180*c2c66affSColin Finck
1181*c2c66affSColin Finck IKsAllocatorEx*
1182*c2c66affSColin Finck STDMETHODCALLTYPE
KsGetPipe(KSPEEKOPERATION Operation)1183*c2c66affSColin Finck COutputPin::KsGetPipe(
1184*c2c66affSColin Finck KSPEEKOPERATION Operation)
1185*c2c66affSColin Finck {
1186*c2c66affSColin Finck if (Operation == KsPeekOperation_AddRef)
1187*c2c66affSColin Finck {
1188*c2c66affSColin Finck if (m_KsAllocatorEx)
1189*c2c66affSColin Finck m_KsAllocatorEx->AddRef();
1190*c2c66affSColin Finck }
1191*c2c66affSColin Finck return m_KsAllocatorEx;
1192*c2c66affSColin Finck }
1193*c2c66affSColin Finck
1194*c2c66affSColin Finck HRESULT
1195*c2c66affSColin Finck STDMETHODCALLTYPE
KsSetPipe(IKsAllocatorEx * KsAllocator)1196*c2c66affSColin Finck COutputPin::KsSetPipe(
1197*c2c66affSColin Finck IKsAllocatorEx *KsAllocator)
1198*c2c66affSColin Finck {
1199*c2c66affSColin Finck if (KsAllocator)
1200*c2c66affSColin Finck KsAllocator->AddRef();
1201*c2c66affSColin Finck
1202*c2c66affSColin Finck if (m_KsAllocatorEx)
1203*c2c66affSColin Finck m_KsAllocatorEx->Release();
1204*c2c66affSColin Finck
1205*c2c66affSColin Finck m_KsAllocatorEx = KsAllocator;
1206*c2c66affSColin Finck return NOERROR;
1207*c2c66affSColin Finck }
1208*c2c66affSColin Finck
1209*c2c66affSColin Finck ULONG
1210*c2c66affSColin Finck STDMETHODCALLTYPE
KsGetPipeAllocatorFlag()1211*c2c66affSColin Finck COutputPin::KsGetPipeAllocatorFlag()
1212*c2c66affSColin Finck {
1213*c2c66affSColin Finck return m_PipeAllocatorFlag;
1214*c2c66affSColin Finck }
1215*c2c66affSColin Finck
1216*c2c66affSColin Finck
1217*c2c66affSColin Finck HRESULT
1218*c2c66affSColin Finck STDMETHODCALLTYPE
KsSetPipeAllocatorFlag(ULONG Flag)1219*c2c66affSColin Finck COutputPin::KsSetPipeAllocatorFlag(
1220*c2c66affSColin Finck ULONG Flag)
1221*c2c66affSColin Finck {
1222*c2c66affSColin Finck m_PipeAllocatorFlag = Flag;
1223*c2c66affSColin Finck return NOERROR;
1224*c2c66affSColin Finck }
1225*c2c66affSColin Finck
1226*c2c66affSColin Finck GUID
1227*c2c66affSColin Finck STDMETHODCALLTYPE
KsGetPinBusCache()1228*c2c66affSColin Finck COutputPin::KsGetPinBusCache()
1229*c2c66affSColin Finck {
1230*c2c66affSColin Finck if (!m_bPinBusCacheInitialized)
1231*c2c66affSColin Finck {
1232*c2c66affSColin Finck CopyMemory(&m_PinBusCache, &m_Medium.Set, sizeof(GUID));
1233*c2c66affSColin Finck m_bPinBusCacheInitialized = TRUE;
1234*c2c66affSColin Finck }
1235*c2c66affSColin Finck
1236*c2c66affSColin Finck return m_PinBusCache;
1237*c2c66affSColin Finck }
1238*c2c66affSColin Finck
1239*c2c66affSColin Finck HRESULT
1240*c2c66affSColin Finck STDMETHODCALLTYPE
KsSetPinBusCache(GUID Bus)1241*c2c66affSColin Finck COutputPin::KsSetPinBusCache(
1242*c2c66affSColin Finck GUID Bus)
1243*c2c66affSColin Finck {
1244*c2c66affSColin Finck CopyMemory(&m_PinBusCache, &Bus, sizeof(GUID));
1245*c2c66affSColin Finck return NOERROR;
1246*c2c66affSColin Finck }
1247*c2c66affSColin Finck
1248*c2c66affSColin Finck PWCHAR
1249*c2c66affSColin Finck STDMETHODCALLTYPE
KsGetPinName()1250*c2c66affSColin Finck COutputPin::KsGetPinName()
1251*c2c66affSColin Finck {
1252*c2c66affSColin Finck return (PWCHAR)m_PinName;
1253*c2c66affSColin Finck }
1254*c2c66affSColin Finck
1255*c2c66affSColin Finck
1256*c2c66affSColin Finck PWCHAR
1257*c2c66affSColin Finck STDMETHODCALLTYPE
KsGetFilterName()1258*c2c66affSColin Finck COutputPin::KsGetFilterName()
1259*c2c66affSColin Finck {
1260*c2c66affSColin Finck return m_FilterName;
1261*c2c66affSColin Finck }
1262*c2c66affSColin Finck
1263*c2c66affSColin Finck //-------------------------------------------------------------------
1264*c2c66affSColin Finck // ISpecifyPropertyPages
1265*c2c66affSColin Finck //
1266*c2c66affSColin Finck
1267*c2c66affSColin Finck HRESULT
1268*c2c66affSColin Finck STDMETHODCALLTYPE
GetPages(CAUUID * pPages)1269*c2c66affSColin Finck COutputPin::GetPages(CAUUID *pPages)
1270*c2c66affSColin Finck {
1271*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1272*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::GetPages NotImplemented\n");
1273*c2c66affSColin Finck #endif
1274*c2c66affSColin Finck
1275*c2c66affSColin Finck if (!pPages)
1276*c2c66affSColin Finck return E_POINTER;
1277*c2c66affSColin Finck
1278*c2c66affSColin Finck pPages->cElems = 0;
1279*c2c66affSColin Finck pPages->pElems = NULL;
1280*c2c66affSColin Finck
1281*c2c66affSColin Finck return S_OK;
1282*c2c66affSColin Finck }
1283*c2c66affSColin Finck
1284*c2c66affSColin Finck //-------------------------------------------------------------------
1285*c2c66affSColin Finck // IKsPinFactory
1286*c2c66affSColin Finck //
1287*c2c66affSColin Finck
1288*c2c66affSColin Finck HRESULT
1289*c2c66affSColin Finck STDMETHODCALLTYPE
KsPinFactory(ULONG * PinFactory)1290*c2c66affSColin Finck COutputPin::KsPinFactory(
1291*c2c66affSColin Finck ULONG* PinFactory)
1292*c2c66affSColin Finck {
1293*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1294*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsPinFactory\n");
1295*c2c66affSColin Finck #endif
1296*c2c66affSColin Finck
1297*c2c66affSColin Finck *PinFactory = m_PinId;
1298*c2c66affSColin Finck return S_OK;
1299*c2c66affSColin Finck }
1300*c2c66affSColin Finck
1301*c2c66affSColin Finck
1302*c2c66affSColin Finck //-------------------------------------------------------------------
1303*c2c66affSColin Finck // IStreamBuilder
1304*c2c66affSColin Finck //
1305*c2c66affSColin Finck
1306*c2c66affSColin Finck HRESULT
1307*c2c66affSColin Finck STDMETHODCALLTYPE
Render(IPin * ppinOut,IGraphBuilder * pGraph)1308*c2c66affSColin Finck COutputPin::Render(
1309*c2c66affSColin Finck IPin *ppinOut,
1310*c2c66affSColin Finck IGraphBuilder *pGraph)
1311*c2c66affSColin Finck {
1312*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1313*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::Render\n");
1314*c2c66affSColin Finck #endif
1315*c2c66affSColin Finck return S_OK;
1316*c2c66affSColin Finck }
1317*c2c66affSColin Finck
1318*c2c66affSColin Finck HRESULT
1319*c2c66affSColin Finck STDMETHODCALLTYPE
Backout(IPin * ppinOut,IGraphBuilder * pGraph)1320*c2c66affSColin Finck COutputPin::Backout(
1321*c2c66affSColin Finck IPin *ppinOut,
1322*c2c66affSColin Finck IGraphBuilder *pGraph)
1323*c2c66affSColin Finck {
1324*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1325*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::Backout\n");
1326*c2c66affSColin Finck #endif
1327*c2c66affSColin Finck
1328*c2c66affSColin Finck return S_OK;
1329*c2c66affSColin Finck }
1330*c2c66affSColin Finck //-------------------------------------------------------------------
1331*c2c66affSColin Finck // IKsObject
1332*c2c66affSColin Finck //
1333*c2c66affSColin Finck HANDLE
1334*c2c66affSColin Finck STDMETHODCALLTYPE
KsGetObjectHandle()1335*c2c66affSColin Finck COutputPin::KsGetObjectHandle()
1336*c2c66affSColin Finck {
1337*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1338*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsGetObjectHandle\n");
1339*c2c66affSColin Finck #endif
1340*c2c66affSColin Finck
1341*c2c66affSColin Finck assert(m_hPin != INVALID_HANDLE_VALUE);
1342*c2c66affSColin Finck return m_hPin;
1343*c2c66affSColin Finck }
1344*c2c66affSColin Finck
1345*c2c66affSColin Finck //-------------------------------------------------------------------
1346*c2c66affSColin Finck // IKsControl
1347*c2c66affSColin Finck //
1348*c2c66affSColin Finck HRESULT
1349*c2c66affSColin Finck STDMETHODCALLTYPE
KsProperty(PKSPROPERTY Property,ULONG PropertyLength,LPVOID PropertyData,ULONG DataLength,ULONG * BytesReturned)1350*c2c66affSColin Finck COutputPin::KsProperty(
1351*c2c66affSColin Finck PKSPROPERTY Property,
1352*c2c66affSColin Finck ULONG PropertyLength,
1353*c2c66affSColin Finck LPVOID PropertyData,
1354*c2c66affSColin Finck ULONG DataLength,
1355*c2c66affSColin Finck ULONG* BytesReturned)
1356*c2c66affSColin Finck {
1357*c2c66affSColin Finck HRESULT hr;
1358*c2c66affSColin Finck
1359*c2c66affSColin Finck assert(m_hPin != INVALID_HANDLE_VALUE);
1360*c2c66affSColin Finck
1361*c2c66affSColin Finck hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
1362*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1363*c2c66affSColin Finck WCHAR Buffer[100];
1364*c2c66affSColin Finck LPOLESTR pstr;
1365*c2c66affSColin Finck StringFromCLSID(Property->Set, &pstr);
1366*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::KsProperty Set %s Id %lu Flags %x hr %x\n", pstr, Property->Id, Property->Flags, hr);
1367*c2c66affSColin Finck OutputDebugStringW(Buffer);
1368*c2c66affSColin Finck #endif
1369*c2c66affSColin Finck
1370*c2c66affSColin Finck return hr;
1371*c2c66affSColin Finck }
1372*c2c66affSColin Finck
1373*c2c66affSColin Finck HRESULT
1374*c2c66affSColin Finck STDMETHODCALLTYPE
KsMethod(PKSMETHOD Method,ULONG MethodLength,LPVOID MethodData,ULONG DataLength,ULONG * BytesReturned)1375*c2c66affSColin Finck COutputPin::KsMethod(
1376*c2c66affSColin Finck PKSMETHOD Method,
1377*c2c66affSColin Finck ULONG MethodLength,
1378*c2c66affSColin Finck LPVOID MethodData,
1379*c2c66affSColin Finck ULONG DataLength,
1380*c2c66affSColin Finck ULONG* BytesReturned)
1381*c2c66affSColin Finck {
1382*c2c66affSColin Finck assert(m_hPin != INVALID_HANDLE_VALUE);
1383*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1384*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsMethod\n");
1385*c2c66affSColin Finck #endif
1386*c2c66affSColin Finck return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
1387*c2c66affSColin Finck }
1388*c2c66affSColin Finck
1389*c2c66affSColin Finck HRESULT
1390*c2c66affSColin Finck STDMETHODCALLTYPE
KsEvent(PKSEVENT Event,ULONG EventLength,LPVOID EventData,ULONG DataLength,ULONG * BytesReturned)1391*c2c66affSColin Finck COutputPin::KsEvent(
1392*c2c66affSColin Finck PKSEVENT Event,
1393*c2c66affSColin Finck ULONG EventLength,
1394*c2c66affSColin Finck LPVOID EventData,
1395*c2c66affSColin Finck ULONG DataLength,
1396*c2c66affSColin Finck ULONG* BytesReturned)
1397*c2c66affSColin Finck {
1398*c2c66affSColin Finck assert(m_hPin != INVALID_HANDLE_VALUE);
1399*c2c66affSColin Finck
1400*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1401*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::KsEvent\n");
1402*c2c66affSColin Finck #endif
1403*c2c66affSColin Finck
1404*c2c66affSColin Finck if (EventLength)
1405*c2c66affSColin Finck return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
1406*c2c66affSColin Finck else
1407*c2c66affSColin Finck return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned);
1408*c2c66affSColin Finck }
1409*c2c66affSColin Finck
1410*c2c66affSColin Finck
1411*c2c66affSColin Finck //-------------------------------------------------------------------
1412*c2c66affSColin Finck // IKsPropertySet
1413*c2c66affSColin Finck //
1414*c2c66affSColin Finck HRESULT
1415*c2c66affSColin Finck STDMETHODCALLTYPE
Set(REFGUID guidPropSet,DWORD dwPropID,LPVOID pInstanceData,DWORD cbInstanceData,LPVOID pPropData,DWORD cbPropData)1416*c2c66affSColin Finck COutputPin::Set(
1417*c2c66affSColin Finck REFGUID guidPropSet,
1418*c2c66affSColin Finck DWORD dwPropID,
1419*c2c66affSColin Finck LPVOID pInstanceData,
1420*c2c66affSColin Finck DWORD cbInstanceData,
1421*c2c66affSColin Finck LPVOID pPropData,
1422*c2c66affSColin Finck DWORD cbPropData)
1423*c2c66affSColin Finck {
1424*c2c66affSColin Finck ULONG BytesReturned;
1425*c2c66affSColin Finck
1426*c2c66affSColin Finck if (cbInstanceData)
1427*c2c66affSColin Finck {
1428*c2c66affSColin Finck PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
1429*c2c66affSColin Finck if (!Property)
1430*c2c66affSColin Finck return E_OUTOFMEMORY;
1431*c2c66affSColin Finck
1432*c2c66affSColin Finck Property->Set = guidPropSet;
1433*c2c66affSColin Finck Property->Id = dwPropID;
1434*c2c66affSColin Finck Property->Flags = KSPROPERTY_TYPE_SET;
1435*c2c66affSColin Finck
1436*c2c66affSColin Finck CopyMemory((Property+1), pInstanceData, cbInstanceData);
1437*c2c66affSColin Finck
1438*c2c66affSColin Finck HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned);
1439*c2c66affSColin Finck CoTaskMemFree(Property);
1440*c2c66affSColin Finck return hr;
1441*c2c66affSColin Finck }
1442*c2c66affSColin Finck else
1443*c2c66affSColin Finck {
1444*c2c66affSColin Finck KSPROPERTY Property;
1445*c2c66affSColin Finck
1446*c2c66affSColin Finck Property.Set = guidPropSet;
1447*c2c66affSColin Finck Property.Id = dwPropID;
1448*c2c66affSColin Finck Property.Flags = KSPROPERTY_TYPE_SET;
1449*c2c66affSColin Finck
1450*c2c66affSColin Finck HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned);
1451*c2c66affSColin Finck return hr;
1452*c2c66affSColin Finck }
1453*c2c66affSColin Finck }
1454*c2c66affSColin Finck
1455*c2c66affSColin Finck HRESULT
1456*c2c66affSColin Finck STDMETHODCALLTYPE
Get(REFGUID guidPropSet,DWORD dwPropID,LPVOID pInstanceData,DWORD cbInstanceData,LPVOID pPropData,DWORD cbPropData,DWORD * pcbReturned)1457*c2c66affSColin Finck COutputPin::Get(
1458*c2c66affSColin Finck REFGUID guidPropSet,
1459*c2c66affSColin Finck DWORD dwPropID,
1460*c2c66affSColin Finck LPVOID pInstanceData,
1461*c2c66affSColin Finck DWORD cbInstanceData,
1462*c2c66affSColin Finck LPVOID pPropData,
1463*c2c66affSColin Finck DWORD cbPropData,
1464*c2c66affSColin Finck DWORD *pcbReturned)
1465*c2c66affSColin Finck {
1466*c2c66affSColin Finck ULONG BytesReturned;
1467*c2c66affSColin Finck
1468*c2c66affSColin Finck if (cbInstanceData)
1469*c2c66affSColin Finck {
1470*c2c66affSColin Finck PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
1471*c2c66affSColin Finck if (!Property)
1472*c2c66affSColin Finck return E_OUTOFMEMORY;
1473*c2c66affSColin Finck
1474*c2c66affSColin Finck Property->Set = guidPropSet;
1475*c2c66affSColin Finck Property->Id = dwPropID;
1476*c2c66affSColin Finck Property->Flags = KSPROPERTY_TYPE_GET;
1477*c2c66affSColin Finck
1478*c2c66affSColin Finck CopyMemory((Property+1), pInstanceData, cbInstanceData);
1479*c2c66affSColin Finck
1480*c2c66affSColin Finck HRESULT hr = KsProperty(Property, sizeof(KSPROPERTY) + cbInstanceData, pPropData, cbPropData, &BytesReturned);
1481*c2c66affSColin Finck CoTaskMemFree(Property);
1482*c2c66affSColin Finck return hr;
1483*c2c66affSColin Finck }
1484*c2c66affSColin Finck else
1485*c2c66affSColin Finck {
1486*c2c66affSColin Finck KSPROPERTY Property;
1487*c2c66affSColin Finck
1488*c2c66affSColin Finck Property.Set = guidPropSet;
1489*c2c66affSColin Finck Property.Id = dwPropID;
1490*c2c66affSColin Finck Property.Flags = KSPROPERTY_TYPE_GET;
1491*c2c66affSColin Finck
1492*c2c66affSColin Finck HRESULT hr = KsProperty(&Property, sizeof(KSPROPERTY), pPropData, cbPropData, &BytesReturned);
1493*c2c66affSColin Finck return hr;
1494*c2c66affSColin Finck }
1495*c2c66affSColin Finck }
1496*c2c66affSColin Finck
1497*c2c66affSColin Finck HRESULT
1498*c2c66affSColin Finck STDMETHODCALLTYPE
QuerySupported(REFGUID guidPropSet,DWORD dwPropID,DWORD * pTypeSupport)1499*c2c66affSColin Finck COutputPin::QuerySupported(
1500*c2c66affSColin Finck REFGUID guidPropSet,
1501*c2c66affSColin Finck DWORD dwPropID,
1502*c2c66affSColin Finck DWORD *pTypeSupport)
1503*c2c66affSColin Finck {
1504*c2c66affSColin Finck KSPROPERTY Property;
1505*c2c66affSColin Finck ULONG BytesReturned;
1506*c2c66affSColin Finck
1507*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1508*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::QuerySupported\n");
1509*c2c66affSColin Finck #endif
1510*c2c66affSColin Finck
1511*c2c66affSColin Finck Property.Set = guidPropSet;
1512*c2c66affSColin Finck Property.Id = dwPropID;
1513*c2c66affSColin Finck Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
1514*c2c66affSColin Finck
1515*c2c66affSColin Finck return KsProperty(&Property, sizeof(KSPROPERTY), pTypeSupport, sizeof(DWORD), &BytesReturned);
1516*c2c66affSColin Finck }
1517*c2c66affSColin Finck
1518*c2c66affSColin Finck
1519*c2c66affSColin Finck //-------------------------------------------------------------------
1520*c2c66affSColin Finck // IPin interface
1521*c2c66affSColin Finck //
1522*c2c66affSColin Finck HRESULT
1523*c2c66affSColin Finck STDMETHODCALLTYPE
Connect(IPin * pReceivePin,const AM_MEDIA_TYPE * pmt)1524*c2c66affSColin Finck COutputPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
1525*c2c66affSColin Finck {
1526*c2c66affSColin Finck HRESULT hr;
1527*c2c66affSColin Finck ALLOCATOR_PROPERTIES Properties;
1528*c2c66affSColin Finck IMemAllocatorCallbackTemp *pMemCallback;
1529*c2c66affSColin Finck LPGUID pGuid;
1530*c2c66affSColin Finck ULONG NumGuids = 0;
1531*c2c66affSColin Finck
1532*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1533*c2c66affSColin Finck WCHAR Buffer[200];
1534*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::Connect called\n");
1535*c2c66affSColin Finck #endif
1536*c2c66affSColin Finck
1537*c2c66affSColin Finck if (pmt)
1538*c2c66affSColin Finck {
1539*c2c66affSColin Finck hr = pReceivePin->QueryAccept(pmt);
1540*c2c66affSColin Finck if (FAILED(hr))
1541*c2c66affSColin Finck return hr;
1542*c2c66affSColin Finck }
1543*c2c66affSColin Finck else
1544*c2c66affSColin Finck {
1545*c2c66affSColin Finck // query accept
1546*c2c66affSColin Finck hr = pReceivePin->QueryAccept(&m_MediaFormat);
1547*c2c66affSColin Finck if (FAILED(hr))
1548*c2c66affSColin Finck return hr;
1549*c2c66affSColin Finck
1550*c2c66affSColin Finck pmt = &m_MediaFormat;
1551*c2c66affSColin Finck }
1552*c2c66affSColin Finck
1553*c2c66affSColin Finck if (m_hPin == INVALID_HANDLE_VALUE)
1554*c2c66affSColin Finck {
1555*c2c66affSColin Finck hr = CreatePin(pmt);
1556*c2c66affSColin Finck if (FAILED(hr))
1557*c2c66affSColin Finck {
1558*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1559*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::Connect CreatePin handle failed with %lx\n", hr);
1560*c2c66affSColin Finck OutputDebugStringW(Buffer);
1561*c2c66affSColin Finck #endif
1562*c2c66affSColin Finck return hr;
1563*c2c66affSColin Finck }
1564*c2c66affSColin Finck }
1565*c2c66affSColin Finck
1566*c2c66affSColin Finck
1567*c2c66affSColin Finck // query for IMemInput interface
1568*c2c66affSColin Finck hr = pReceivePin->QueryInterface(IID_IMemInputPin, (void**)&m_MemInputPin);
1569*c2c66affSColin Finck if (FAILED(hr))
1570*c2c66affSColin Finck {
1571*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1572*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::Connect no IMemInputPin interface\n");
1573*c2c66affSColin Finck #endif
1574*c2c66affSColin Finck
1575*c2c66affSColin Finck return hr;
1576*c2c66affSColin Finck }
1577*c2c66affSColin Finck
1578*c2c66affSColin Finck // get input pin allocator properties
1579*c2c66affSColin Finck ZeroMemory(&Properties, sizeof(ALLOCATOR_PROPERTIES));
1580*c2c66affSColin Finck m_MemInputPin->GetAllocatorRequirements(&Properties);
1581*c2c66affSColin Finck
1582*c2c66affSColin Finck //FIXME determine allocator properties
1583*c2c66affSColin Finck Properties.cBuffers = 32;
1584*c2c66affSColin Finck Properties.cbBuffer = 2048 * 188; //2048 frames * MPEG2 TS Payload size
1585*c2c66affSColin Finck Properties.cbAlign = 4;
1586*c2c66affSColin Finck
1587*c2c66affSColin Finck // get input pin allocator
1588*c2c66affSColin Finck #if 0
1589*c2c66affSColin Finck hr = m_MemInputPin->GetAllocator(&m_MemAllocator);
1590*c2c66affSColin Finck if (SUCCEEDED(hr))
1591*c2c66affSColin Finck {
1592*c2c66affSColin Finck // set allocator properties
1593*c2c66affSColin Finck hr = m_MemAllocator->SetProperties(&Properties, &m_Properties);
1594*c2c66affSColin Finck if (FAILED(hr))
1595*c2c66affSColin Finck m_MemAllocator->Release();
1596*c2c66affSColin Finck }
1597*c2c66affSColin Finck #endif
1598*c2c66affSColin Finck
1599*c2c66affSColin Finck if (1)
1600*c2c66affSColin Finck {
1601*c2c66affSColin Finck hr = CKsAllocator_Constructor(NULL, IID_IMemAllocator, (void**)&m_MemAllocator);
1602*c2c66affSColin Finck if (FAILED(hr))
1603*c2c66affSColin Finck return hr;
1604*c2c66affSColin Finck
1605*c2c66affSColin Finck // set allocator properties
1606*c2c66affSColin Finck hr = m_MemAllocator->SetProperties(&Properties, &m_Properties);
1607*c2c66affSColin Finck if (FAILED(hr))
1608*c2c66affSColin Finck {
1609*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1610*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::Connect IMemAllocator::SetProperties failed with hr %lx\n", hr);
1611*c2c66affSColin Finck OutputDebugStringW(Buffer);
1612*c2c66affSColin Finck #endif
1613*c2c66affSColin Finck m_MemAllocator->Release();
1614*c2c66affSColin Finck m_MemInputPin->Release();
1615*c2c66affSColin Finck return hr;
1616*c2c66affSColin Finck }
1617*c2c66affSColin Finck }
1618*c2c66affSColin Finck
1619*c2c66affSColin Finck // commit property changes
1620*c2c66affSColin Finck hr = m_MemAllocator->Commit();
1621*c2c66affSColin Finck if (FAILED(hr))
1622*c2c66affSColin Finck {
1623*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1624*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::Connect IMemAllocator::Commit failed with hr %lx\n", hr);
1625*c2c66affSColin Finck OutputDebugStringW(Buffer);
1626*c2c66affSColin Finck #endif
1627*c2c66affSColin Finck m_MemAllocator->Release();
1628*c2c66affSColin Finck m_MemInputPin->Release();
1629*c2c66affSColin Finck return hr;
1630*c2c66affSColin Finck }
1631*c2c66affSColin Finck
1632*c2c66affSColin Finck // get callback interface
1633*c2c66affSColin Finck hr = m_MemAllocator->QueryInterface(IID_IMemAllocatorCallbackTemp, (void**)&pMemCallback);
1634*c2c66affSColin Finck if (FAILED(hr))
1635*c2c66affSColin Finck {
1636*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1637*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::Connect No IMemAllocatorCallbackTemp interface hr %lx\n", hr);
1638*c2c66affSColin Finck OutputDebugStringW(Buffer);
1639*c2c66affSColin Finck #endif
1640*c2c66affSColin Finck m_MemAllocator->Release();
1641*c2c66affSColin Finck m_MemInputPin->Release();
1642*c2c66affSColin Finck return hr;
1643*c2c66affSColin Finck }
1644*c2c66affSColin Finck
1645*c2c66affSColin Finck // set notification routine
1646*c2c66affSColin Finck hr = pMemCallback->SetNotify((IMemAllocatorNotifyCallbackTemp*)this);
1647*c2c66affSColin Finck
1648*c2c66affSColin Finck // release IMemAllocatorNotifyCallbackTemp interface
1649*c2c66affSColin Finck pMemCallback->Release();
1650*c2c66affSColin Finck
1651*c2c66affSColin Finck if (FAILED(hr))
1652*c2c66affSColin Finck {
1653*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1654*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::Connect IMemAllocatorNotifyCallbackTemp::SetNotify failed hr %lx\n", hr);
1655*c2c66affSColin Finck OutputDebugStringW(Buffer);
1656*c2c66affSColin Finck #endif
1657*c2c66affSColin Finck m_MemAllocator->Release();
1658*c2c66affSColin Finck m_MemInputPin->Release();
1659*c2c66affSColin Finck return hr;
1660*c2c66affSColin Finck }
1661*c2c66affSColin Finck
1662*c2c66affSColin Finck // now set allocator
1663*c2c66affSColin Finck hr = m_MemInputPin->NotifyAllocator(m_MemAllocator, TRUE);
1664*c2c66affSColin Finck if (FAILED(hr))
1665*c2c66affSColin Finck {
1666*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1667*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::Connect IMemInputPin::NotifyAllocator failed with hr %lx\n", hr);
1668*c2c66affSColin Finck OutputDebugStringW(Buffer);
1669*c2c66affSColin Finck #endif
1670*c2c66affSColin Finck m_MemAllocator->Release();
1671*c2c66affSColin Finck m_MemInputPin->Release();
1672*c2c66affSColin Finck return hr;
1673*c2c66affSColin Finck }
1674*c2c66affSColin Finck
1675*c2c66affSColin Finck
1676*c2c66affSColin Finck assert(m_hPin != INVALID_HANDLE_VALUE);
1677*c2c66affSColin Finck
1678*c2c66affSColin Finck // get all supported sets
1679*c2c66affSColin Finck if (m_Plugins.empty())
1680*c2c66affSColin Finck {
1681*c2c66affSColin Finck if (GetSupportedSets(&pGuid, &NumGuids))
1682*c2c66affSColin Finck {
1683*c2c66affSColin Finck // load all proxy plugins
1684*c2c66affSColin Finck if (FAILED(LoadProxyPlugins(pGuid, NumGuids)))
1685*c2c66affSColin Finck {
1686*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1687*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::Connect LoadProxyPlugins failed\n");
1688*c2c66affSColin Finck #endif
1689*c2c66affSColin Finck }
1690*c2c66affSColin Finck // free sets
1691*c2c66affSColin Finck CoTaskMemFree(pGuid);
1692*c2c66affSColin Finck }
1693*c2c66affSColin Finck }
1694*c2c66affSColin Finck
1695*c2c66affSColin Finck // receive connection;
1696*c2c66affSColin Finck hr = pReceivePin->ReceiveConnection((IPin*)this, pmt);
1697*c2c66affSColin Finck if (SUCCEEDED(hr))
1698*c2c66affSColin Finck {
1699*c2c66affSColin Finck // increment reference count
1700*c2c66affSColin Finck pReceivePin->AddRef();
1701*c2c66affSColin Finck m_Pin = pReceivePin;
1702*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1703*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::Connect success\n");
1704*c2c66affSColin Finck #endif
1705*c2c66affSColin Finck }
1706*c2c66affSColin Finck else
1707*c2c66affSColin Finck {
1708*c2c66affSColin Finck m_MemInputPin->Release();
1709*c2c66affSColin Finck m_MemAllocator->Release();
1710*c2c66affSColin Finck }
1711*c2c66affSColin Finck
1712*c2c66affSColin Finck return hr;
1713*c2c66affSColin Finck }
1714*c2c66affSColin Finck
1715*c2c66affSColin Finck HRESULT
1716*c2c66affSColin Finck STDMETHODCALLTYPE
ReceiveConnection(IPin * pConnector,const AM_MEDIA_TYPE * pmt)1717*c2c66affSColin Finck COutputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
1718*c2c66affSColin Finck {
1719*c2c66affSColin Finck return E_UNEXPECTED;
1720*c2c66affSColin Finck }
1721*c2c66affSColin Finck HRESULT
1722*c2c66affSColin Finck STDMETHODCALLTYPE
Disconnect(void)1723*c2c66affSColin Finck COutputPin::Disconnect( void)
1724*c2c66affSColin Finck {
1725*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1726*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::Disconnect\n");
1727*c2c66affSColin Finck #endif
1728*c2c66affSColin Finck
1729*c2c66affSColin Finck if (!m_Pin)
1730*c2c66affSColin Finck {
1731*c2c66affSColin Finck // pin was not connected
1732*c2c66affSColin Finck return S_FALSE;
1733*c2c66affSColin Finck }
1734*c2c66affSColin Finck
1735*c2c66affSColin Finck //FIXME
1736*c2c66affSColin Finck //check if filter is active
1737*c2c66affSColin Finck
1738*c2c66affSColin Finck m_Pin->Release();
1739*c2c66affSColin Finck m_Pin = NULL;
1740*c2c66affSColin Finck m_MemInputPin->Release();
1741*c2c66affSColin Finck m_MemAllocator->Release();
1742*c2c66affSColin Finck
1743*c2c66affSColin Finck CloseHandle(m_hPin);
1744*c2c66affSColin Finck m_hPin = INVALID_HANDLE_VALUE;
1745*c2c66affSColin Finck
1746*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1747*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::Disconnect\n");
1748*c2c66affSColin Finck #endif
1749*c2c66affSColin Finck return S_OK;
1750*c2c66affSColin Finck }
1751*c2c66affSColin Finck HRESULT
1752*c2c66affSColin Finck STDMETHODCALLTYPE
ConnectedTo(IPin ** pPin)1753*c2c66affSColin Finck COutputPin::ConnectedTo(IPin **pPin)
1754*c2c66affSColin Finck {
1755*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1756*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::ConnectedTo\n");
1757*c2c66affSColin Finck #endif
1758*c2c66affSColin Finck
1759*c2c66affSColin Finck if (!pPin)
1760*c2c66affSColin Finck return E_POINTER;
1761*c2c66affSColin Finck
1762*c2c66affSColin Finck if (m_Pin)
1763*c2c66affSColin Finck {
1764*c2c66affSColin Finck // increment reference count
1765*c2c66affSColin Finck m_Pin->AddRef();
1766*c2c66affSColin Finck *pPin = m_Pin;
1767*c2c66affSColin Finck return S_OK;
1768*c2c66affSColin Finck }
1769*c2c66affSColin Finck
1770*c2c66affSColin Finck *pPin = NULL;
1771*c2c66affSColin Finck return VFW_E_NOT_CONNECTED;
1772*c2c66affSColin Finck }
1773*c2c66affSColin Finck HRESULT
1774*c2c66affSColin Finck STDMETHODCALLTYPE
ConnectionMediaType(AM_MEDIA_TYPE * pmt)1775*c2c66affSColin Finck COutputPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt)
1776*c2c66affSColin Finck {
1777*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1778*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::ConnectionMediaType called\n");
1779*c2c66affSColin Finck #endif
1780*c2c66affSColin Finck
1781*c2c66affSColin Finck return E_NOTIMPL;
1782*c2c66affSColin Finck }
1783*c2c66affSColin Finck HRESULT
1784*c2c66affSColin Finck STDMETHODCALLTYPE
QueryPinInfo(PIN_INFO * pInfo)1785*c2c66affSColin Finck COutputPin::QueryPinInfo(PIN_INFO *pInfo)
1786*c2c66affSColin Finck {
1787*c2c66affSColin Finck wcscpy(pInfo->achName, m_PinName);
1788*c2c66affSColin Finck pInfo->dir = PINDIR_OUTPUT;
1789*c2c66affSColin Finck pInfo->pFilter = m_ParentFilter;
1790*c2c66affSColin Finck m_ParentFilter->AddRef();
1791*c2c66affSColin Finck
1792*c2c66affSColin Finck return S_OK;
1793*c2c66affSColin Finck }
1794*c2c66affSColin Finck HRESULT
1795*c2c66affSColin Finck STDMETHODCALLTYPE
QueryDirection(PIN_DIRECTION * pPinDir)1796*c2c66affSColin Finck COutputPin::QueryDirection(PIN_DIRECTION *pPinDir)
1797*c2c66affSColin Finck {
1798*c2c66affSColin Finck if (pPinDir)
1799*c2c66affSColin Finck {
1800*c2c66affSColin Finck *pPinDir = PINDIR_OUTPUT;
1801*c2c66affSColin Finck return S_OK;
1802*c2c66affSColin Finck }
1803*c2c66affSColin Finck
1804*c2c66affSColin Finck return E_POINTER;
1805*c2c66affSColin Finck }
1806*c2c66affSColin Finck HRESULT
1807*c2c66affSColin Finck STDMETHODCALLTYPE
QueryId(LPWSTR * Id)1808*c2c66affSColin Finck COutputPin::QueryId(LPWSTR *Id)
1809*c2c66affSColin Finck {
1810*c2c66affSColin Finck *Id = (LPWSTR)CoTaskMemAlloc((wcslen(m_PinName)+1)*sizeof(WCHAR));
1811*c2c66affSColin Finck if (!*Id)
1812*c2c66affSColin Finck return E_OUTOFMEMORY;
1813*c2c66affSColin Finck
1814*c2c66affSColin Finck wcscpy(*Id, m_PinName);
1815*c2c66affSColin Finck return S_OK;
1816*c2c66affSColin Finck }
1817*c2c66affSColin Finck HRESULT
1818*c2c66affSColin Finck STDMETHODCALLTYPE
QueryAccept(const AM_MEDIA_TYPE * pmt)1819*c2c66affSColin Finck COutputPin::QueryAccept(const AM_MEDIA_TYPE *pmt)
1820*c2c66affSColin Finck {
1821*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1822*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::QueryAccept called\n");
1823*c2c66affSColin Finck #endif
1824*c2c66affSColin Finck
1825*c2c66affSColin Finck return E_NOTIMPL;
1826*c2c66affSColin Finck }
1827*c2c66affSColin Finck HRESULT
1828*c2c66affSColin Finck STDMETHODCALLTYPE
EnumMediaTypes(IEnumMediaTypes ** ppEnum)1829*c2c66affSColin Finck COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
1830*c2c66affSColin Finck {
1831*c2c66affSColin Finck HRESULT hr;
1832*c2c66affSColin Finck ULONG MediaTypeCount = 0, Index;
1833*c2c66affSColin Finck AM_MEDIA_TYPE * MediaTypes;
1834*c2c66affSColin Finck HANDLE hFilter;
1835*c2c66affSColin Finck IKsObject * KsObjectParent;
1836*c2c66affSColin Finck
1837*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
1838*c2c66affSColin Finck if (FAILED(hr))
1839*c2c66affSColin Finck return hr;
1840*c2c66affSColin Finck
1841*c2c66affSColin Finck // get parent filter handle
1842*c2c66affSColin Finck hFilter = KsObjectParent->KsGetObjectHandle();
1843*c2c66affSColin Finck
1844*c2c66affSColin Finck // release IKsObject
1845*c2c66affSColin Finck KsObjectParent->Release();
1846*c2c66affSColin Finck
1847*c2c66affSColin Finck // query media type count
1848*c2c66affSColin Finck hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount);
1849*c2c66affSColin Finck if (FAILED(hr) || !MediaTypeCount)
1850*c2c66affSColin Finck {
1851*c2c66affSColin Finck return hr;
1852*c2c66affSColin Finck }
1853*c2c66affSColin Finck
1854*c2c66affSColin Finck // allocate media types
1855*c2c66affSColin Finck MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount);
1856*c2c66affSColin Finck if (!MediaTypes)
1857*c2c66affSColin Finck {
1858*c2c66affSColin Finck // not enough memory
1859*c2c66affSColin Finck return E_OUTOFMEMORY;
1860*c2c66affSColin Finck }
1861*c2c66affSColin Finck
1862*c2c66affSColin Finck // zero media types
1863*c2c66affSColin Finck ZeroMemory(MediaTypes, sizeof(AM_MEDIA_TYPE) * MediaTypeCount);
1864*c2c66affSColin Finck
1865*c2c66affSColin Finck for(Index = 0; Index < MediaTypeCount; Index++)
1866*c2c66affSColin Finck {
1867*c2c66affSColin Finck // get media type
1868*c2c66affSColin Finck hr = KsGetMediaType(Index, &MediaTypes[Index], hFilter, m_PinId);
1869*c2c66affSColin Finck if (FAILED(hr))
1870*c2c66affSColin Finck {
1871*c2c66affSColin Finck // failed
1872*c2c66affSColin Finck CoTaskMemFree(MediaTypes);
1873*c2c66affSColin Finck return hr;
1874*c2c66affSColin Finck }
1875*c2c66affSColin Finck }
1876*c2c66affSColin Finck
1877*c2c66affSColin Finck return CEnumMediaTypes_fnConstructor(MediaTypeCount, MediaTypes, IID_IEnumMediaTypes, (void**)ppEnum);
1878*c2c66affSColin Finck }
1879*c2c66affSColin Finck HRESULT
1880*c2c66affSColin Finck STDMETHODCALLTYPE
QueryInternalConnections(IPin ** apPin,ULONG * nPin)1881*c2c66affSColin Finck COutputPin::QueryInternalConnections(IPin **apPin, ULONG *nPin)
1882*c2c66affSColin Finck {
1883*c2c66affSColin Finck return E_NOTIMPL;
1884*c2c66affSColin Finck }
1885*c2c66affSColin Finck HRESULT
1886*c2c66affSColin Finck STDMETHODCALLTYPE
EndOfStream(void)1887*c2c66affSColin Finck COutputPin::EndOfStream( void)
1888*c2c66affSColin Finck {
1889*c2c66affSColin Finck /* should be called only on input pins */
1890*c2c66affSColin Finck return E_UNEXPECTED;
1891*c2c66affSColin Finck }
1892*c2c66affSColin Finck HRESULT
1893*c2c66affSColin Finck STDMETHODCALLTYPE
BeginFlush(void)1894*c2c66affSColin Finck COutputPin::BeginFlush( void)
1895*c2c66affSColin Finck {
1896*c2c66affSColin Finck /* should be called only on input pins */
1897*c2c66affSColin Finck return E_UNEXPECTED;
1898*c2c66affSColin Finck }
1899*c2c66affSColin Finck HRESULT
1900*c2c66affSColin Finck STDMETHODCALLTYPE
EndFlush(void)1901*c2c66affSColin Finck COutputPin::EndFlush( void)
1902*c2c66affSColin Finck {
1903*c2c66affSColin Finck /* should be called only on input pins */
1904*c2c66affSColin Finck return E_UNEXPECTED;
1905*c2c66affSColin Finck }
1906*c2c66affSColin Finck HRESULT
1907*c2c66affSColin Finck STDMETHODCALLTYPE
NewSegment(REFERENCE_TIME tStart,REFERENCE_TIME tStop,double dRate)1908*c2c66affSColin Finck COutputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
1909*c2c66affSColin Finck {
1910*c2c66affSColin Finck if (!m_Pin)
1911*c2c66affSColin Finck {
1912*c2c66affSColin Finck // we are not connected
1913*c2c66affSColin Finck return VFW_E_NOT_CONNECTED;
1914*c2c66affSColin Finck }
1915*c2c66affSColin Finck
1916*c2c66affSColin Finck return m_Pin->NewSegment(tStart, tStop, dRate);
1917*c2c66affSColin Finck }
1918*c2c66affSColin Finck
1919*c2c66affSColin Finck //-------------------------------------------------------------------
1920*c2c66affSColin Finck HRESULT
1921*c2c66affSColin Finck STDMETHODCALLTYPE
CheckFormat(const AM_MEDIA_TYPE * pmt)1922*c2c66affSColin Finck COutputPin::CheckFormat(
1923*c2c66affSColin Finck const AM_MEDIA_TYPE *pmt)
1924*c2c66affSColin Finck {
1925*c2c66affSColin Finck PKSMULTIPLE_ITEM MultipleItem;
1926*c2c66affSColin Finck PKSDATAFORMAT DataFormat;
1927*c2c66affSColin Finck HRESULT hr;
1928*c2c66affSColin Finck IKsObject * KsObjectParent;
1929*c2c66affSColin Finck HANDLE hFilter;
1930*c2c66affSColin Finck
1931*c2c66affSColin Finck if (!pmt)
1932*c2c66affSColin Finck return E_POINTER;
1933*c2c66affSColin Finck
1934*c2c66affSColin Finck // get IKsObject interface
1935*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
1936*c2c66affSColin Finck if (FAILED(hr))
1937*c2c66affSColin Finck return hr;
1938*c2c66affSColin Finck
1939*c2c66affSColin Finck // get parent filter handle
1940*c2c66affSColin Finck hFilter = KsObjectParent->KsGetObjectHandle();
1941*c2c66affSColin Finck
1942*c2c66affSColin Finck // release IKsObject
1943*c2c66affSColin Finck KsObjectParent->Release();
1944*c2c66affSColin Finck
1945*c2c66affSColin Finck if (!hFilter)
1946*c2c66affSColin Finck return E_HANDLE;
1947*c2c66affSColin Finck
1948*c2c66affSColin Finck
1949*c2c66affSColin Finck hr = KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_DATARANGES, (PVOID*)&MultipleItem);
1950*c2c66affSColin Finck if (FAILED(hr))
1951*c2c66affSColin Finck return S_FALSE;
1952*c2c66affSColin Finck
1953*c2c66affSColin Finck DataFormat = (PKSDATAFORMAT)(MultipleItem + 1);
1954*c2c66affSColin Finck for(ULONG Index = 0; Index < MultipleItem->Count; Index++)
1955*c2c66affSColin Finck {
1956*c2c66affSColin Finck if (IsEqualGUID(pmt->majortype, DataFormat->MajorFormat) &&
1957*c2c66affSColin Finck IsEqualGUID(pmt->subtype, DataFormat->SubFormat) &&
1958*c2c66affSColin Finck IsEqualGUID(pmt->formattype, DataFormat->Specifier))
1959*c2c66affSColin Finck {
1960*c2c66affSColin Finck // format is supported
1961*c2c66affSColin Finck CoTaskMemFree(MultipleItem);
1962*c2c66affSColin Finck return S_OK;
1963*c2c66affSColin Finck }
1964*c2c66affSColin Finck DataFormat = (PKSDATAFORMAT)((ULONG_PTR)DataFormat + DataFormat->FormatSize);
1965*c2c66affSColin Finck }
1966*c2c66affSColin Finck //format is not supported
1967*c2c66affSColin Finck CoTaskMemFree(MultipleItem);
1968*c2c66affSColin Finck return S_FALSE;
1969*c2c66affSColin Finck }
1970*c2c66affSColin Finck
1971*c2c66affSColin Finck HRESULT
1972*c2c66affSColin Finck STDMETHODCALLTYPE
CreatePin(const AM_MEDIA_TYPE * pmt)1973*c2c66affSColin Finck COutputPin::CreatePin(
1974*c2c66affSColin Finck const AM_MEDIA_TYPE *pmt)
1975*c2c66affSColin Finck {
1976*c2c66affSColin Finck PKSMULTIPLE_ITEM MediumList;
1977*c2c66affSColin Finck PKSMULTIPLE_ITEM InterfaceList;
1978*c2c66affSColin Finck PKSPIN_MEDIUM Medium;
1979*c2c66affSColin Finck PKSPIN_INTERFACE Interface;
1980*c2c66affSColin Finck IKsInterfaceHandler * InterfaceHandler;
1981*c2c66affSColin Finck HRESULT hr;
1982*c2c66affSColin Finck
1983*c2c66affSColin Finck // query for pin medium
1984*c2c66affSColin Finck hr = KsQueryMediums(&MediumList);
1985*c2c66affSColin Finck if (FAILED(hr))
1986*c2c66affSColin Finck {
1987*c2c66affSColin Finck #ifdef KSPROXY_TRACE
1988*c2c66affSColin Finck WCHAR Buffer[100];
1989*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::CreatePin KsQueryMediums failed %lx\n", hr);
1990*c2c66affSColin Finck OutputDebugStringW(Buffer);
1991*c2c66affSColin Finck #endif
1992*c2c66affSColin Finck return hr;
1993*c2c66affSColin Finck }
1994*c2c66affSColin Finck
1995*c2c66affSColin Finck // query for pin interface
1996*c2c66affSColin Finck hr = KsQueryInterfaces(&InterfaceList);
1997*c2c66affSColin Finck if (FAILED(hr))
1998*c2c66affSColin Finck {
1999*c2c66affSColin Finck // failed
2000*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2001*c2c66affSColin Finck WCHAR Buffer[100];
2002*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::CreatePin KsQueryInterfaces failed %lx\n", hr);
2003*c2c66affSColin Finck OutputDebugStringW(Buffer);
2004*c2c66affSColin Finck #endif
2005*c2c66affSColin Finck
2006*c2c66affSColin Finck CoTaskMemFree(MediumList);
2007*c2c66affSColin Finck return hr;
2008*c2c66affSColin Finck }
2009*c2c66affSColin Finck
2010*c2c66affSColin Finck if (MediumList->Count)
2011*c2c66affSColin Finck {
2012*c2c66affSColin Finck //use first available medium
2013*c2c66affSColin Finck Medium = (PKSPIN_MEDIUM)(MediumList + 1);
2014*c2c66affSColin Finck }
2015*c2c66affSColin Finck else
2016*c2c66affSColin Finck {
2017*c2c66affSColin Finck // default to standard medium
2018*c2c66affSColin Finck Medium = &StandardPinMedium;
2019*c2c66affSColin Finck }
2020*c2c66affSColin Finck
2021*c2c66affSColin Finck if (InterfaceList->Count)
2022*c2c66affSColin Finck {
2023*c2c66affSColin Finck //use first available interface
2024*c2c66affSColin Finck Interface = (PKSPIN_INTERFACE)(InterfaceList + 1);
2025*c2c66affSColin Finck }
2026*c2c66affSColin Finck else
2027*c2c66affSColin Finck {
2028*c2c66affSColin Finck // default to standard interface
2029*c2c66affSColin Finck Interface = &StandardPinInterface;
2030*c2c66affSColin Finck }
2031*c2c66affSColin Finck
2032*c2c66affSColin Finck if (m_Communication != KSPIN_COMMUNICATION_BRIDGE && m_Communication != KSPIN_COMMUNICATION_NONE)
2033*c2c66affSColin Finck {
2034*c2c66affSColin Finck // now create pin
2035*c2c66affSColin Finck hr = CreatePinHandle(Medium, Interface, pmt);
2036*c2c66affSColin Finck if (FAILED(hr))
2037*c2c66affSColin Finck {
2038*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2039*c2c66affSColin Finck WCHAR Buffer[100];
2040*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::CreatePinHandle failed with %lx\n", hr);
2041*c2c66affSColin Finck OutputDebugStringW(Buffer);
2042*c2c66affSColin Finck #endif
2043*c2c66affSColin Finck return hr;
2044*c2c66affSColin Finck }
2045*c2c66affSColin Finck
2046*c2c66affSColin Finck if (!m_InterfaceHandler)
2047*c2c66affSColin Finck {
2048*c2c66affSColin Finck // now load the IKsInterfaceHandler plugin
2049*c2c66affSColin Finck hr = CoCreateInstance(Interface->Set, NULL, CLSCTX_INPROC_SERVER, IID_IKsInterfaceHandler, (void**)&InterfaceHandler);
2050*c2c66affSColin Finck if (FAILED(hr))
2051*c2c66affSColin Finck {
2052*c2c66affSColin Finck // failed to load interface handler plugin
2053*c2c66affSColin Finck CoTaskMemFree(MediumList);
2054*c2c66affSColin Finck CoTaskMemFree(InterfaceList);
2055*c2c66affSColin Finck
2056*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2057*c2c66affSColin Finck WCHAR Buffer[100];
2058*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::CreatePin failed to create interface handler %lx\n", hr);
2059*c2c66affSColin Finck OutputDebugStringW(Buffer);
2060*c2c66affSColin Finck #endif
2061*c2c66affSColin Finck
2062*c2c66affSColin Finck return hr;
2063*c2c66affSColin Finck }
2064*c2c66affSColin Finck
2065*c2c66affSColin Finck // now set the pin
2066*c2c66affSColin Finck hr = InterfaceHandler->KsSetPin((IKsPin*)this);
2067*c2c66affSColin Finck if (FAILED(hr))
2068*c2c66affSColin Finck {
2069*c2c66affSColin Finck // failed to initialize interface handler plugin
2070*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2071*c2c66affSColin Finck WCHAR Buffer[100];
2072*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::CreatePin failed to initialize interface handler %lx\n", hr);
2073*c2c66affSColin Finck OutputDebugStringW(Buffer);
2074*c2c66affSColin Finck #endif
2075*c2c66affSColin Finck InterfaceHandler->Release();
2076*c2c66affSColin Finck CoTaskMemFree(MediumList);
2077*c2c66affSColin Finck CoTaskMemFree(InterfaceList);
2078*c2c66affSColin Finck return hr;
2079*c2c66affSColin Finck }
2080*c2c66affSColin Finck
2081*c2c66affSColin Finck // store interface handler
2082*c2c66affSColin Finck m_InterfaceHandler = InterfaceHandler;
2083*c2c66affSColin Finck }
2084*c2c66affSColin Finck }
2085*c2c66affSColin Finck else
2086*c2c66affSColin Finck {
2087*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2088*c2c66affSColin Finck WCHAR Buffer[100];
2089*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::CreatePin unexpected communication %u %s\n", m_Communication, m_PinName);
2090*c2c66affSColin Finck OutputDebugStringW(Buffer);
2091*c2c66affSColin Finck #endif
2092*c2c66affSColin Finck
2093*c2c66affSColin Finck hr = E_FAIL;
2094*c2c66affSColin Finck }
2095*c2c66affSColin Finck
2096*c2c66affSColin Finck // free medium / interface / dataformat
2097*c2c66affSColin Finck CoTaskMemFree(MediumList);
2098*c2c66affSColin Finck CoTaskMemFree(InterfaceList);
2099*c2c66affSColin Finck
2100*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2101*c2c66affSColin Finck WCHAR Buffer[100];
2102*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::CreatePin Result %lx\n", hr);
2103*c2c66affSColin Finck OutputDebugStringW(Buffer);
2104*c2c66affSColin Finck #endif
2105*c2c66affSColin Finck
2106*c2c66affSColin Finck return hr;
2107*c2c66affSColin Finck }
2108*c2c66affSColin Finck
2109*c2c66affSColin Finck HRESULT
2110*c2c66affSColin Finck STDMETHODCALLTYPE
CreatePinHandle(PKSPIN_MEDIUM Medium,PKSPIN_INTERFACE Interface,const AM_MEDIA_TYPE * pmt)2111*c2c66affSColin Finck COutputPin::CreatePinHandle(
2112*c2c66affSColin Finck PKSPIN_MEDIUM Medium,
2113*c2c66affSColin Finck PKSPIN_INTERFACE Interface,
2114*c2c66affSColin Finck const AM_MEDIA_TYPE *pmt)
2115*c2c66affSColin Finck {
2116*c2c66affSColin Finck PKSPIN_CONNECT PinConnect;
2117*c2c66affSColin Finck PKSDATAFORMAT DataFormat;
2118*c2c66affSColin Finck ULONG Length;
2119*c2c66affSColin Finck HRESULT hr;
2120*c2c66affSColin Finck HANDLE hFilter;
2121*c2c66affSColin Finck IKsObject * KsObjectParent;
2122*c2c66affSColin Finck
2123*c2c66affSColin Finck //KSALLOCATOR_FRAMING Framing;
2124*c2c66affSColin Finck //KSPROPERTY Property;
2125*c2c66affSColin Finck //ULONG BytesReturned;
2126*c2c66affSColin Finck
2127*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle\n");
2128*c2c66affSColin Finck
2129*c2c66affSColin Finck if (m_hPin != INVALID_HANDLE_VALUE)
2130*c2c66affSColin Finck {
2131*c2c66affSColin Finck // pin already exists
2132*c2c66affSColin Finck //CloseHandle(m_hPin);
2133*c2c66affSColin Finck //m_hPin = INVALID_HANDLE_VALUE;
2134*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle pin already exists\n");
2135*c2c66affSColin Finck return S_OK;
2136*c2c66affSColin Finck }
2137*c2c66affSColin Finck
2138*c2c66affSColin Finck
2139*c2c66affSColin Finck // calc format size
2140*c2c66affSColin Finck Length = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT) + pmt->cbFormat;
2141*c2c66affSColin Finck
2142*c2c66affSColin Finck // allocate pin connect
2143*c2c66affSColin Finck PinConnect = (PKSPIN_CONNECT)CoTaskMemAlloc(Length);
2144*c2c66affSColin Finck if (!PinConnect)
2145*c2c66affSColin Finck {
2146*c2c66affSColin Finck // failed
2147*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle out of memory\n");
2148*c2c66affSColin Finck return E_OUTOFMEMORY;
2149*c2c66affSColin Finck }
2150*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle copy pinconnect\n");
2151*c2c66affSColin Finck // setup request
2152*c2c66affSColin Finck CopyMemory(&PinConnect->Interface, Interface, sizeof(KSPIN_INTERFACE));
2153*c2c66affSColin Finck CopyMemory(&PinConnect->Medium, Medium, sizeof(KSPIN_MEDIUM));
2154*c2c66affSColin Finck PinConnect->PinId = m_PinId;
2155*c2c66affSColin Finck PinConnect->PinToHandle = NULL;
2156*c2c66affSColin Finck PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
2157*c2c66affSColin Finck PinConnect->Priority.PrioritySubClass = KSPRIORITY_NORMAL;
2158*c2c66affSColin Finck
2159*c2c66affSColin Finck // get dataformat offset
2160*c2c66affSColin Finck DataFormat = (PKSDATAFORMAT)(PinConnect + 1);
2161*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle copy format\n");
2162*c2c66affSColin Finck // copy data format
2163*c2c66affSColin Finck DataFormat->FormatSize = sizeof(KSDATAFORMAT) + pmt->cbFormat;
2164*c2c66affSColin Finck DataFormat->Flags = 0;
2165*c2c66affSColin Finck DataFormat->SampleSize = pmt->lSampleSize;
2166*c2c66affSColin Finck DataFormat->Reserved = 0;
2167*c2c66affSColin Finck CopyMemory(&DataFormat->MajorFormat, &pmt->majortype, sizeof(GUID));
2168*c2c66affSColin Finck CopyMemory(&DataFormat->SubFormat, &pmt->subtype, sizeof(GUID));
2169*c2c66affSColin Finck CopyMemory(&DataFormat->Specifier, &pmt->formattype, sizeof(GUID));
2170*c2c66affSColin Finck
2171*c2c66affSColin Finck if (pmt->cbFormat)
2172*c2c66affSColin Finck {
2173*c2c66affSColin Finck // copy extended format
2174*c2c66affSColin Finck WCHAR Buffer[100];
2175*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::CreatePinHandle copy format %p pbFormat %lu\n", pmt, pmt->cbFormat);
2176*c2c66affSColin Finck OutputDebugStringW(Buffer);
2177*c2c66affSColin Finck CopyMemory((DataFormat + 1), pmt->pbFormat, pmt->cbFormat);
2178*c2c66affSColin Finck }
2179*c2c66affSColin Finck
2180*c2c66affSColin Finck // get IKsObject interface
2181*c2c66affSColin Finck hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&KsObjectParent);
2182*c2c66affSColin Finck if (FAILED(hr))
2183*c2c66affSColin Finck {
2184*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle no IID_IKsObject interface\n");
2185*c2c66affSColin Finck return hr;
2186*c2c66affSColin Finck }
2187*c2c66affSColin Finck
2188*c2c66affSColin Finck // get parent filter handle
2189*c2c66affSColin Finck hFilter = KsObjectParent->KsGetObjectHandle();
2190*c2c66affSColin Finck
2191*c2c66affSColin Finck // release IKsObject
2192*c2c66affSColin Finck KsObjectParent->Release();
2193*c2c66affSColin Finck
2194*c2c66affSColin Finck if (!hFilter)
2195*c2c66affSColin Finck {
2196*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle no filter handle\n");
2197*c2c66affSColin Finck return E_HANDLE;
2198*c2c66affSColin Finck }
2199*c2c66affSColin Finck
2200*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle before creating pin\n");
2201*c2c66affSColin Finck // create pin
2202*c2c66affSColin Finck DWORD dwError = KsCreatePin(hFilter, PinConnect, GENERIC_READ, &m_hPin);
2203*c2c66affSColin Finck
2204*c2c66affSColin Finck if (dwError == ERROR_SUCCESS)
2205*c2c66affSColin Finck {
2206*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle created pin\n");
2207*c2c66affSColin Finck
2208*c2c66affSColin Finck // store current interface / medium
2209*c2c66affSColin Finck CopyMemory(&m_Medium, Medium, sizeof(KSPIN_MEDIUM));
2210*c2c66affSColin Finck CopyMemory(&m_Interface, Interface, sizeof(KSPIN_INTERFACE));
2211*c2c66affSColin Finck CopyMemory(&m_MediaFormat, pmt, sizeof(AM_MEDIA_TYPE));
2212*c2c66affSColin Finck
2213*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2214*c2c66affSColin Finck LPOLESTR pMajor, pSub, pFormat;
2215*c2c66affSColin Finck StringFromIID(m_MediaFormat.majortype, &pMajor);
2216*c2c66affSColin Finck StringFromIID(m_MediaFormat.subtype , &pSub);
2217*c2c66affSColin Finck StringFromIID(m_MediaFormat.formattype, &pFormat);
2218*c2c66affSColin Finck WCHAR Buffer[200];
2219*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::CreatePinHandle Major %s SubType %s Format %s pbFormat %p cbFormat %u\n", pMajor, pSub, pFormat, pmt->pbFormat, pmt->cbFormat);
2220*c2c66affSColin Finck CoTaskMemFree(pMajor);
2221*c2c66affSColin Finck CoTaskMemFree(pSub);
2222*c2c66affSColin Finck CoTaskMemFree(pFormat);
2223*c2c66affSColin Finck OutputDebugStringW(Buffer);
2224*c2c66affSColin Finck #endif
2225*c2c66affSColin Finck
2226*c2c66affSColin Finck if (pmt->cbFormat)
2227*c2c66affSColin Finck {
2228*c2c66affSColin Finck m_MediaFormat.pbFormat = (BYTE*)CoTaskMemAlloc(pmt->cbFormat);
2229*c2c66affSColin Finck if (!m_MediaFormat.pbFormat)
2230*c2c66affSColin Finck {
2231*c2c66affSColin Finck CoTaskMemFree(PinConnect);
2232*c2c66affSColin Finck m_MediaFormat.pbFormat = NULL;
2233*c2c66affSColin Finck m_MediaFormat.cbFormat = 0;
2234*c2c66affSColin Finck return E_OUTOFMEMORY;
2235*c2c66affSColin Finck }
2236*c2c66affSColin Finck CopyMemory(m_MediaFormat.pbFormat, pmt->pbFormat, pmt->cbFormat);
2237*c2c66affSColin Finck }
2238*c2c66affSColin Finck #if 0
2239*c2c66affSColin Finck Property.Set = KSPROPSETID_Connection;
2240*c2c66affSColin Finck Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING;
2241*c2c66affSColin Finck Property.Flags = KSPROPERTY_TYPE_GET;
2242*c2c66affSColin Finck
2243*c2c66affSColin Finck ZeroMemory(&Framing, sizeof(KSALLOCATOR_FRAMING));
2244*c2c66affSColin Finck hr = KsProperty(&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned);
2245*c2c66affSColin Finck if (SUCCEEDED(hr))
2246*c2c66affSColin Finck {
2247*c2c66affSColin Finck m_Properties.cbAlign = (Framing.FileAlignment + 1);
2248*c2c66affSColin Finck m_Properties.cbBuffer = Framing.FrameSize;
2249*c2c66affSColin Finck m_Properties.cbPrefix = 0; //FIXME
2250*c2c66affSColin Finck m_Properties.cBuffers = Framing.Frames;
2251*c2c66affSColin Finck }
2252*c2c66affSColin Finck hr = S_OK;
2253*c2c66affSColin Finck #endif
2254*c2c66affSColin Finck
2255*c2c66affSColin Finck if (FAILED(InitializeIOThread()))
2256*c2c66affSColin Finck {
2257*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle failed to initialize i/o thread\n");
2258*c2c66affSColin Finck }
2259*c2c66affSColin Finck
2260*c2c66affSColin Finck //TODO
2261*c2c66affSColin Finck // connect pin pipes
2262*c2c66affSColin Finck
2263*c2c66affSColin Finck }
2264*c2c66affSColin Finck else
2265*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::CreatePinHandle failed to create pin\n");
2266*c2c66affSColin Finck // free pin connect
2267*c2c66affSColin Finck CoTaskMemFree(PinConnect);
2268*c2c66affSColin Finck
2269*c2c66affSColin Finck return hr;
2270*c2c66affSColin Finck }
2271*c2c66affSColin Finck
2272*c2c66affSColin Finck HRESULT
2273*c2c66affSColin Finck STDMETHODCALLTYPE
GetSupportedSets(LPGUID * pOutGuid,PULONG NumGuids)2274*c2c66affSColin Finck COutputPin::GetSupportedSets(
2275*c2c66affSColin Finck LPGUID * pOutGuid,
2276*c2c66affSColin Finck PULONG NumGuids)
2277*c2c66affSColin Finck {
2278*c2c66affSColin Finck KSPROPERTY Property;
2279*c2c66affSColin Finck LPGUID pGuid;
2280*c2c66affSColin Finck ULONG NumProperty = 0;
2281*c2c66affSColin Finck ULONG NumMethods = 0;
2282*c2c66affSColin Finck ULONG NumEvents = 0;
2283*c2c66affSColin Finck ULONG Length;
2284*c2c66affSColin Finck ULONG BytesReturned;
2285*c2c66affSColin Finck HRESULT hr;
2286*c2c66affSColin Finck
2287*c2c66affSColin Finck Property.Set = GUID_NULL;
2288*c2c66affSColin Finck Property.Id = 0;
2289*c2c66affSColin Finck Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
2290*c2c66affSColin Finck
2291*c2c66affSColin Finck KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumProperty);
2292*c2c66affSColin Finck KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumMethods);
2293*c2c66affSColin Finck KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &NumEvents);
2294*c2c66affSColin Finck
2295*c2c66affSColin Finck Length = NumProperty + NumMethods + NumEvents;
2296*c2c66affSColin Finck
2297*c2c66affSColin Finck assert(Length);
2298*c2c66affSColin Finck
2299*c2c66affSColin Finck // allocate guid buffer
2300*c2c66affSColin Finck pGuid = (LPGUID)CoTaskMemAlloc(Length);
2301*c2c66affSColin Finck if (!pGuid)
2302*c2c66affSColin Finck {
2303*c2c66affSColin Finck // failed
2304*c2c66affSColin Finck return E_OUTOFMEMORY;
2305*c2c66affSColin Finck }
2306*c2c66affSColin Finck
2307*c2c66affSColin Finck NumProperty /= sizeof(GUID);
2308*c2c66affSColin Finck NumMethods /= sizeof(GUID);
2309*c2c66affSColin Finck NumEvents /= sizeof(GUID);
2310*c2c66affSColin Finck
2311*c2c66affSColin Finck // get all properties
2312*c2c66affSColin Finck hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)pGuid, Length, &BytesReturned);
2313*c2c66affSColin Finck if (FAILED(hr))
2314*c2c66affSColin Finck {
2315*c2c66affSColin Finck CoTaskMemFree(pGuid);
2316*c2c66affSColin Finck return E_FAIL;
2317*c2c66affSColin Finck }
2318*c2c66affSColin Finck Length -= BytesReturned;
2319*c2c66affSColin Finck
2320*c2c66affSColin Finck // get all methods
2321*c2c66affSColin Finck if (Length && NumMethods)
2322*c2c66affSColin Finck {
2323*c2c66affSColin Finck hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty], Length, &BytesReturned);
2324*c2c66affSColin Finck if (FAILED(hr))
2325*c2c66affSColin Finck {
2326*c2c66affSColin Finck CoTaskMemFree(pGuid);
2327*c2c66affSColin Finck return E_FAIL;
2328*c2c66affSColin Finck }
2329*c2c66affSColin Finck Length -= BytesReturned;
2330*c2c66affSColin Finck }
2331*c2c66affSColin Finck
2332*c2c66affSColin Finck // get all events
2333*c2c66affSColin Finck if (Length && NumEvents)
2334*c2c66affSColin Finck {
2335*c2c66affSColin Finck hr = KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&pGuid[NumProperty+NumMethods], Length, &BytesReturned);
2336*c2c66affSColin Finck if (FAILED(hr))
2337*c2c66affSColin Finck {
2338*c2c66affSColin Finck CoTaskMemFree(pGuid);
2339*c2c66affSColin Finck return E_FAIL;
2340*c2c66affSColin Finck }
2341*c2c66affSColin Finck Length -= BytesReturned;
2342*c2c66affSColin Finck }
2343*c2c66affSColin Finck
2344*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2345*c2c66affSColin Finck WCHAR Buffer[200];
2346*c2c66affSColin Finck swprintf(Buffer, L"NumProperty %lu NumMethods %lu NumEvents %lu\n", NumProperty, NumMethods, NumEvents);
2347*c2c66affSColin Finck OutputDebugStringW(Buffer);
2348*c2c66affSColin Finck #endif
2349*c2c66affSColin Finck
2350*c2c66affSColin Finck *pOutGuid = pGuid;
2351*c2c66affSColin Finck *NumGuids = NumProperty+NumEvents+NumMethods;
2352*c2c66affSColin Finck return S_OK;
2353*c2c66affSColin Finck }
2354*c2c66affSColin Finck
2355*c2c66affSColin Finck HRESULT
2356*c2c66affSColin Finck STDMETHODCALLTYPE
LoadProxyPlugins(LPGUID pGuids,ULONG NumGuids)2357*c2c66affSColin Finck COutputPin::LoadProxyPlugins(
2358*c2c66affSColin Finck LPGUID pGuids,
2359*c2c66affSColin Finck ULONG NumGuids)
2360*c2c66affSColin Finck {
2361*c2c66affSColin Finck ULONG Index;
2362*c2c66affSColin Finck LPOLESTR pStr;
2363*c2c66affSColin Finck HKEY hKey, hSubKey;
2364*c2c66affSColin Finck HRESULT hr;
2365*c2c66affSColin Finck IUnknown * pUnknown;
2366*c2c66affSColin Finck
2367*c2c66affSColin Finck if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\MediaInterfaces", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
2368*c2c66affSColin Finck {
2369*c2c66affSColin Finck OutputDebugStringW(L"CKsProxy::LoadProxyPlugins failed to open MediaInterfaces key\n");
2370*c2c66affSColin Finck return E_FAIL;
2371*c2c66affSColin Finck }
2372*c2c66affSColin Finck
2373*c2c66affSColin Finck // enumerate all sets
2374*c2c66affSColin Finck for(Index = 0; Index < NumGuids; Index++)
2375*c2c66affSColin Finck {
2376*c2c66affSColin Finck // convert to string
2377*c2c66affSColin Finck hr = StringFromCLSID(pGuids[Index], &pStr);
2378*c2c66affSColin Finck if (FAILED(hr))
2379*c2c66affSColin Finck return E_FAIL;
2380*c2c66affSColin Finck
2381*c2c66affSColin Finck // now try open class key
2382*c2c66affSColin Finck if (RegOpenKeyExW(hKey, pStr, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
2383*c2c66affSColin Finck {
2384*c2c66affSColin Finck // no plugin for that set exists
2385*c2c66affSColin Finck CoTaskMemFree(pStr);
2386*c2c66affSColin Finck continue;
2387*c2c66affSColin Finck }
2388*c2c66affSColin Finck
2389*c2c66affSColin Finck // try load plugin
2390*c2c66affSColin Finck hr = CoCreateInstance(pGuids[Index], (IBaseFilter*)this, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&pUnknown);
2391*c2c66affSColin Finck if (SUCCEEDED(hr))
2392*c2c66affSColin Finck {
2393*c2c66affSColin Finck // store plugin
2394*c2c66affSColin Finck m_Plugins.push_back(pUnknown);
2395*c2c66affSColin Finck }
2396*c2c66affSColin Finck // close key
2397*c2c66affSColin Finck RegCloseKey(hSubKey);
2398*c2c66affSColin Finck }
2399*c2c66affSColin Finck
2400*c2c66affSColin Finck // close media interfaces key
2401*c2c66affSColin Finck RegCloseKey(hKey);
2402*c2c66affSColin Finck return S_OK;
2403*c2c66affSColin Finck }
2404*c2c66affSColin Finck
2405*c2c66affSColin Finck
2406*c2c66affSColin Finck HRESULT
2407*c2c66affSColin Finck WINAPI
IoProcessRoutine()2408*c2c66affSColin Finck COutputPin::IoProcessRoutine()
2409*c2c66affSColin Finck {
2410*c2c66affSColin Finck IMediaSample *Sample;
2411*c2c66affSColin Finck LONG SampleCount;
2412*c2c66affSColin Finck HRESULT hr;
2413*c2c66affSColin Finck PKSSTREAM_SEGMENT * StreamSegment;
2414*c2c66affSColin Finck HANDLE hEvent;
2415*c2c66affSColin Finck IMediaSample ** Samples;
2416*c2c66affSColin Finck LONG NumHandles;
2417*c2c66affSColin Finck DWORD dwStatus;
2418*c2c66affSColin Finck
2419*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2420*c2c66affSColin Finck WCHAR Buffer[200];
2421*c2c66affSColin Finck #endif
2422*c2c66affSColin Finck
2423*c2c66affSColin Finck NumHandles = m_Properties.cBuffers / 2;
2424*c2c66affSColin Finck
2425*c2c66affSColin Finck if (!NumHandles)
2426*c2c66affSColin Finck NumHandles = 8;
2427*c2c66affSColin Finck
2428*c2c66affSColin Finck assert(NumHandles);
2429*c2c66affSColin Finck
2430*c2c66affSColin Finck //allocate stream segment array
2431*c2c66affSColin Finck StreamSegment = (PKSSTREAM_SEGMENT*)CoTaskMemAlloc(sizeof(PVOID) * NumHandles);
2432*c2c66affSColin Finck if (!StreamSegment)
2433*c2c66affSColin Finck {
2434*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::IoProcessRoutine out of memory\n");
2435*c2c66affSColin Finck return E_FAIL;
2436*c2c66affSColin Finck }
2437*c2c66affSColin Finck
2438*c2c66affSColin Finck // allocate handle array
2439*c2c66affSColin Finck Samples = (IMediaSample**)CoTaskMemAlloc(sizeof(IMediaSample*) * NumHandles);
2440*c2c66affSColin Finck if (!Samples)
2441*c2c66affSColin Finck {
2442*c2c66affSColin Finck OutputDebugStringW(L"COutputPin::IoProcessRoutine out of memory\n");
2443*c2c66affSColin Finck return E_FAIL;
2444*c2c66affSColin Finck }
2445*c2c66affSColin Finck
2446*c2c66affSColin Finck // zero handles array
2447*c2c66affSColin Finck ZeroMemory(StreamSegment, sizeof(PVOID) * NumHandles);
2448*c2c66affSColin Finck ZeroMemory(Samples, sizeof(IMediaSample*) * NumHandles);
2449*c2c66affSColin Finck
2450*c2c66affSColin Finck // first wait for the start event to signal
2451*c2c66affSColin Finck WaitForSingleObject(m_hStartEvent, INFINITE);
2452*c2c66affSColin Finck
2453*c2c66affSColin Finck m_IoCount = 0;
2454*c2c66affSColin Finck
2455*c2c66affSColin Finck assert(m_InterfaceHandler);
2456*c2c66affSColin Finck do
2457*c2c66affSColin Finck {
2458*c2c66affSColin Finck if (m_StopInProgress)
2459*c2c66affSColin Finck {
2460*c2c66affSColin Finck // stop io thread
2461*c2c66affSColin Finck break;
2462*c2c66affSColin Finck }
2463*c2c66affSColin Finck
2464*c2c66affSColin Finck assert(m_State == KSSTATE_RUN);
2465*c2c66affSColin Finck assert(m_MemAllocator);
2466*c2c66affSColin Finck
2467*c2c66affSColin Finck // get buffer
2468*c2c66affSColin Finck hr = m_MemAllocator->GetBuffer(&Sample, NULL, NULL, AM_GBF_NOWAIT);
2469*c2c66affSColin Finck
2470*c2c66affSColin Finck if (FAILED(hr))
2471*c2c66affSColin Finck {
2472*c2c66affSColin Finck WaitForSingleObject(m_hBufferAvailable, INFINITE);
2473*c2c66affSColin Finck // now retry again
2474*c2c66affSColin Finck continue;
2475*c2c66affSColin Finck }
2476*c2c66affSColin Finck
2477*c2c66affSColin Finck // fill buffer
2478*c2c66affSColin Finck SampleCount = 1;
2479*c2c66affSColin Finck Samples[m_IoCount] = Sample;
2480*c2c66affSColin Finck
2481*c2c66affSColin Finck Sample->SetTime(NULL, NULL);
2482*c2c66affSColin Finck hr = m_InterfaceHandler->KsProcessMediaSamples(NULL, /* FIXME */
2483*c2c66affSColin Finck &Samples[m_IoCount],
2484*c2c66affSColin Finck &SampleCount,
2485*c2c66affSColin Finck KsIoOperation_Read,
2486*c2c66affSColin Finck &StreamSegment[m_IoCount]);
2487*c2c66affSColin Finck if (FAILED(hr) || !StreamSegment)
2488*c2c66affSColin Finck {
2489*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2490*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::IoProcessRoutine KsProcessMediaSamples FAILED PinName %s hr %lx\n", m_PinName, hr);
2491*c2c66affSColin Finck OutputDebugStringW(Buffer);
2492*c2c66affSColin Finck #endif
2493*c2c66affSColin Finck break;
2494*c2c66affSColin Finck }
2495*c2c66affSColin Finck
2496*c2c66affSColin Finck // interface handle should increment pending i/o count
2497*c2c66affSColin Finck assert(m_IoCount >= 1);
2498*c2c66affSColin Finck
2499*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::IoProcessRoutine m_IoCount %lu NumHandles %lu\n", m_IoCount, NumHandles);
2500*c2c66affSColin Finck OutputDebugStringW(Buffer);
2501*c2c66affSColin Finck
2502*c2c66affSColin Finck if (m_IoCount != NumHandles)
2503*c2c66affSColin Finck continue;
2504*c2c66affSColin Finck
2505*c2c66affSColin Finck // get completion handle
2506*c2c66affSColin Finck hEvent = StreamSegment[0]->CompletionEvent;
2507*c2c66affSColin Finck
2508*c2c66affSColin Finck // wait for i/o completion
2509*c2c66affSColin Finck dwStatus = WaitForSingleObject(hEvent, INFINITE);
2510*c2c66affSColin Finck
2511*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::IoProcessRoutine dwStatus %lx Error %lx NumHandles %lu\n", dwStatus, GetLastError(), NumHandles);
2512*c2c66affSColin Finck OutputDebugStringW(Buffer);
2513*c2c66affSColin Finck
2514*c2c66affSColin Finck // perform completion
2515*c2c66affSColin Finck m_InterfaceHandler->KsCompleteIo(StreamSegment[0]);
2516*c2c66affSColin Finck
2517*c2c66affSColin Finck // close completion event
2518*c2c66affSColin Finck CloseHandle(hEvent);
2519*c2c66affSColin Finck
2520*c2c66affSColin Finck if (SUCCEEDED(hr))
2521*c2c66affSColin Finck {
2522*c2c66affSColin Finck assert(m_MemInputPin);
2523*c2c66affSColin Finck
2524*c2c66affSColin Finck // now deliver the sample
2525*c2c66affSColin Finck hr = m_MemInputPin->Receive(Samples[0]);
2526*c2c66affSColin Finck
2527*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2528*c2c66affSColin Finck swprintf(Buffer, L"COutputPin::IoProcessRoutine PinName %s IMemInputPin::Receive hr %lx Sample %p m_MemAllocator %p\n", m_PinName, hr, Sample, m_MemAllocator);
2529*c2c66affSColin Finck OutputDebugStringW(Buffer);
2530*c2c66affSColin Finck #endif
2531*c2c66affSColin Finck
2532*c2c66affSColin Finck if (FAILED(hr))
2533*c2c66affSColin Finck break;
2534*c2c66affSColin Finck
2535*c2c66affSColin Finck Sample = NULL;
2536*c2c66affSColin Finck }
2537*c2c66affSColin Finck
2538*c2c66affSColin Finck //circular stream segment array
2539*c2c66affSColin Finck RtlMoveMemory(StreamSegment, &StreamSegment[1], sizeof(PVOID) * (NumHandles - 1));
2540*c2c66affSColin Finck RtlMoveMemory(Samples, &Samples[1], sizeof(IMediaSample*) * (NumHandles - 1));
2541*c2c66affSColin Finck
2542*c2c66affSColin Finck }while(TRUE);
2543*c2c66affSColin Finck
2544*c2c66affSColin Finck // signal end of i/o thread
2545*c2c66affSColin Finck SetEvent(m_hStopEvent);
2546*c2c66affSColin Finck
2547*c2c66affSColin Finck m_IoThreadStarted = false;
2548*c2c66affSColin Finck
2549*c2c66affSColin Finck return NOERROR;
2550*c2c66affSColin Finck }
2551*c2c66affSColin Finck
2552*c2c66affSColin Finck DWORD
2553*c2c66affSColin Finck WINAPI
COutputPin_IoThreadStartup(LPVOID lpParameter)2554*c2c66affSColin Finck COutputPin_IoThreadStartup(
2555*c2c66affSColin Finck LPVOID lpParameter)
2556*c2c66affSColin Finck {
2557*c2c66affSColin Finck COutputPin * Pin = (COutputPin*)lpParameter;
2558*c2c66affSColin Finck assert(Pin);
2559*c2c66affSColin Finck
2560*c2c66affSColin Finck return Pin->IoProcessRoutine();
2561*c2c66affSColin Finck }
2562*c2c66affSColin Finck
2563*c2c66affSColin Finck
2564*c2c66affSColin Finck HRESULT
2565*c2c66affSColin Finck WINAPI
InitializeIOThread()2566*c2c66affSColin Finck COutputPin::InitializeIOThread()
2567*c2c66affSColin Finck {
2568*c2c66affSColin Finck HANDLE hThread;
2569*c2c66affSColin Finck
2570*c2c66affSColin Finck if (m_IoThreadStarted)
2571*c2c66affSColin Finck return NOERROR;
2572*c2c66affSColin Finck
2573*c2c66affSColin Finck if (!m_hStartEvent)
2574*c2c66affSColin Finck m_hStartEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
2575*c2c66affSColin Finck
2576*c2c66affSColin Finck if (!m_hStartEvent)
2577*c2c66affSColin Finck return E_OUTOFMEMORY;
2578*c2c66affSColin Finck
2579*c2c66affSColin Finck if (!m_hStopEvent)
2580*c2c66affSColin Finck m_hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
2581*c2c66affSColin Finck
2582*c2c66affSColin Finck if (!m_hStopEvent)
2583*c2c66affSColin Finck return E_OUTOFMEMORY;
2584*c2c66affSColin Finck
2585*c2c66affSColin Finck if (!m_hBufferAvailable)
2586*c2c66affSColin Finck m_hBufferAvailable = CreateEventW(NULL, FALSE, FALSE, NULL);
2587*c2c66affSColin Finck
2588*c2c66affSColin Finck if (!m_hBufferAvailable)
2589*c2c66affSColin Finck return E_OUTOFMEMORY;
2590*c2c66affSColin Finck
2591*c2c66affSColin Finck m_StopInProgress = false;
2592*c2c66affSColin Finck m_IoThreadStarted = true;
2593*c2c66affSColin Finck
2594*c2c66affSColin Finck // now create the startup thread
2595*c2c66affSColin Finck hThread = CreateThread(NULL, 0, COutputPin_IoThreadStartup, (LPVOID)this, 0, NULL);
2596*c2c66affSColin Finck if (!hThread)
2597*c2c66affSColin Finck return E_OUTOFMEMORY;
2598*c2c66affSColin Finck
2599*c2c66affSColin Finck
2600*c2c66affSColin Finck // close thread handle
2601*c2c66affSColin Finck CloseHandle(hThread);
2602*c2c66affSColin Finck return NOERROR;
2603*c2c66affSColin Finck }
2604*c2c66affSColin Finck
2605*c2c66affSColin Finck HRESULT
2606*c2c66affSColin Finck STDMETHODCALLTYPE
COutputPin_SetState(IPin * Pin,KSSTATE State)2607*c2c66affSColin Finck COutputPin_SetState(
2608*c2c66affSColin Finck IPin * Pin,
2609*c2c66affSColin Finck KSSTATE State)
2610*c2c66affSColin Finck {
2611*c2c66affSColin Finck HRESULT hr = S_OK;
2612*c2c66affSColin Finck KSPROPERTY Property;
2613*c2c66affSColin Finck KSSTATE CurState;
2614*c2c66affSColin Finck ULONG BytesReturned;
2615*c2c66affSColin Finck COutputPin * pPin = (COutputPin*)Pin;
2616*c2c66affSColin Finck
2617*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2618*c2c66affSColin Finck WCHAR Buffer[200];
2619*c2c66affSColin Finck #endif
2620*c2c66affSColin Finck
2621*c2c66affSColin Finck Property.Set = KSPROPSETID_Connection;
2622*c2c66affSColin Finck Property.Id = KSPROPERTY_CONNECTION_STATE;
2623*c2c66affSColin Finck Property.Flags = KSPROPERTY_TYPE_SET;
2624*c2c66affSColin Finck
2625*c2c66affSColin Finck EnterCriticalSection(&pPin->m_Lock);
2626*c2c66affSColin Finck
2627*c2c66affSColin Finck if (pPin->m_State <= State)
2628*c2c66affSColin Finck {
2629*c2c66affSColin Finck if (pPin->m_State == KSSTATE_STOP)
2630*c2c66affSColin Finck {
2631*c2c66affSColin Finck hr = pPin->InitializeIOThread();
2632*c2c66affSColin Finck if (FAILED(hr))
2633*c2c66affSColin Finck {
2634*c2c66affSColin Finck // failed to initialize I/O thread
2635*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2636*c2c66affSColin Finck OutputDebugStringW(L"Failed to initialize I/O Thread\n");
2637*c2c66affSColin Finck #endif
2638*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2639*c2c66affSColin Finck return hr;
2640*c2c66affSColin Finck }
2641*c2c66affSColin Finck CurState = KSSTATE_ACQUIRE;
2642*c2c66affSColin Finck hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
2643*c2c66affSColin Finck
2644*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2645*c2c66affSColin Finck swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_STOP KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin->m_PinName, hr);
2646*c2c66affSColin Finck OutputDebugStringW(Buffer);
2647*c2c66affSColin Finck #endif
2648*c2c66affSColin Finck
2649*c2c66affSColin Finck if (FAILED(hr))
2650*c2c66affSColin Finck {
2651*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2652*c2c66affSColin Finck return hr;
2653*c2c66affSColin Finck }
2654*c2c66affSColin Finck
2655*c2c66affSColin Finck pPin->m_State = CurState;
2656*c2c66affSColin Finck
2657*c2c66affSColin Finck if (pPin->m_State == State)
2658*c2c66affSColin Finck {
2659*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2660*c2c66affSColin Finck return hr;
2661*c2c66affSColin Finck }
2662*c2c66affSColin Finck }
2663*c2c66affSColin Finck if (pPin->m_State == KSSTATE_ACQUIRE)
2664*c2c66affSColin Finck {
2665*c2c66affSColin Finck CurState = KSSTATE_PAUSE;
2666*c2c66affSColin Finck hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
2667*c2c66affSColin Finck
2668*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2669*c2c66affSColin Finck swprintf(Buffer, L"COutputPin_SetState Setting State CurState KSSTATE_ACQUIRE KSSTATE_PAUSE PinName %s hr %lx\n", pPin->m_PinName, hr);
2670*c2c66affSColin Finck OutputDebugStringW(Buffer);
2671*c2c66affSColin Finck #endif
2672*c2c66affSColin Finck
2673*c2c66affSColin Finck if (FAILED(hr))
2674*c2c66affSColin Finck {
2675*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2676*c2c66affSColin Finck return hr;
2677*c2c66affSColin Finck }
2678*c2c66affSColin Finck
2679*c2c66affSColin Finck pPin->m_State = CurState;
2680*c2c66affSColin Finck
2681*c2c66affSColin Finck if (pPin->m_State == State)
2682*c2c66affSColin Finck {
2683*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2684*c2c66affSColin Finck return hr;
2685*c2c66affSColin Finck }
2686*c2c66affSColin Finck }
2687*c2c66affSColin Finck if (State == KSSTATE_RUN && pPin->m_State == KSSTATE_PAUSE)
2688*c2c66affSColin Finck {
2689*c2c66affSColin Finck CurState = KSSTATE_RUN;
2690*c2c66affSColin Finck hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
2691*c2c66affSColin Finck
2692*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2693*c2c66affSColin Finck swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_RUN PinName %s hr %lx\n", pPin->m_PinName, hr);
2694*c2c66affSColin Finck OutputDebugStringW(Buffer);
2695*c2c66affSColin Finck #endif
2696*c2c66affSColin Finck
2697*c2c66affSColin Finck if (SUCCEEDED(hr))
2698*c2c66affSColin Finck {
2699*c2c66affSColin Finck pPin->m_State = CurState;
2700*c2c66affSColin Finck // signal start event
2701*c2c66affSColin Finck SetEvent(pPin->m_hStartEvent);
2702*c2c66affSColin Finck }
2703*c2c66affSColin Finck }
2704*c2c66affSColin Finck
2705*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2706*c2c66affSColin Finck return hr;
2707*c2c66affSColin Finck }
2708*c2c66affSColin Finck else
2709*c2c66affSColin Finck {
2710*c2c66affSColin Finck if (pPin->m_State == KSSTATE_RUN)
2711*c2c66affSColin Finck {
2712*c2c66affSColin Finck // setting pending stop flag
2713*c2c66affSColin Finck pPin->m_StopInProgress = true;
2714*c2c66affSColin Finck
2715*c2c66affSColin Finck // release any waiting threads
2716*c2c66affSColin Finck SetEvent(pPin->m_hBufferAvailable);
2717*c2c66affSColin Finck
2718*c2c66affSColin Finck // wait until i/o thread is done
2719*c2c66affSColin Finck WaitForSingleObject(pPin->m_hStopEvent, INFINITE);
2720*c2c66affSColin Finck
2721*c2c66affSColin Finck CurState = KSSTATE_PAUSE;
2722*c2c66affSColin Finck hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
2723*c2c66affSColin Finck
2724*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2725*c2c66affSColin Finck swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_RUN KSSTATE_PAUSE PinName %s hr %lx\n", pPin->m_PinName, hr);
2726*c2c66affSColin Finck OutputDebugStringW(Buffer);
2727*c2c66affSColin Finck #endif
2728*c2c66affSColin Finck
2729*c2c66affSColin Finck if (FAILED(hr))
2730*c2c66affSColin Finck {
2731*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2732*c2c66affSColin Finck return hr;
2733*c2c66affSColin Finck }
2734*c2c66affSColin Finck
2735*c2c66affSColin Finck pPin->m_State = CurState;
2736*c2c66affSColin Finck
2737*c2c66affSColin Finck if (FAILED(hr))
2738*c2c66affSColin Finck {
2739*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2740*c2c66affSColin Finck return hr;
2741*c2c66affSColin Finck }
2742*c2c66affSColin Finck }
2743*c2c66affSColin Finck if (pPin->m_State == KSSTATE_PAUSE)
2744*c2c66affSColin Finck {
2745*c2c66affSColin Finck CurState = KSSTATE_ACQUIRE;
2746*c2c66affSColin Finck hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
2747*c2c66affSColin Finck
2748*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2749*c2c66affSColin Finck swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_PAUSE KSSTATE_ACQUIRE PinName %s hr %lx\n", pPin->m_PinName, hr);
2750*c2c66affSColin Finck OutputDebugStringW(Buffer);
2751*c2c66affSColin Finck #endif
2752*c2c66affSColin Finck
2753*c2c66affSColin Finck if (FAILED(hr))
2754*c2c66affSColin Finck {
2755*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2756*c2c66affSColin Finck return hr;
2757*c2c66affSColin Finck }
2758*c2c66affSColin Finck
2759*c2c66affSColin Finck pPin->m_State = CurState;
2760*c2c66affSColin Finck
2761*c2c66affSColin Finck if (pPin->m_State == State)
2762*c2c66affSColin Finck {
2763*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2764*c2c66affSColin Finck return hr;
2765*c2c66affSColin Finck }
2766*c2c66affSColin Finck }
2767*c2c66affSColin Finck
2768*c2c66affSColin Finck CloseHandle(pPin->m_hStopEvent);
2769*c2c66affSColin Finck CloseHandle(pPin->m_hStartEvent);
2770*c2c66affSColin Finck CloseHandle(pPin->m_hBufferAvailable);
2771*c2c66affSColin Finck
2772*c2c66affSColin Finck /* close event handles */
2773*c2c66affSColin Finck pPin->m_hStopEvent = NULL;
2774*c2c66affSColin Finck pPin->m_hStartEvent = NULL;
2775*c2c66affSColin Finck pPin->m_hBufferAvailable = NULL;
2776*c2c66affSColin Finck
2777*c2c66affSColin Finck CurState = KSSTATE_STOP;
2778*c2c66affSColin Finck hr = pPin->KsProperty(&Property, sizeof(KSPROPERTY), &CurState, sizeof(KSSTATE), &BytesReturned);
2779*c2c66affSColin Finck
2780*c2c66affSColin Finck #ifdef KSPROXY_TRACE
2781*c2c66affSColin Finck swprintf(Buffer, L"COutputPin_SetState Setting State CurState: KSSTATE_ACQUIRE KSSTATE_STOP PinName %s hr %lx\n", pPin->m_PinName, hr);
2782*c2c66affSColin Finck OutputDebugStringW(Buffer);
2783*c2c66affSColin Finck #endif
2784*c2c66affSColin Finck
2785*c2c66affSColin Finck if (SUCCEEDED(hr))
2786*c2c66affSColin Finck {
2787*c2c66affSColin Finck // store state
2788*c2c66affSColin Finck pPin->m_State = CurState;
2789*c2c66affSColin Finck }
2790*c2c66affSColin Finck
2791*c2c66affSColin Finck // unset pending stop flag
2792*c2c66affSColin Finck pPin->m_StopInProgress = false;
2793*c2c66affSColin Finck
2794*c2c66affSColin Finck LeaveCriticalSection(&pPin->m_Lock);
2795*c2c66affSColin Finck return hr;
2796*c2c66affSColin Finck }
2797*c2c66affSColin Finck }
2798*c2c66affSColin Finck
2799*c2c66affSColin Finck HRESULT
2800*c2c66affSColin Finck WINAPI
COutputPin_Constructor(IBaseFilter * ParentFilter,LPCWSTR PinName,ULONG PinId,KSPIN_COMMUNICATION Communication,REFIID riid,LPVOID * ppv)2801*c2c66affSColin Finck COutputPin_Constructor(
2802*c2c66affSColin Finck IBaseFilter * ParentFilter,
2803*c2c66affSColin Finck LPCWSTR PinName,
2804*c2c66affSColin Finck ULONG PinId,
2805*c2c66affSColin Finck KSPIN_COMMUNICATION Communication,
2806*c2c66affSColin Finck REFIID riid,
2807*c2c66affSColin Finck LPVOID * ppv)
2808*c2c66affSColin Finck {
2809*c2c66affSColin Finck COutputPin * handler = new COutputPin(ParentFilter, PinName, PinId, Communication);
2810*c2c66affSColin Finck
2811*c2c66affSColin Finck if (!handler)
2812*c2c66affSColin Finck return E_OUTOFMEMORY;
2813*c2c66affSColin Finck
2814*c2c66affSColin Finck if (FAILED(handler->QueryInterface(riid, ppv)))
2815*c2c66affSColin Finck {
2816*c2c66affSColin Finck /* not supported */
2817*c2c66affSColin Finck delete handler;
2818*c2c66affSColin Finck return E_NOINTERFACE;
2819*c2c66affSColin Finck }
2820*c2c66affSColin Finck
2821*c2c66affSColin Finck return S_OK;
2822*c2c66affSColin Finck }
2823