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/interface.cpp
5*c2c66affSColin Finck * PURPOSE: IKsInterfaceHandler interface
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 const GUID IID_IKsObject = {0x423c13a2, 0x2070, 0x11d0, {0x9e, 0xf7, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
12*c2c66affSColin Finck
13*c2c66affSColin Finck class CKsInterfaceHandler : public IKsInterfaceHandler
14*c2c66affSColin Finck {
15*c2c66affSColin Finck public:
16*c2c66affSColin Finck STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
17*c2c66affSColin Finck
AddRef()18*c2c66affSColin Finck STDMETHODIMP_(ULONG) AddRef()
19*c2c66affSColin Finck {
20*c2c66affSColin Finck InterlockedIncrement(&m_Ref);
21*c2c66affSColin Finck return m_Ref;
22*c2c66affSColin Finck }
Release()23*c2c66affSColin Finck STDMETHODIMP_(ULONG) Release()
24*c2c66affSColin Finck {
25*c2c66affSColin Finck InterlockedDecrement(&m_Ref);
26*c2c66affSColin Finck
27*c2c66affSColin Finck if (!m_Ref)
28*c2c66affSColin Finck {
29*c2c66affSColin Finck delete this;
30*c2c66affSColin Finck return 0;
31*c2c66affSColin Finck }
32*c2c66affSColin Finck return m_Ref;
33*c2c66affSColin Finck }
34*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsSetPin(IKsPin *KsPin);
35*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsProcessMediaSamples(IKsDataTypeHandler *KsDataTypeHandler, IMediaSample** SampleList, PLONG SampleCount, KSIOOPERATION IoOperation, PKSSTREAM_SEGMENT *StreamSegment);
36*c2c66affSColin Finck HRESULT STDMETHODCALLTYPE KsCompleteIo(PKSSTREAM_SEGMENT StreamSegment);
37*c2c66affSColin Finck
CKsInterfaceHandler()38*c2c66affSColin Finck CKsInterfaceHandler() : m_Ref(0), m_Handle(NULL), m_Pin(0) {m_PinName[0] = L'\0';};
~CKsInterfaceHandler()39*c2c66affSColin Finck virtual ~CKsInterfaceHandler(){};
40*c2c66affSColin Finck
41*c2c66affSColin Finck protected:
42*c2c66affSColin Finck LONG m_Ref;
43*c2c66affSColin Finck HANDLE m_Handle;
44*c2c66affSColin Finck IKsPinEx * m_Pin;
45*c2c66affSColin Finck WCHAR m_PinName[129];
46*c2c66affSColin Finck };
47*c2c66affSColin Finck
48*c2c66affSColin Finck typedef struct
49*c2c66affSColin Finck {
50*c2c66affSColin Finck KSSTREAM_SEGMENT StreamSegment;
51*c2c66affSColin Finck OVERLAPPED Overlapped;
52*c2c66affSColin Finck IMediaSample * MediaSample[64];
53*c2c66affSColin Finck
54*c2c66affSColin Finck ULONG SampleCount;
55*c2c66affSColin Finck ULONG ExtendedSize;
56*c2c66affSColin Finck PKSSTREAM_HEADER StreamHeader;
57*c2c66affSColin Finck }KSSTREAM_SEGMENT_EXT, *PKSSTREAM_SEGMENT_EXT;
58*c2c66affSColin Finck
59*c2c66affSColin Finck
60*c2c66affSColin Finck HRESULT
61*c2c66affSColin Finck STDMETHODCALLTYPE
QueryInterface(IN REFIID refiid,OUT PVOID * Output)62*c2c66affSColin Finck CKsInterfaceHandler::QueryInterface(
63*c2c66affSColin Finck IN REFIID refiid,
64*c2c66affSColin Finck OUT PVOID* Output)
65*c2c66affSColin Finck {
66*c2c66affSColin Finck if (IsEqualGUID(refiid, IID_IUnknown) ||
67*c2c66affSColin Finck IsEqualGUID(refiid, IID_IKsInterfaceHandler))
68*c2c66affSColin Finck {
69*c2c66affSColin Finck *Output = PVOID(this);
70*c2c66affSColin Finck reinterpret_cast<IUnknown*>(*Output)->AddRef();
71*c2c66affSColin Finck return NOERROR;
72*c2c66affSColin Finck }
73*c2c66affSColin Finck return E_NOINTERFACE;
74*c2c66affSColin Finck }
75*c2c66affSColin Finck
76*c2c66affSColin Finck HRESULT
77*c2c66affSColin Finck STDMETHODCALLTYPE
KsSetPin(IKsPin * KsPin)78*c2c66affSColin Finck CKsInterfaceHandler::KsSetPin(
79*c2c66affSColin Finck IKsPin *KsPin)
80*c2c66affSColin Finck {
81*c2c66affSColin Finck HRESULT hr;
82*c2c66affSColin Finck IKsObject * KsObject;
83*c2c66affSColin Finck IKsPinEx * Pin;
84*c2c66affSColin Finck
85*c2c66affSColin Finck // get IKsPinEx interface
86*c2c66affSColin Finck hr = KsPin->QueryInterface(IID_IKsPinEx, (void**)&Pin);
87*c2c66affSColin Finck if (SUCCEEDED(hr))
88*c2c66affSColin Finck {
89*c2c66affSColin Finck // check if IKsObject is supported
90*c2c66affSColin Finck hr = KsPin->QueryInterface(IID_IKsObject, (void**)&KsObject);
91*c2c66affSColin Finck
92*c2c66affSColin Finck if (SUCCEEDED(hr))
93*c2c66affSColin Finck {
94*c2c66affSColin Finck // get pin handle
95*c2c66affSColin Finck m_Handle = KsObject->KsGetObjectHandle();
96*c2c66affSColin Finck
97*c2c66affSColin Finck // release IKsObject interface
98*c2c66affSColin Finck KsObject->Release();
99*c2c66affSColin Finck
100*c2c66affSColin Finck if (!m_Handle)
101*c2c66affSColin Finck {
102*c2c66affSColin Finck // expected a file handle
103*c2c66affSColin Finck hr = E_UNEXPECTED;
104*c2c66affSColin Finck Pin->Release();
105*c2c66affSColin Finck }
106*c2c66affSColin Finck else
107*c2c66affSColin Finck {
108*c2c66affSColin Finck if (m_Pin)
109*c2c66affSColin Finck {
110*c2c66affSColin Finck // release old interface
111*c2c66affSColin Finck m_Pin->Release();
112*c2c66affSColin Finck }
113*c2c66affSColin Finck m_Pin = Pin;
114*c2c66affSColin Finck }
115*c2c66affSColin Finck }
116*c2c66affSColin Finck else
117*c2c66affSColin Finck {
118*c2c66affSColin Finck //release IKsPinEx interface
119*c2c66affSColin Finck Pin->Release();
120*c2c66affSColin Finck }
121*c2c66affSColin Finck }
122*c2c66affSColin Finck #if 1
123*c2c66affSColin Finck //DBG code
124*c2c66affSColin Finck PIN_INFO PinInfo;
125*c2c66affSColin Finck IPin * pPin;
126*c2c66affSColin Finck if (SUCCEEDED(KsPin->QueryInterface(IID_IPin, (void**)&pPin)))
127*c2c66affSColin Finck {
128*c2c66affSColin Finck if (SUCCEEDED(pPin->QueryPinInfo(&PinInfo)))
129*c2c66affSColin Finck {
130*c2c66affSColin Finck if (PinInfo.pFilter)
131*c2c66affSColin Finck PinInfo.pFilter->Release();
132*c2c66affSColin Finck
133*c2c66affSColin Finck wcscpy(m_PinName, PinInfo.achName);
134*c2c66affSColin Finck }
135*c2c66affSColin Finck pPin->Release();
136*c2c66affSColin Finck }
137*c2c66affSColin Finck #endif
138*c2c66affSColin Finck
139*c2c66affSColin Finck // done
140*c2c66affSColin Finck return hr;
141*c2c66affSColin Finck }
142*c2c66affSColin Finck
143*c2c66affSColin Finck HRESULT
144*c2c66affSColin Finck STDMETHODCALLTYPE
KsProcessMediaSamples(IKsDataTypeHandler * KsDataTypeHandler,IMediaSample ** SampleList,PLONG SampleCount,KSIOOPERATION IoOperation,PKSSTREAM_SEGMENT * OutStreamSegment)145*c2c66affSColin Finck CKsInterfaceHandler::KsProcessMediaSamples(
146*c2c66affSColin Finck IKsDataTypeHandler *KsDataTypeHandler,
147*c2c66affSColin Finck IMediaSample** SampleList,
148*c2c66affSColin Finck PLONG SampleCount,
149*c2c66affSColin Finck KSIOOPERATION IoOperation,
150*c2c66affSColin Finck PKSSTREAM_SEGMENT *OutStreamSegment)
151*c2c66affSColin Finck {
152*c2c66affSColin Finck PKSSTREAM_SEGMENT_EXT StreamSegment;
153*c2c66affSColin Finck ULONG ExtendedSize, Index, BytesReturned;
154*c2c66affSColin Finck HRESULT hr = S_OK;
155*c2c66affSColin Finck
156*c2c66affSColin Finck // sanity check
157*c2c66affSColin Finck assert(*SampleCount);
158*c2c66affSColin Finck
159*c2c66affSColin Finck if (*SampleCount == 0 || *SampleCount < 0)
160*c2c66affSColin Finck return E_FAIL;
161*c2c66affSColin Finck
162*c2c66affSColin Finck // zero stream segment
163*c2c66affSColin Finck *OutStreamSegment = NULL;
164*c2c66affSColin Finck
165*c2c66affSColin Finck // allocate stream segment
166*c2c66affSColin Finck StreamSegment = (PKSSTREAM_SEGMENT_EXT)CoTaskMemAlloc(sizeof(KSSTREAM_SEGMENT_EXT));
167*c2c66affSColin Finck if (!StreamSegment)
168*c2c66affSColin Finck return E_OUTOFMEMORY;
169*c2c66affSColin Finck
170*c2c66affSColin Finck // zero stream segment
171*c2c66affSColin Finck ZeroMemory(StreamSegment, sizeof(KSSTREAM_SEGMENT_EXT));
172*c2c66affSColin Finck
173*c2c66affSColin Finck //allocate event
174*c2c66affSColin Finck StreamSegment->StreamSegment.CompletionEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
175*c2c66affSColin Finck
176*c2c66affSColin Finck if (!StreamSegment->StreamSegment.CompletionEvent)
177*c2c66affSColin Finck {
178*c2c66affSColin Finck // failed to create event
179*c2c66affSColin Finck CoTaskMemFree(StreamSegment);
180*c2c66affSColin Finck return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
181*c2c66affSColin Finck }
182*c2c66affSColin Finck
183*c2c66affSColin Finck // increase our own reference count
184*c2c66affSColin Finck AddRef();
185*c2c66affSColin Finck
186*c2c66affSColin Finck // setup stream segment
187*c2c66affSColin Finck StreamSegment->StreamSegment.KsDataTypeHandler = KsDataTypeHandler;
188*c2c66affSColin Finck StreamSegment->StreamSegment.KsInterfaceHandler = (IKsInterfaceHandler*)this;
189*c2c66affSColin Finck StreamSegment->StreamSegment.IoOperation = IoOperation;
190*c2c66affSColin Finck StreamSegment->Overlapped.hEvent = StreamSegment->StreamSegment.CompletionEvent;
191*c2c66affSColin Finck
192*c2c66affSColin Finck
193*c2c66affSColin Finck // ge extension size
194*c2c66affSColin Finck ExtendedSize = 0;
195*c2c66affSColin Finck if (KsDataTypeHandler)
196*c2c66affSColin Finck {
197*c2c66affSColin Finck // query extension size
198*c2c66affSColin Finck KsDataTypeHandler->KsQueryExtendedSize(&ExtendedSize);
199*c2c66affSColin Finck
200*c2c66affSColin Finck if (ExtendedSize)
201*c2c66affSColin Finck {
202*c2c66affSColin Finck // increment reference count
203*c2c66affSColin Finck KsDataTypeHandler->AddRef();
204*c2c66affSColin Finck }
205*c2c66affSColin Finck else
206*c2c66affSColin Finck {
207*c2c66affSColin Finck // no need for the datatype handler
208*c2c66affSColin Finck StreamSegment->StreamSegment.KsDataTypeHandler = NULL;
209*c2c66affSColin Finck }
210*c2c66affSColin Finck }
211*c2c66affSColin Finck
212*c2c66affSColin Finck StreamSegment->ExtendedSize = ExtendedSize;
213*c2c66affSColin Finck StreamSegment->SampleCount = (ULONG)*SampleCount;
214*c2c66affSColin Finck
215*c2c66affSColin Finck // calculate stream header size count
216*c2c66affSColin Finck ULONG StreamHeaderSize = StreamSegment->SampleCount * (sizeof(KSSTREAM_HEADER) + ExtendedSize);
217*c2c66affSColin Finck
218*c2c66affSColin Finck // allocate stream header
219*c2c66affSColin Finck StreamSegment->StreamHeader = (PKSSTREAM_HEADER)CoTaskMemAlloc(StreamHeaderSize);
220*c2c66affSColin Finck if (!StreamSegment->StreamHeader)
221*c2c66affSColin Finck {
222*c2c66affSColin Finck // not enough memory
223*c2c66affSColin Finck CloseHandle(StreamSegment->StreamSegment.CompletionEvent);
224*c2c66affSColin Finck
225*c2c66affSColin Finck if (StreamSegment->StreamSegment.KsDataTypeHandler)
226*c2c66affSColin Finck StreamSegment->StreamSegment.KsDataTypeHandler->Release();
227*c2c66affSColin Finck
228*c2c66affSColin Finck // free stream segment
229*c2c66affSColin Finck CoTaskMemFree(StreamSegment);
230*c2c66affSColin Finck
231*c2c66affSColin Finck //release our reference count
232*c2c66affSColin Finck Release();
233*c2c66affSColin Finck return E_OUTOFMEMORY;
234*c2c66affSColin Finck }
235*c2c66affSColin Finck
236*c2c66affSColin Finck // zero stream headers
237*c2c66affSColin Finck ZeroMemory(StreamSegment->StreamHeader, StreamHeaderSize);
238*c2c66affSColin Finck
239*c2c66affSColin Finck PKSSTREAM_HEADER CurStreamHeader = StreamSegment->StreamHeader;
240*c2c66affSColin Finck
241*c2c66affSColin Finck // initialize all stream headers
242*c2c66affSColin Finck for(Index = 0; Index < StreamSegment->SampleCount; Index++)
243*c2c66affSColin Finck {
244*c2c66affSColin Finck if (ExtendedSize)
245*c2c66affSColin Finck {
246*c2c66affSColin Finck // initialize extended size
247*c2c66affSColin Finck hr = KsDataTypeHandler->KsPrepareIoOperation(SampleList[Index], (CurStreamHeader + 1), IoOperation);
248*c2c66affSColin Finck // sanity check
249*c2c66affSColin Finck assert(hr == NOERROR);
250*c2c66affSColin Finck }
251*c2c66affSColin Finck
252*c2c66affSColin Finck // query for IMediaSample2 interface
253*c2c66affSColin Finck IMediaSample2 * MediaSample;
254*c2c66affSColin Finck AM_SAMPLE2_PROPERTIES Properties;
255*c2c66affSColin Finck ZeroMemory(&Properties, sizeof(AM_SAMPLE2_PROPERTIES));
256*c2c66affSColin Finck
257*c2c66affSColin Finck hr = SampleList[Index]->QueryInterface(IID_IMediaSample2, (void**)&MediaSample);
258*c2c66affSColin Finck if (SUCCEEDED(hr))
259*c2c66affSColin Finck {
260*c2c66affSColin Finck //get properties
261*c2c66affSColin Finck
262*c2c66affSColin Finck hr = MediaSample->GetProperties(sizeof(AM_SAMPLE2_PROPERTIES), (BYTE*)&Properties);
263*c2c66affSColin Finck
264*c2c66affSColin Finck //release IMediaSample2 interface
265*c2c66affSColin Finck MediaSample->Release();
266*c2c66affSColin Finck }
267*c2c66affSColin Finck else
268*c2c66affSColin Finck {
269*c2c66affSColin Finck // get properties
270*c2c66affSColin Finck hr = SampleList[Index]->GetPointer((BYTE**)&Properties.pbBuffer);
271*c2c66affSColin Finck assert(hr == NOERROR);
272*c2c66affSColin Finck hr = SampleList[Index]->GetTime(&Properties.tStart, &Properties.tStop);
273*c2c66affSColin Finck
274*c2c66affSColin Finck Properties.cbBuffer = SampleList[Index]->GetSize();
275*c2c66affSColin Finck assert(Properties.cbBuffer);
276*c2c66affSColin Finck
277*c2c66affSColin Finck Properties.dwSampleFlags = 0;
278*c2c66affSColin Finck
279*c2c66affSColin Finck if (SampleList[Index]->IsDiscontinuity() == S_OK)
280*c2c66affSColin Finck Properties.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
281*c2c66affSColin Finck
282*c2c66affSColin Finck if (SampleList[Index]->IsPreroll() == S_OK)
283*c2c66affSColin Finck Properties.dwSampleFlags |= AM_SAMPLE_PREROLL;
284*c2c66affSColin Finck
285*c2c66affSColin Finck if (SampleList[Index]->IsSyncPoint() == S_OK)
286*c2c66affSColin Finck Properties.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
287*c2c66affSColin Finck }
288*c2c66affSColin Finck #ifdef KSPROXY_TRACE
289*c2c66affSColin Finck WCHAR Buffer[200];
290*c2c66affSColin Finck swprintf(Buffer, L"CKsInterfaceHandler::KsProcessMediaSamples PinName %s BufferLength %lu Property Buffer %p ExtendedSize %u lActual %u dwSampleFlags %lx\n", m_PinName, Properties.cbBuffer, Properties.pbBuffer, ExtendedSize, Properties.lActual, Properties.dwSampleFlags);
291*c2c66affSColin Finck OutputDebugStringW(Buffer);
292*c2c66affSColin Finck #endif
293*c2c66affSColin Finck
294*c2c66affSColin Finck CurStreamHeader->Size = sizeof(KSSTREAM_HEADER) + ExtendedSize;
295*c2c66affSColin Finck CurStreamHeader->PresentationTime.Denominator = 1;
296*c2c66affSColin Finck CurStreamHeader->PresentationTime.Numerator = 1;
297*c2c66affSColin Finck CurStreamHeader->FrameExtent = Properties.cbBuffer;
298*c2c66affSColin Finck CurStreamHeader->Data = Properties.pbBuffer;
299*c2c66affSColin Finck
300*c2c66affSColin Finck if (IoOperation == KsIoOperation_Write)
301*c2c66affSColin Finck {
302*c2c66affSColin Finck // set flags
303*c2c66affSColin Finck CurStreamHeader->OptionsFlags = Properties.dwSampleFlags;
304*c2c66affSColin Finck CurStreamHeader->DataUsed = Properties.lActual;
305*c2c66affSColin Finck // increment reference count
306*c2c66affSColin Finck SampleList[Index]->AddRef();
307*c2c66affSColin Finck }
308*c2c66affSColin Finck
309*c2c66affSColin Finck // store sample in stream segment
310*c2c66affSColin Finck StreamSegment->MediaSample[Index] = SampleList[Index];
311*c2c66affSColin Finck
312*c2c66affSColin Finck // move to next header
313*c2c66affSColin Finck CurStreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)CurStreamHeader + CurStreamHeader->Size);
314*c2c66affSColin Finck }
315*c2c66affSColin Finck
316*c2c66affSColin Finck // submit to device
317*c2c66affSColin Finck m_Pin->KsIncrementPendingIoCount();
318*c2c66affSColin Finck
319*c2c66affSColin Finck if (DeviceIoControl(m_Handle,
320*c2c66affSColin Finck IoOperation == KsIoOperation_Write ? IOCTL_KS_WRITE_STREAM : IOCTL_KS_READ_STREAM,
321*c2c66affSColin Finck NULL, 0,
322*c2c66affSColin Finck StreamSegment->StreamHeader,
323*c2c66affSColin Finck StreamHeaderSize,
324*c2c66affSColin Finck &BytesReturned,
325*c2c66affSColin Finck &StreamSegment->Overlapped))
326*c2c66affSColin Finck {
327*c2c66affSColin Finck // signal completion
328*c2c66affSColin Finck SetEvent(StreamSegment->StreamSegment.CompletionEvent);
329*c2c66affSColin Finck hr = S_OK;
330*c2c66affSColin Finck *OutStreamSegment = (PKSSTREAM_SEGMENT)StreamSegment;
331*c2c66affSColin Finck }
332*c2c66affSColin Finck else
333*c2c66affSColin Finck {
334*c2c66affSColin Finck if (GetLastError() == ERROR_IO_PENDING)
335*c2c66affSColin Finck {
336*c2c66affSColin Finck *OutStreamSegment = (PKSSTREAM_SEGMENT)StreamSegment;
337*c2c66affSColin Finck hr = S_OK;
338*c2c66affSColin Finck }
339*c2c66affSColin Finck }
340*c2c66affSColin Finck return hr;
341*c2c66affSColin Finck }
342*c2c66affSColin Finck
343*c2c66affSColin Finck HRESULT
344*c2c66affSColin Finck STDMETHODCALLTYPE
KsCompleteIo(PKSSTREAM_SEGMENT InStreamSegment)345*c2c66affSColin Finck CKsInterfaceHandler::KsCompleteIo(
346*c2c66affSColin Finck PKSSTREAM_SEGMENT InStreamSegment)
347*c2c66affSColin Finck {
348*c2c66affSColin Finck PKSSTREAM_SEGMENT_EXT StreamSegment;
349*c2c66affSColin Finck PKSSTREAM_HEADER CurStreamHeader;
350*c2c66affSColin Finck DWORD dwError = ERROR_SUCCESS, BytesReturned;
351*c2c66affSColin Finck BOOL bOverlapped;
352*c2c66affSColin Finck ULONG Index;
353*c2c66affSColin Finck HRESULT hr;
354*c2c66affSColin Finck IMediaSample2 * MediaSample;
355*c2c66affSColin Finck AM_SAMPLE2_PROPERTIES Properties;
356*c2c66affSColin Finck REFERENCE_TIME Start, Stop;
357*c2c66affSColin Finck
358*c2c66affSColin Finck // get private stream segment
359*c2c66affSColin Finck StreamSegment = (PKSSTREAM_SEGMENT_EXT)InStreamSegment;
360*c2c66affSColin Finck
361*c2c66affSColin Finck // get result
362*c2c66affSColin Finck bOverlapped = GetOverlappedResult(m_Handle, &StreamSegment->Overlapped, &BytesReturned, FALSE);
363*c2c66affSColin Finck dwError = GetLastError();
364*c2c66affSColin Finck
365*c2c66affSColin Finck CurStreamHeader = StreamSegment->StreamHeader;
366*c2c66affSColin Finck
367*c2c66affSColin Finck //iterate through all stream headers
368*c2c66affSColin Finck for(Index = 0; Index < StreamSegment->SampleCount; Index++)
369*c2c66affSColin Finck {
370*c2c66affSColin Finck if (!bOverlapped)
371*c2c66affSColin Finck {
372*c2c66affSColin Finck // operation failed
373*c2c66affSColin Finck m_Pin->KsNotifyError(StreamSegment->MediaSample[Index], MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, dwError));
374*c2c66affSColin Finck }
375*c2c66affSColin Finck
376*c2c66affSColin Finck // query IMediaSample2 interface
377*c2c66affSColin Finck hr = StreamSegment->MediaSample[Index]->QueryInterface(IID_IMediaSample2, (void**)&MediaSample);
378*c2c66affSColin Finck if (SUCCEEDED(hr))
379*c2c66affSColin Finck {
380*c2c66affSColin Finck // media sample properties
381*c2c66affSColin Finck hr = MediaSample->GetProperties(sizeof(AM_SAMPLE2_PROPERTIES), (BYTE*)&Properties);
382*c2c66affSColin Finck if (SUCCEEDED(hr))
383*c2c66affSColin Finck {
384*c2c66affSColin Finck //update media sample properties
385*c2c66affSColin Finck Properties.dwTypeSpecificFlags = CurStreamHeader->TypeSpecificFlags;
386*c2c66affSColin Finck Properties.dwSampleFlags |= (CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY);
387*c2c66affSColin Finck
388*c2c66affSColin Finck MediaSample->SetProperties(sizeof(AM_SAMPLE2_PROPERTIES), (BYTE*)&Properties);
389*c2c66affSColin Finck }
390*c2c66affSColin Finck // release IMediaSample2 interface
391*c2c66affSColin Finck MediaSample->Release();
392*c2c66affSColin Finck }
393*c2c66affSColin Finck
394*c2c66affSColin Finck // was an extended header used
395*c2c66affSColin Finck if (StreamSegment->ExtendedSize)
396*c2c66affSColin Finck {
397*c2c66affSColin Finck // unprepare stream header extension
398*c2c66affSColin Finck StreamSegment->StreamSegment.KsDataTypeHandler->KsCompleteIoOperation(StreamSegment->MediaSample[Index], (CurStreamHeader + 1), StreamSegment->StreamSegment.IoOperation, bOverlapped == FALSE);
399*c2c66affSColin Finck }
400*c2c66affSColin Finck
401*c2c66affSColin Finck Start = 0;
402*c2c66affSColin Finck Stop = 0;
403*c2c66affSColin Finck if (bOverlapped && StreamSegment->StreamSegment.IoOperation == KsIoOperation_Read)
404*c2c66affSColin Finck {
405*c2c66affSColin Finck // update common media sample details
406*c2c66affSColin Finck StreamSegment->MediaSample[Index]->SetSyncPoint((CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT));
407*c2c66affSColin Finck StreamSegment->MediaSample[Index]->SetPreroll((CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_PREROLL));
408*c2c66affSColin Finck StreamSegment->MediaSample[Index]->SetDiscontinuity((CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY));
409*c2c66affSColin Finck
410*c2c66affSColin Finck if (CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEVALID)
411*c2c66affSColin Finck {
412*c2c66affSColin Finck // use valid timestamp
413*c2c66affSColin Finck Start = CurStreamHeader->PresentationTime.Time;
414*c2c66affSColin Finck
415*c2c66affSColin Finck if (CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DURATIONVALID)
416*c2c66affSColin Finck {
417*c2c66affSColin Finck Stop = CurStreamHeader->PresentationTime.Time + CurStreamHeader->Duration;
418*c2c66affSColin Finck }
419*c2c66affSColin Finck }
420*c2c66affSColin Finck }
421*c2c66affSColin Finck
422*c2c66affSColin Finck // now set time
423*c2c66affSColin Finck hr = StreamSegment->MediaSample[Index]->SetTime(&Start, &Stop);
424*c2c66affSColin Finck if (FAILED(hr))
425*c2c66affSColin Finck {
426*c2c66affSColin Finck // use start time
427*c2c66affSColin Finck StreamSegment->MediaSample[Index]->SetTime(&Start, &Start);
428*c2c66affSColin Finck }
429*c2c66affSColin Finck
430*c2c66affSColin Finck // set valid data length
431*c2c66affSColin Finck StreamSegment->MediaSample[Index]->SetActualDataLength(CurStreamHeader->DataUsed);
432*c2c66affSColin Finck
433*c2c66affSColin Finck if (StreamSegment->StreamSegment.IoOperation == KsIoOperation_Read)
434*c2c66affSColin Finck {
435*c2c66affSColin Finck if (bOverlapped)
436*c2c66affSColin Finck {
437*c2c66affSColin Finck // deliver sample
438*c2c66affSColin Finck m_Pin->KsDeliver(StreamSegment->MediaSample[Index], CurStreamHeader->OptionsFlags);
439*c2c66affSColin Finck }
440*c2c66affSColin Finck }
441*c2c66affSColin Finck else if (StreamSegment->StreamSegment.IoOperation == KsIoOperation_Write)
442*c2c66affSColin Finck {
443*c2c66affSColin Finck // release media sample reference
444*c2c66affSColin Finck StreamSegment->MediaSample[Index]->Release();
445*c2c66affSColin Finck }
446*c2c66affSColin Finck
447*c2c66affSColin Finck CurStreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)CurStreamHeader + CurStreamHeader->Size);
448*c2c66affSColin Finck }
449*c2c66affSColin Finck
450*c2c66affSColin Finck // delete stream headers
451*c2c66affSColin Finck CoTaskMemFree(StreamSegment->StreamHeader);
452*c2c66affSColin Finck
453*c2c66affSColin Finck if (StreamSegment->StreamSegment.KsDataTypeHandler)
454*c2c66affSColin Finck {
455*c2c66affSColin Finck // release reference
456*c2c66affSColin Finck StreamSegment->StreamSegment.KsDataTypeHandler->Release();
457*c2c66affSColin Finck }
458*c2c66affSColin Finck
459*c2c66affSColin Finck // decrement pending i/o count
460*c2c66affSColin Finck m_Pin->KsDecrementPendingIoCount();
461*c2c66affSColin Finck
462*c2c66affSColin Finck //notify of completion
463*c2c66affSColin Finck m_Pin->KsMediaSamplesCompleted(InStreamSegment);
464*c2c66affSColin Finck
465*c2c66affSColin Finck //destroy stream segment
466*c2c66affSColin Finck CoTaskMemFree(StreamSegment);
467*c2c66affSColin Finck
468*c2c66affSColin Finck //release reference to ourselves
469*c2c66affSColin Finck Release();
470*c2c66affSColin Finck
471*c2c66affSColin Finck // done
472*c2c66affSColin Finck // Event handle is closed by caller
473*c2c66affSColin Finck return S_OK;
474*c2c66affSColin Finck }
475*c2c66affSColin Finck
476*c2c66affSColin Finck HRESULT
477*c2c66affSColin Finck WINAPI
CKsInterfaceHandler_Constructor(IUnknown * pUnkOuter,REFIID riid,LPVOID * ppv)478*c2c66affSColin Finck CKsInterfaceHandler_Constructor(
479*c2c66affSColin Finck IUnknown * pUnkOuter,
480*c2c66affSColin Finck REFIID riid,
481*c2c66affSColin Finck LPVOID * ppv)
482*c2c66affSColin Finck {
483*c2c66affSColin Finck #ifdef KSPROXY_TRACE
484*c2c66affSColin Finck OutputDebugStringW(L"CKsInterfaceHandler_Constructor\n");
485*c2c66affSColin Finck #endif
486*c2c66affSColin Finck
487*c2c66affSColin Finck CKsInterfaceHandler * handler = new CKsInterfaceHandler();
488*c2c66affSColin Finck
489*c2c66affSColin Finck if (!handler)
490*c2c66affSColin Finck return E_OUTOFMEMORY;
491*c2c66affSColin Finck
492*c2c66affSColin Finck if (FAILED(handler->QueryInterface(riid, ppv)))
493*c2c66affSColin Finck {
494*c2c66affSColin Finck /* not supported */
495*c2c66affSColin Finck delete handler;
496*c2c66affSColin Finck return E_NOINTERFACE;
497*c2c66affSColin Finck }
498*c2c66affSColin Finck
499*c2c66affSColin Finck return NOERROR;
500*c2c66affSColin Finck }
501