Reactos
at master 366 lines 8.0 kB view raw
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}