[KSPROXY]
[reactos.git] / reactos / dll / directx / ksproxy / mediasample.cpp
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
4 * FILE: dll/directx/ksproxy/mediasample.cpp
5 * PURPOSE: IMediaSample interface
6 *
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
8 */
9 #include "precomp.h"
10
11 class CMediaSample : public IMediaSample
12 {
13 public:
14 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
15
16 STDMETHODIMP_(ULONG) AddRef()
17 {
18 InterlockedIncrement(&m_Ref);
19 return m_Ref;
20 }
21 STDMETHODIMP_(ULONG) Release()
22 {
23 InterlockedDecrement(&m_Ref);
24 DebugBreak();
25 if (!m_Ref)
26 {
27 if (m_Allocator)
28 {
29 m_Allocator->ReleaseBuffer((IMediaSample*)this);
30 return 0;
31 }
32 delete this;
33 return 0;
34 }
35 return m_Ref;
36 }
37
38 HRESULT STDMETHODCALLTYPE GetPointer(BYTE **ppBuffer);
39 long STDMETHODCALLTYPE GetSize(void);
40 HRESULT STDMETHODCALLTYPE GetTime(REFERENCE_TIME *pTimeStart, REFERENCE_TIME *pTimeEnd);
41 HRESULT STDMETHODCALLTYPE SetTime(REFERENCE_TIME *pTimeStart, REFERENCE_TIME *pTimeEnd);
42 HRESULT STDMETHODCALLTYPE IsSyncPoint();
43 HRESULT STDMETHODCALLTYPE SetSyncPoint(BOOL bIsSyncPoint);
44 HRESULT STDMETHODCALLTYPE IsPreroll();
45 HRESULT STDMETHODCALLTYPE SetPreroll(BOOL bIsPreroll);
46 long STDMETHODCALLTYPE GetActualDataLength();
47 HRESULT STDMETHODCALLTYPE SetActualDataLength(long Length);
48 HRESULT STDMETHODCALLTYPE GetMediaType(AM_MEDIA_TYPE **ppMediaType);
49 HRESULT STDMETHODCALLTYPE SetMediaType(AM_MEDIA_TYPE *pMediaType);
50 HRESULT STDMETHODCALLTYPE IsDiscontinuity();
51 HRESULT STDMETHODCALLTYPE SetDiscontinuity(BOOL bDiscontinuity);
52 HRESULT STDMETHODCALLTYPE GetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd);
53 HRESULT STDMETHODCALLTYPE SetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd);
54
55 CMediaSample(IMemAllocator * Allocator, BYTE * Buffer, LONG BufferSize);
56 virtual ~CMediaSample(){}
57
58 protected:
59 ULONG m_Flags;
60 ULONG m_TypeFlags;
61 BYTE * m_Buffer;
62 LONG m_ActualLength;
63 LONG m_BufferSize;
64 IMemAllocator * m_Allocator;
65 CMediaSample * m_Next;
66 REFERENCE_TIME m_StartTime;
67 REFERENCE_TIME m_StopTime;
68 LONGLONG m_MediaStart;
69 LONGLONG m_MediaStop;
70 AM_MEDIA_TYPE * m_MediaType;
71 ULONG m_StreamId;
72
73 public:
74 LONG m_Ref;
75
76 BOOL m_bMediaTimeValid;
77
78
79 };
80
81 CMediaSample::CMediaSample(
82 IMemAllocator * Allocator,
83 BYTE * Buffer,
84 LONG BufferSize) :
85 m_Flags(0),
86 m_TypeFlags(0),
87 m_Buffer(Buffer),
88 m_ActualLength(BufferSize),
89 m_BufferSize(BufferSize),
90 m_Allocator(Allocator),
91 m_Next(0),
92 m_StartTime(0),
93 m_StopTime(0),
94 m_MediaStart(0),
95 m_MediaStop(0),
96 m_MediaType(0),
97 m_StreamId(0),
98 m_Ref(0),
99 m_bMediaTimeValid(0)
100 {
101 }
102
103
104 HRESULT
105 STDMETHODCALLTYPE
106 CMediaSample::QueryInterface(
107 IN REFIID refiid,
108 OUT PVOID* Output)
109 {
110 if (IsEqualGUID(refiid, IID_IUnknown) ||
111 IsEqualGUID(refiid, IID_IMediaSample))
112 {
113 *Output = PVOID(this);
114 reinterpret_cast<IMediaSample*>(*Output)->AddRef();
115 return NOERROR;
116 }
117 if (IsEqualGUID(refiid, IID_IMediaSample2))
118 {
119
120 OutputDebugStringW(L"CMediaSample::QueryInterface requested IMediaSample2 interface\n");
121 #if 0
122 *Output = (IMediaSample2*)(this);
123 reinterpret_cast<IMediaSample2*>(*Output)->AddRef();
124 return NOERROR;
125 #endif
126 }
127
128 return E_NOINTERFACE;
129 }
130
131 //-------------------------------------------------------------------
132 // IMediaSample interface
133 //
134 HRESULT
135 STDMETHODCALLTYPE
136 CMediaSample::GetPointer(
137 BYTE **ppBuffer)
138 {
139 if (!ppBuffer)
140 return E_POINTER;
141
142 *ppBuffer = m_Buffer;
143 return S_OK;
144 }
145
146 long
147 STDMETHODCALLTYPE
148 CMediaSample::GetSize()
149 {
150 return m_BufferSize;
151 }
152
153 HRESULT
154 STDMETHODCALLTYPE
155 CMediaSample::GetTime(
156 REFERENCE_TIME *pTimeStart,
157 REFERENCE_TIME *pTimeEnd)
158 {
159 HRESULT hr;
160
161 if (!pTimeStart || !pTimeEnd)
162 return E_POINTER;
163
164 if (!(m_Flags & (AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID)))
165 {
166 // no time is set
167 return VFW_E_SAMPLE_TIME_NOT_SET;
168 }
169
170 *pTimeStart = m_StartTime;
171
172 if (m_Flags & AM_SAMPLE_STOPVALID)
173 {
174 *pTimeEnd = m_StopTime;
175 hr = NOERROR;
176 }
177 else
178 {
179 *pTimeEnd = m_StartTime + 1;
180 hr = VFW_S_NO_STOP_TIME;
181 }
182 return hr;
183 }
184
185 HRESULT
186 STDMETHODCALLTYPE
187 CMediaSample::SetTime(REFERENCE_TIME *pTimeStart, REFERENCE_TIME *pTimeEnd)
188 {
189 if (!pTimeStart)
190 {
191 m_Flags &= ~(AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID);
192 return NOERROR;
193 }
194
195 if (!pTimeEnd)
196 {
197 m_Flags &= ~(AM_SAMPLE_STOPVALID);
198 m_Flags |= AM_SAMPLE_TIMEVALID;
199 m_StartTime = *pTimeStart;
200 return NOERROR;
201 }
202
203
204 m_Flags |= (AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID);
205 m_StartTime = *pTimeStart;
206 m_StopTime = *pTimeEnd;
207
208 return NOERROR;
209 }
210
211 HRESULT
212 STDMETHODCALLTYPE
213 CMediaSample::IsSyncPoint()
214 {
215 return (m_Flags & AM_SAMPLE_SPLICEPOINT) ? S_OK : S_FALSE;
216 }
217 HRESULT
218 STDMETHODCALLTYPE
219 CMediaSample::SetSyncPoint(BOOL bIsSyncPoint)
220 {
221 if (bIsSyncPoint)
222 m_Flags |= AM_SAMPLE_SPLICEPOINT;
223 else
224 m_Flags &= ~AM_SAMPLE_SPLICEPOINT;
225
226 return NOERROR;
227 }
228
229 HRESULT
230 STDMETHODCALLTYPE
231 CMediaSample::IsPreroll()
232 {
233 return (m_Flags & AM_SAMPLE_PREROLL) ? S_OK : S_FALSE;
234 }
235
236 HRESULT
237 STDMETHODCALLTYPE
238 CMediaSample::SetPreroll(BOOL bIsPreroll)
239 {
240 if (bIsPreroll)
241 m_Flags |= AM_SAMPLE_PREROLL;
242 else
243 m_Flags &= ~AM_SAMPLE_PREROLL;
244
245 return NOERROR;
246 }
247
248 long
249 STDMETHODCALLTYPE
250 CMediaSample::GetActualDataLength()
251 {
252 return m_ActualLength;
253 }
254
255 HRESULT
256 STDMETHODCALLTYPE
257 CMediaSample::SetActualDataLength(long Length)
258 {
259 if (Length > m_BufferSize)
260 return VFW_E_BUFFER_OVERFLOW;
261
262 m_ActualLength = Length;
263 return NOERROR;
264 }
265
266 HRESULT
267 STDMETHODCALLTYPE
268 CMediaSample::GetMediaType(AM_MEDIA_TYPE **ppMediaType)
269 {
270 OutputDebugStringW(L"CMediaSample::GetMediaType\n");
271
272 if (!m_MediaType)
273 {
274 *ppMediaType = NULL;
275 return S_FALSE;
276 }
277
278 assert(0);
279 return E_NOTIMPL;
280 }
281
282 HRESULT
283 STDMETHODCALLTYPE
284 CMediaSample::SetMediaType(AM_MEDIA_TYPE *pMediaType)
285 {
286 OutputDebugStringW(L"CMediaSample::SetMediaType NotImplemented\n");
287 DebugBreak();
288 return E_NOTIMPL;
289 }
290
291
292 HRESULT
293 STDMETHODCALLTYPE
294 CMediaSample::IsDiscontinuity()
295 {
296 return (m_Flags & AM_SAMPLE_DATADISCONTINUITY) ? S_OK : S_FALSE;
297 }
298
299 HRESULT
300 STDMETHODCALLTYPE
301 CMediaSample::SetDiscontinuity(BOOL bDiscontinuity)
302 {
303 if (bDiscontinuity)
304 m_Flags |= AM_SAMPLE_DATADISCONTINUITY;
305 else
306 m_Flags &= ~AM_SAMPLE_DATADISCONTINUITY;
307
308 return NOERROR;
309 }
310
311 HRESULT
312 STDMETHODCALLTYPE
313 CMediaSample::GetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd)
314 {
315 if (!pTimeStart || !pTimeEnd)
316 return E_POINTER;
317
318 if (!m_bMediaTimeValid)
319 return VFW_E_MEDIA_TIME_NOT_SET;
320
321 m_MediaStart = *pTimeStart;
322 m_MediaStop = *pTimeEnd;
323
324 return NOERROR;
325 }
326
327 HRESULT
328 STDMETHODCALLTYPE
329 CMediaSample::SetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd)
330 {
331 if (!pTimeStart || !pTimeEnd)
332 {
333 m_bMediaTimeValid = false;
334 return NOERROR;
335 }
336
337 m_MediaStart = *pTimeStart;
338 m_MediaStop = *pTimeEnd;
339
340 return NOERROR;
341 }
342
343
344
345
346 HRESULT
347 WINAPI
348 CMediaSample_Constructor(
349 IMemAllocator* Allocator,
350 BYTE* pBuffer,
351 ULONG BufferSize,
352 REFIID riid,
353 LPVOID * ppv)
354 {
355 OutputDebugStringW(L"CMediaSample_Constructor\n");
356
357 CMediaSample * handler = new CMediaSample(Allocator, pBuffer, BufferSize);
358
359 if (!handler)
360 return E_OUTOFMEMORY;
361
362 if (FAILED(handler->QueryInterface(riid, ppv)))
363 {
364 /* not supported */
365 delete handler;
366 return E_NOINTERFACE;
367 }
368
369 return NOERROR;
370 }