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