mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
9393fc320e
Excluded: 3rd-party code (incl. wine) and most of the win32ss.
366 lines
7.8 KiB
C++
366 lines
7.8 KiB
C++
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
|
|
* FILE: dll/directx/ksproxy/mediasample.cpp
|
|
* PURPOSE: IMediaSample interface
|
|
*
|
|
* PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
|
|
*/
|
|
#include "precomp.h"
|
|
|
|
class CMediaSample : public IMediaSample
|
|
{
|
|
public:
|
|
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
|
|
|
|
STDMETHODIMP_(ULONG) AddRef()
|
|
{
|
|
InterlockedIncrement(&m_Ref);
|
|
return m_Ref;
|
|
}
|
|
STDMETHODIMP_(ULONG) Release()
|
|
{
|
|
InterlockedDecrement(&m_Ref);
|
|
if (!m_Ref)
|
|
{
|
|
if (m_Allocator)
|
|
{
|
|
m_Allocator->ReleaseBuffer((IMediaSample*)this);
|
|
return 0;
|
|
}
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return m_Ref;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE GetPointer(BYTE **ppBuffer);
|
|
long STDMETHODCALLTYPE GetSize(void);
|
|
HRESULT STDMETHODCALLTYPE GetTime(REFERENCE_TIME *pTimeStart, REFERENCE_TIME *pTimeEnd);
|
|
HRESULT STDMETHODCALLTYPE SetTime(REFERENCE_TIME *pTimeStart, REFERENCE_TIME *pTimeEnd);
|
|
HRESULT STDMETHODCALLTYPE IsSyncPoint();
|
|
HRESULT STDMETHODCALLTYPE SetSyncPoint(BOOL bIsSyncPoint);
|
|
HRESULT STDMETHODCALLTYPE IsPreroll();
|
|
HRESULT STDMETHODCALLTYPE SetPreroll(BOOL bIsPreroll);
|
|
long STDMETHODCALLTYPE GetActualDataLength();
|
|
HRESULT STDMETHODCALLTYPE SetActualDataLength(long Length);
|
|
HRESULT STDMETHODCALLTYPE GetMediaType(AM_MEDIA_TYPE **ppMediaType);
|
|
HRESULT STDMETHODCALLTYPE SetMediaType(AM_MEDIA_TYPE *pMediaType);
|
|
HRESULT STDMETHODCALLTYPE IsDiscontinuity();
|
|
HRESULT STDMETHODCALLTYPE SetDiscontinuity(BOOL bDiscontinuity);
|
|
HRESULT STDMETHODCALLTYPE GetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd);
|
|
HRESULT STDMETHODCALLTYPE SetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd);
|
|
|
|
CMediaSample(IMemAllocator * Allocator, BYTE * Buffer, LONG BufferSize);
|
|
virtual ~CMediaSample(){}
|
|
|
|
protected:
|
|
ULONG m_Flags;
|
|
ULONG m_TypeFlags;
|
|
BYTE * m_Buffer;
|
|
LONG m_ActualLength;
|
|
LONG m_BufferSize;
|
|
IMemAllocator * m_Allocator;
|
|
CMediaSample * m_Next;
|
|
REFERENCE_TIME m_StartTime;
|
|
REFERENCE_TIME m_StopTime;
|
|
LONGLONG m_MediaStart;
|
|
LONGLONG m_MediaStop;
|
|
AM_MEDIA_TYPE * m_MediaType;
|
|
ULONG m_StreamId;
|
|
|
|
public:
|
|
LONG m_Ref;
|
|
|
|
BOOL m_bMediaTimeValid;
|
|
|
|
|
|
};
|
|
|
|
CMediaSample::CMediaSample(
|
|
IMemAllocator * Allocator,
|
|
BYTE * Buffer,
|
|
LONG BufferSize) :
|
|
m_Flags(0),
|
|
m_TypeFlags(0),
|
|
m_Buffer(Buffer),
|
|
m_ActualLength(BufferSize),
|
|
m_BufferSize(BufferSize),
|
|
m_Allocator(Allocator),
|
|
m_Next(0),
|
|
m_StartTime(0),
|
|
m_StopTime(0),
|
|
m_MediaStart(0),
|
|
m_MediaStop(0),
|
|
m_MediaType(0),
|
|
m_StreamId(0),
|
|
m_Ref(0),
|
|
m_bMediaTimeValid(0)
|
|
{
|
|
}
|
|
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::QueryInterface(
|
|
IN REFIID refiid,
|
|
OUT PVOID* Output)
|
|
{
|
|
if (IsEqualGUID(refiid, IID_IUnknown) ||
|
|
IsEqualGUID(refiid, IID_IMediaSample))
|
|
{
|
|
*Output = PVOID(this);
|
|
reinterpret_cast<IMediaSample*>(*Output)->AddRef();
|
|
return NOERROR;
|
|
}
|
|
if (IsEqualGUID(refiid, IID_IMediaSample2))
|
|
{
|
|
#if 0
|
|
*Output = (IMediaSample2*)(this);
|
|
reinterpret_cast<IMediaSample2*>(*Output)->AddRef();
|
|
return NOERROR;
|
|
#endif
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
// IMediaSample interface
|
|
//
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::GetPointer(
|
|
BYTE **ppBuffer)
|
|
{
|
|
if (!ppBuffer)
|
|
return E_POINTER;
|
|
|
|
*ppBuffer = m_Buffer;
|
|
return S_OK;
|
|
}
|
|
|
|
long
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::GetSize()
|
|
{
|
|
return m_BufferSize;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::GetTime(
|
|
REFERENCE_TIME *pTimeStart,
|
|
REFERENCE_TIME *pTimeEnd)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (!pTimeStart || !pTimeEnd)
|
|
return E_POINTER;
|
|
|
|
if (!(m_Flags & (AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID)))
|
|
{
|
|
// no time is set
|
|
return VFW_E_SAMPLE_TIME_NOT_SET;
|
|
}
|
|
|
|
*pTimeStart = m_StartTime;
|
|
|
|
if (m_Flags & AM_SAMPLE_STOPVALID)
|
|
{
|
|
*pTimeEnd = m_StopTime;
|
|
hr = NOERROR;
|
|
}
|
|
else
|
|
{
|
|
*pTimeEnd = m_StartTime + 1;
|
|
hr = VFW_S_NO_STOP_TIME;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::SetTime(REFERENCE_TIME *pTimeStart, REFERENCE_TIME *pTimeEnd)
|
|
{
|
|
if (!pTimeStart)
|
|
{
|
|
m_Flags &= ~(AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID);
|
|
return NOERROR;
|
|
}
|
|
|
|
if (!pTimeEnd)
|
|
{
|
|
m_Flags &= ~(AM_SAMPLE_STOPVALID);
|
|
m_Flags |= AM_SAMPLE_TIMEVALID;
|
|
m_StartTime = *pTimeStart;
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
m_Flags |= (AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID);
|
|
m_StartTime = *pTimeStart;
|
|
m_StopTime = *pTimeEnd;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::IsSyncPoint()
|
|
{
|
|
return (m_Flags & AM_SAMPLE_SPLICEPOINT) ? S_OK : S_FALSE;
|
|
}
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::SetSyncPoint(BOOL bIsSyncPoint)
|
|
{
|
|
if (bIsSyncPoint)
|
|
m_Flags |= AM_SAMPLE_SPLICEPOINT;
|
|
else
|
|
m_Flags &= ~AM_SAMPLE_SPLICEPOINT;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::IsPreroll()
|
|
{
|
|
return (m_Flags & AM_SAMPLE_PREROLL) ? S_OK : S_FALSE;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::SetPreroll(BOOL bIsPreroll)
|
|
{
|
|
if (bIsPreroll)
|
|
m_Flags |= AM_SAMPLE_PREROLL;
|
|
else
|
|
m_Flags &= ~AM_SAMPLE_PREROLL;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
long
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::GetActualDataLength()
|
|
{
|
|
return m_ActualLength;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::SetActualDataLength(long Length)
|
|
{
|
|
if (Length > m_BufferSize)
|
|
return VFW_E_BUFFER_OVERFLOW;
|
|
|
|
m_ActualLength = Length;
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::GetMediaType(AM_MEDIA_TYPE **ppMediaType)
|
|
{
|
|
if (!m_MediaType)
|
|
{
|
|
*ppMediaType = NULL;
|
|
return S_FALSE;
|
|
}
|
|
|
|
assert(0);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::SetMediaType(AM_MEDIA_TYPE *pMediaType)
|
|
{
|
|
OutputDebugStringW(L"CMediaSample::SetMediaType NotImplemented\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::IsDiscontinuity()
|
|
{
|
|
return (m_Flags & AM_SAMPLE_DATADISCONTINUITY) ? S_OK : S_FALSE;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::SetDiscontinuity(BOOL bDiscontinuity)
|
|
{
|
|
if (bDiscontinuity)
|
|
m_Flags |= AM_SAMPLE_DATADISCONTINUITY;
|
|
else
|
|
m_Flags &= ~AM_SAMPLE_DATADISCONTINUITY;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::GetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd)
|
|
{
|
|
if (!pTimeStart || !pTimeEnd)
|
|
return E_POINTER;
|
|
|
|
if (!m_bMediaTimeValid)
|
|
return VFW_E_MEDIA_TIME_NOT_SET;
|
|
|
|
m_MediaStart = *pTimeStart;
|
|
m_MediaStop = *pTimeEnd;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
HRESULT
|
|
STDMETHODCALLTYPE
|
|
CMediaSample::SetMediaTime(LONGLONG *pTimeStart, LONGLONG *pTimeEnd)
|
|
{
|
|
if (!pTimeStart || !pTimeEnd)
|
|
{
|
|
m_bMediaTimeValid = false;
|
|
return NOERROR;
|
|
}
|
|
|
|
m_MediaStart = *pTimeStart;
|
|
m_MediaStop = *pTimeEnd;
|
|
|
|
return NOERROR;
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT
|
|
WINAPI
|
|
CMediaSample_Constructor(
|
|
IMemAllocator* Allocator,
|
|
BYTE* pBuffer,
|
|
ULONG BufferSize,
|
|
REFIID riid,
|
|
LPVOID * ppv)
|
|
{
|
|
#ifdef KSPROXY_TRACE
|
|
OutputDebugStringW(L"CMediaSample_Constructor\n");
|
|
#endif
|
|
|
|
CMediaSample * handler = new CMediaSample(Allocator, pBuffer, BufferSize);
|
|
|
|
if (!handler)
|
|
return E_OUTOFMEMORY;
|
|
|
|
if (FAILED(handler->QueryInterface(riid, ppv)))
|
|
{
|
|
/* not supported */
|
|
delete handler;
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
return NOERROR;
|
|
}
|