[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 #if 0
120 *Output = (IMediaSample2*)(this);
121 reinterpret_cast<IMediaSample2*>(*Output)->AddRef();
122 return NOERROR;
123 #endif
124 }
125
126 return E_NOINTERFACE;
127 }
128
129 //-------------------------------------------------------------------
130 // IMediaSample interface
131 //
132 HRESULT
133 STDMETHODCALLTYPE
134 CMediaSample::GetPointer(
135 BYTE **ppBuffer)
136 {
137 if (!ppBuffer)
138 return E_POINTER;
139
140 *ppBuffer = m_Buffer;
141 return S_OK;
142 }
143
144 long
145 STDMETHODCALLTYPE
146 CMediaSample::GetSize()
147 {
148 return m_BufferSize;
149 }
150
151 HRESULT
152 STDMETHODCALLTYPE
153 CMediaSample::GetTime(
154 REFERENCE_TIME *pTimeStart,
155 REFERENCE_TIME *pTimeEnd)
156 {
157 HRESULT hr;
158
159 if (!pTimeStart || !pTimeEnd)
160 return E_POINTER;
161
162 if (!(m_Flags & (AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID)))
163 {
164 // no time is set
165 return VFW_E_SAMPLE_TIME_NOT_SET;
166 }
167
168 *pTimeStart = m_StartTime;
169
170 if (m_Flags & AM_SAMPLE_STOPVALID)
171 {
172 *pTimeEnd = m_StopTime;
173 hr = NOERROR;
174 }
175 else
176 {
177 *pTimeEnd = m_StartTime + 1;
178 hr = VFW_S_NO_STOP_TIME;
179 }
180 return hr;
181 }
182
183 HRESULT
184 STDMETHODCALLTYPE
185 CMediaSample::SetTime(REFERENCE_TIME *pTimeStart, REFERENCE_TIME *pTimeEnd)
186 {
187 if (!pTimeStart)
188 {
189 m_Flags &= ~(AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID);
190 return NOERROR;
191 }
192
193 if (!pTimeEnd)
194 {
195 m_Flags &= ~(AM_SAMPLE_STOPVALID);
196 m_Flags |= AM_SAMPLE_TIMEVALID;
197 m_StartTime = *pTimeStart;
198 return NOERROR;
199 }
200
201
202 m_Flags |= (AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID);
203 m_StartTime = *pTimeStart;
204 m_StopTime = *pTimeEnd;
205
206 return NOERROR;
207 }
208
209 HRESULT
210 STDMETHODCALLTYPE
211 CMediaSample::IsSyncPoint()
212 {
213 return (m_Flags & AM_SAMPLE_SPLICEPOINT) ? S_OK : S_FALSE;
214 }
215 HRESULT
216 STDMETHODCALLTYPE
217 CMediaSample::SetSyncPoint(BOOL bIsSyncPoint)
218 {
219 if (bIsSyncPoint)
220 m_Flags |= AM_SAMPLE_SPLICEPOINT;
221 else
222 m_Flags &= ~AM_SAMPLE_SPLICEPOINT;
223
224 return NOERROR;
225 }
226
227 HRESULT
228 STDMETHODCALLTYPE
229 CMediaSample::IsPreroll()
230 {
231 return (m_Flags & AM_SAMPLE_PREROLL) ? S_OK : S_FALSE;
232 }
233
234 HRESULT
235 STDMETHODCALLTYPE
236 CMediaSample::SetPreroll(BOOL bIsPreroll)
237 {
238 if (bIsPreroll)
239 m_Flags |= AM_SAMPLE_PREROLL;
240 else
241 m_Flags &= ~AM_SAMPLE_PREROLL;
242
243 return NOERROR;
244 }
245
246 long
247 STDMETHODCALLTYPE
248 CMediaSample::GetActualDataLength()
249 {
250 return m_ActualLength;
251 }
252
253 HRESULT
254 STDMETHODCALLTYPE
255 CMediaSample::SetActualDataLength(long Length)
256 {
257 if (Length > m_BufferSize)
258 return VFW_E_BUFFER_OVERFLOW;
259
260 m_ActualLength = Length;
261 return NOERROR;
262 }
263
264 HRESULT
265 STDMETHODCALLTYPE
266 CMediaSample::GetMediaType(AM_MEDIA_TYPE **ppMediaType)
267 {
268 if (!m_MediaType)
269 {
270 *ppMediaType = NULL;
271 return S_FALSE;
272 }
273
274 assert(0);
275 return E_NOTIMPL;
276 }
277
278 HRESULT
279 STDMETHODCALLTYPE
280 CMediaSample::SetMediaType(AM_MEDIA_TYPE *pMediaType)
281 {
282 OutputDebugStringW(L"CMediaSample::SetMediaType NotImplemented\n");
283 DebugBreak();
284 return E_NOTIMPL;
285 }
286
287
288 HRESULT
289 STDMETHODCALLTYPE
290 CMediaSample::IsDiscontinuity()
291 {
292 return (m_Flags & AM_SAMPLE_DATADISCONTINUITY) ? S_OK : S_FALSE;
293 }
294
295 HRESULT
296 STDMETHODCALLTYPE
297 CMediaSample::SetDiscontinuity(BOOL bDiscontinuity)
298 {
299 if (bDiscontinuity)
300 m_Flags |= AM_SAMPLE_DATADISCONTINUITY;
301 else
302 m_Flags &= ~AM_SAMPLE_DATADISCONTINUITY;
303
304 return NOERROR;
305 }
306
307 HRESULT
308 STDMETHODCALLTYPE
309 CMediaSample::GetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd)
310 {
311 if (!pTimeStart || !pTimeEnd)
312 return E_POINTER;
313
314 if (!m_bMediaTimeValid)
315 return VFW_E_MEDIA_TIME_NOT_SET;
316
317 m_MediaStart = *pTimeStart;
318 m_MediaStop = *pTimeEnd;
319
320 return NOERROR;
321 }
322
323 HRESULT
324 STDMETHODCALLTYPE
325 CMediaSample::SetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd)
326 {
327 if (!pTimeStart || !pTimeEnd)
328 {
329 m_bMediaTimeValid = false;
330 return NOERROR;
331 }
332
333 m_MediaStart = *pTimeStart;
334 m_MediaStop = *pTimeEnd;
335
336 return NOERROR;
337 }
338
339
340
341
342 HRESULT
343 WINAPI
344 CMediaSample_Constructor(
345 IMemAllocator* Allocator,
346 BYTE* pBuffer,
347 ULONG BufferSize,
348 REFIID riid,
349 LPVOID * ppv)
350 {
351 #ifdef KSPROXY_TRACE
352 OutputDebugStringW(L"CMediaSample_Constructor\n");
353 #endif
354
355 CMediaSample * handler = new CMediaSample(Allocator, pBuffer, BufferSize);
356
357 if (!handler)
358 return E_OUTOFMEMORY;
359
360 if (FAILED(handler->QueryInterface(riid, ppv)))
361 {
362 /* not supported */
363 delete handler;
364 return E_NOINTERFACE;
365 }
366
367 return NOERROR;
368 }