📄 mspool.cpp
字号:
//------------------------------------------------------------------------------
// File: MSPool.cpp
//
// Desc: DirectShow sample code - implementation of DSNetwork sample filters
//
// Copyright (c) 2000-2002 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include "precomp.h"
#include "dsnetifc.h"
#include "le.h"
#include "buffpool.h"
#include "dsrecv.h"
#include "mspool.h"
// ---------------------------------------------------------------------------
// CTSMediaSample
// ---------------------------------------------------------------------------
CTSMediaSample::CTSMediaSample (
IN CTSMediaSamplePool * pMSPool
) : m_pMSPool (pMSPool),
m_lRef (0),
m_pBuffer (NULL),
m_dwFlags (0),
m_dwTypeSpecificFlags (0),
m_pbPayload (NULL),
m_lActual (0),
m_rtStart (0),
m_rtEnd (0),
m_llMediaStart (0),
m_llMediaEnd (0),
m_pMediaType (NULL),
m_dwStreamId (0)
{
ASSERT (m_pMSPool) ;
}
CTSMediaSample::~CTSMediaSample (
)
{
ASSERT (m_pMediaType == NULL) ;
}
// -------------------------------------------------------------------
// init
void
CTSMediaSample::ResetMS_ (
)
{
// the flags
m_dwFlags = 0x00000000 ;
// the media type, if it is set
if (m_pMediaType != NULL) {
DeleteMediaType (m_pMediaType) ;
m_pMediaType = NULL ;
}
}
HRESULT
CTSMediaSample::Init (
IN CBuffer * pBuffer,
IN BYTE * pbPayload,
IN int iPayloadLength,
IN LONGLONG * pllMediaStart,
IN LONGLONG * pllMediaEnd,
IN REFERENCE_TIME * prtStart,
IN REFERENCE_TIME * prtEnd,
IN DWORD dwMediaSampleFlags
)
{
ASSERT (pBuffer) ;
ASSERT ((dwMediaSampleFlags | SAMPLE_VALIDFLAGS) == SAMPLE_VALIDFLAGS) ;
// buffer we'll be referencing
m_pBuffer = pBuffer ;
m_pBuffer -> AddRef () ;
// set media sample properties
m_pbPayload = pbPayload ; // pbPayload might not align with
// start of CBuffer's buffer
m_lActual = iPayloadLength ; // nor may the length be same as
// CBuffer's length
m_dwFlags = dwMediaSampleFlags ;
// we don't support in-band media type changes
ASSERT ((m_dwFlags & SAMPLE_TYPECHANGED) == 0) ;
// pts
if (m_dwFlags & SAMPLE_TIMEVALID) {
// overflows should be a non-issue
m_rtStart = (* prtStart) ;
if (m_dwFlags & SAMPLE_STOPVALID) {
m_rtEnd = (* prtEnd) ;
}
}
// media times
if (m_dwFlags & SAMPLE_MEDIATIMEVALID) {
m_llMediaStart = (* pllMediaStart) ;
m_llMediaEnd = (* pllMediaEnd) ;
}
return S_OK ;
}
// -------------------------------------------------------------------
// IUnknown methods
STDMETHODIMP
CTSMediaSample::QueryInterface (
IN REFIID riid,
OUT void ** ppv
)
{
if (ppv == NULL) {
return E_INVALIDARG ;
}
if (riid == IID_IUnknown ||
riid == IID_IMediaSample ||
riid == IID_IMediaSample2) {
(* ppv) = reinterpret_cast <void *> (this) ;
}
else {
return E_NOINTERFACE ;
}
(reinterpret_cast <IUnknown *> (* ppv)) -> AddRef () ;
return S_OK ;
}
STDMETHODIMP_(ULONG)
CTSMediaSample::AddRef (
)
{
return InterlockedIncrement (& m_lRef) ;
}
STDMETHODIMP_(ULONG)
CTSMediaSample::Release (
)
{
if (InterlockedDecrement (& m_lRef) == 0) {
// release the buffer we're referencing
m_pBuffer -> Release () ;
m_pBuffer = NULL ;
// reset our internal fields
ResetMS_ () ;
// recycle ourselves into the pool
m_pMSPool -> RecycleMS (this) ;
return 0 ;
}
return m_lRef ;
}
// -------------------------------------------------------------------
// IMediaSample
// get me a read/write pointer to this buffer's memory. I will actually
// want to use sizeUsed bytes.
STDMETHODIMP
CTSMediaSample::GetPointer (
OUT BYTE ** ppBuffer
)
{
if (ppBuffer == NULL) {
return E_POINTER ;
}
(* ppBuffer) = m_pbPayload ;
return S_OK ;
}
// return the size in bytes of the buffer data area
STDMETHODIMP_(LONG)
CTSMediaSample::GetSize (
)
{
return m_lActual ;
}
// get the stream time at which this sample should start and finish.
STDMETHODIMP
CTSMediaSample::GetTime (
OUT REFERENCE_TIME * pTimeStart, // put time here
OUT REFERENCE_TIME * pTimeEnd
)
{
HRESULT hr ;
if ((m_dwFlags & SAMPLE_TIMEVALID) == 0) {
return VFW_E_SAMPLE_TIME_NOT_SET ;
}
if (pTimeStart == NULL ||
pTimeEnd == NULL) {
return E_POINTER ;
}
// start time is there; maybe stop time
(* pTimeStart) = m_rtStart ;
// do we have a stop time ?
if ((m_dwFlags & SAMPLE_STOPVALID) != 0) {
(* pTimeEnd) = m_rtEnd ;
hr = S_OK ;
}
else {
// apparently this breaks older stuff if we don't do this ..
(* pTimeEnd) = m_rtStart + 1 ;
hr = VFW_S_NO_STOP_TIME ;
}
return hr ;
}
// Set the stream time at which this sample should start and finish.
// pTimeStart==pTimeEnd==NULL will invalidate the time stamps in
// this sample
STDMETHODIMP
CTSMediaSample::SetTime (
IN REFERENCE_TIME * pTimeStart, // put time here
IN REFERENCE_TIME * pTimeEnd
)
{
// caller wishes to explicitely clear the time
if (pTimeStart == NULL) {
// clear the flags
m_dwFlags &= ~(SAMPLE_TIMEVALID | SAMPLE_STOPVALID) ;
return S_OK ;
}
// we have been given a start time
m_dwFlags |= SAMPLE_TIMEVALID ;
m_rtStart = * pTimeStart ;
// do we have a stop time ?
if (pTimeEnd != NULL) {
m_dwFlags |= SAMPLE_STOPVALID ;
m_rtEnd = (* pTimeEnd) ;
}
else {
// clear the stop time valid flag
m_dwFlags &= ~SAMPLE_STOPVALID ;
}
return S_OK ;
}
// sync-point property. If true, then the beginning of this
// sample is a sync-point. (note that if AM_MEDIA_TYPE.bTemporalCompression
// is false then all samples are sync points). A filter can start
// a stream at any sync point. S_FALSE if not sync-point, S_OK if true.
STDMETHODIMP
CTSMediaSample::IsSyncPoint (
)
{
return (m_dwFlags & SAMPLE_SYNCPOINT) ? S_OK : S_FALSE ;
}
STDMETHODIMP
CTSMediaSample::SetSyncPoint (
IN BOOL bIsSyncPoint
)
{
if (bIsSyncPoint) {
m_dwFlags |= SAMPLE_SYNCPOINT ;
}
else {
m_dwFlags &= ~SAMPLE_SYNCPOINT ;
}
return S_OK ;
}
// preroll property. If true, this sample is for preroll only and
// shouldn't be displayed.
STDMETHODIMP
CTSMediaSample::IsPreroll (
)
{
return (m_dwFlags & SAMPLE_PREROLL) ? S_OK : S_FALSE ;
}
STDMETHODIMP
CTSMediaSample::SetPreroll (
BOOL bIsPreroll
)
{
if (bIsPreroll) {
m_dwFlags |= SAMPLE_PREROLL ;
}
else {
m_dwFlags &= ~SAMPLE_PREROLL ;
}
return S_OK ;
}
STDMETHODIMP_(LONG)
CTSMediaSample::GetActualDataLength (
)
{
return m_lActual ;
}
STDMETHODIMP
CTSMediaSample::SetActualDataLength (
IN long lActual
)
{
if (lActual > m_lActual) {
return VFW_E_BUFFER_OVERFLOW ;
}
m_lActual = lActual ;
return S_OK ;
}
// these allow for limited format changes in band - if no format change
// has been made when you receive a sample GetMediaType will return S_FALSE
STDMETHODIMP
CTSMediaSample::GetMediaType (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -