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