xref: /reactos/dll/directx/ksproxy/mediasample.cpp (revision 5100859e)
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 
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 
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 
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
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
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
145 CMediaSample::GetSize()
146 {
147     return m_BufferSize;
148 }
149 
150 HRESULT
151 STDMETHODCALLTYPE
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
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
210 CMediaSample::IsSyncPoint()
211 {
212     return (m_Flags & AM_SAMPLE_SPLICEPOINT) ? S_OK : S_FALSE;
213 }
214 HRESULT
215 STDMETHODCALLTYPE
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
228 CMediaSample::IsPreroll()
229 {
230     return (m_Flags & AM_SAMPLE_PREROLL) ? S_OK : S_FALSE;
231 }
232 
233 HRESULT
234 STDMETHODCALLTYPE
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
247 CMediaSample::GetActualDataLength()
248 {
249     return m_ActualLength;
250 }
251 
252 HRESULT
253 STDMETHODCALLTYPE
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
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
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
288 CMediaSample::IsDiscontinuity()
289 {
290     return (m_Flags & AM_SAMPLE_DATADISCONTINUITY) ? S_OK : S_FALSE;
291 }
292 
293 HRESULT
294 STDMETHODCALLTYPE
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
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
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
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