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