Reactos
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
11class CMediaSample : public IMediaSample
12{
13public:
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 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);
55 virtual ~CMediaSample(){}
56
57protected:
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
72public:
73 LONG m_Ref;
74
75 BOOL m_bMediaTimeValid;
76
77
78};
79
80CMediaSample::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
103HRESULT
104STDMETHODCALLTYPE
105CMediaSample::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//
131HRESULT
132STDMETHODCALLTYPE
133CMediaSample::GetPointer(
134 BYTE **ppBuffer)
135{
136 if (!ppBuffer)
137 return E_POINTER;
138
139 *ppBuffer = m_Buffer;
140 return S_OK;
141}
142
143long
144STDMETHODCALLTYPE
145CMediaSample::GetSize()
146{
147 return m_BufferSize;
148}
149
150HRESULT
151STDMETHODCALLTYPE
152CMediaSample::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
182HRESULT
183STDMETHODCALLTYPE
184CMediaSample::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
208HRESULT
209STDMETHODCALLTYPE
210CMediaSample::IsSyncPoint()
211{
212 return (m_Flags & AM_SAMPLE_SPLICEPOINT) ? S_OK : S_FALSE;
213}
214HRESULT
215STDMETHODCALLTYPE
216CMediaSample::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
226HRESULT
227STDMETHODCALLTYPE
228CMediaSample::IsPreroll()
229{
230 return (m_Flags & AM_SAMPLE_PREROLL) ? S_OK : S_FALSE;
231}
232
233HRESULT
234STDMETHODCALLTYPE
235CMediaSample::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
245long
246STDMETHODCALLTYPE
247CMediaSample::GetActualDataLength()
248{
249 return m_ActualLength;
250}
251
252HRESULT
253STDMETHODCALLTYPE
254CMediaSample::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
263HRESULT
264STDMETHODCALLTYPE
265CMediaSample::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
277HRESULT
278STDMETHODCALLTYPE
279CMediaSample::SetMediaType(AM_MEDIA_TYPE *pMediaType)
280{
281 OutputDebugStringW(L"CMediaSample::SetMediaType NotImplemented\n");
282 return E_NOTIMPL;
283}
284
285
286HRESULT
287STDMETHODCALLTYPE
288CMediaSample::IsDiscontinuity()
289{
290 return (m_Flags & AM_SAMPLE_DATADISCONTINUITY) ? S_OK : S_FALSE;
291}
292
293HRESULT
294STDMETHODCALLTYPE
295CMediaSample::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
305HRESULT
306STDMETHODCALLTYPE
307CMediaSample::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
321HRESULT
322STDMETHODCALLTYPE
323CMediaSample::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
340HRESULT
341WINAPI
342CMediaSample_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}