⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mspool.cpp

📁 最近在学习directshow, Directshow实务精选的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
// 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 + -