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

📄 mspool.cpp

📁 最近在学习directshow, Directshow实务精选的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    AM_MEDIA_TYPE ** ppMediaType
    )
{
    if (ppMediaType == NULL) {
        return E_POINTER ;
    }

    if ((m_dwFlags & SAMPLE_TYPECHANGED) == 0) {
        ASSERT (m_pMediaType == NULL) ;
        (* ppMediaType) = NULL ;
        return S_FALSE ;
    }

    ASSERT (m_pMediaType != NULL) ;

    (* ppMediaType) = CreateMediaType (m_pMediaType) ;
    if (* ppMediaType) {
        return E_OUTOFMEMORY ;
    }

    return S_OK ;
}

STDMETHODIMP
CTSMediaSample::SetMediaType (
    AM_MEDIA_TYPE * pMediaType
    )
{
    if (m_pMediaType != NULL) {
        DeleteMediaType (m_pMediaType) ;
        m_pMediaType = NULL ;
    }

    //  explicitely being cleared
    if (pMediaType == NULL) {
        m_dwFlags &= ~SAMPLE_TYPECHANGED ;
        return S_OK ;
    }

    m_pMediaType = CreateMediaType (pMediaType) ;
    if (m_pMediaType == NULL) {
        m_dwFlags &= ~SAMPLE_TYPECHANGED ;
        return E_OUTOFMEMORY ;
    }

    m_dwFlags |= SAMPLE_TYPECHANGED ;

    return S_OK ;
}

// returns S_OK if there is a discontinuity in the data (this frame is
// not a continuation of the previous stream of data
// - there has been a seek or some dropped samples).
STDMETHODIMP
CTSMediaSample::IsDiscontinuity (
    )
{
    return (m_dwFlags & SAMPLE_DISCONTINUITY) ? S_OK : S_FALSE ;
}

// set the discontinuity property - TRUE if this sample is not a
// continuation, but a new sample after a seek or a dropped sample.
STDMETHODIMP
CTSMediaSample::SetDiscontinuity (
    BOOL bDiscontinuity
    )
{
    if (bDiscontinuity) {
        m_dwFlags |= SAMPLE_DISCONTINUITY ;
    }
    else {
        m_dwFlags &= ~SAMPLE_DISCONTINUITY ;
    }

    return S_OK ;
}

// get the media times for this sample
STDMETHODIMP
CTSMediaSample::GetMediaTime (
    OUT LONGLONG * pTimeStart,
    OUT LONGLONG * pTimeEnd
    )
{
    if ((m_dwFlags & SAMPLE_MEDIATIMEVALID) == 0) {
        return VFW_E_MEDIA_TIME_NOT_SET ;
    }

    if (pTimeStart == NULL ||
        pTimeEnd == NULL) {

        return E_POINTER ;
    }

    (* pTimeStart)  = m_llMediaStart ;
    (* pTimeEnd)    = m_llMediaEnd ;

    return S_OK ;
}

// Set the media times for this sample
// pTimeStart==pTimeEnd==NULL will invalidate the media time stamps in
// this sample
STDMETHODIMP
CTSMediaSample::SetMediaTime (
    IN  LONGLONG * pTimeStart,
    IN  LONGLONG * pTimeEnd
    )
{
    //  caller is explicitely clearing the media time
    if (pTimeStart == NULL) {
        //  toggle the bit OFF
        m_dwFlags &= ~SAMPLE_MEDIATIMEVALID ;
        return S_OK ;
    }

    if (pTimeEnd == NULL) {
        return E_POINTER ;
    }

    //  toggle the bit ON
    m_dwFlags |= SAMPLE_MEDIATIMEVALID ;

    //  and save the times
    m_rtStart   = (* pTimeStart) ;
    m_rtEnd     = (* pTimeEnd) ;

    return S_OK ;
}

//  -------------------------------------------------------------------
//  IMediaSample methods

// Set and get properties (IMediaSample2)
STDMETHODIMP
CTSMediaSample::GetProperties (
    IN  DWORD   cbProperties,
    OUT BYTE *  pbProperties
    )
{
    AM_SAMPLE2_PROPERTIES   Props ;
    HRESULT                 hr ;

    hr = S_OK ;

    if (cbProperties > 0) {
        if (pbProperties) {
            Props.cbData                = Min <DWORD> (cbProperties, sizeof Props) ;
            Props.dwSampleFlags         = m_dwFlags & ~SAMPLE_VALIDFLAGS ;
            Props.dwTypeSpecificFlags   = m_dwTypeSpecificFlags ;
            Props.pbBuffer              = m_pbPayload ;
            Props.cbBuffer              = m_lActual ;       //  same as actual
            Props.lActual               = m_lActual ;
            Props.tStart                = m_rtStart ;
            Props.tStop                 = m_rtEnd ;
            Props.dwStreamId            = m_dwStreamId ;

            if (m_dwFlags & AM_SAMPLE_TYPECHANGED) {
                Props.pMediaType = m_pMediaType ;
            } else {
                Props.pMediaType = NULL ;
            }

            memcpy (pbProperties, & Props, Props.cbData) ;
        }
        else {
            hr = E_POINTER ;
        }
    }

    return hr ;
}

STDMETHODIMP
CTSMediaSample::SetProperties (
    IN  DWORD           cbProperties,
    IN  const BYTE *    pbProperties
    )
{
    return E_NOTIMPL ;
}

//  ---------------------------------------------------------------------------
//      CTSMediaSamplePool
//  ---------------------------------------------------------------------------

CTSMediaSamplePool::CTSMediaSamplePool (
    IN  DWORD                       dwPoolSize,
    IN  CNetworkReceiverFilter *    pHostingFilter,
    OUT HRESULT *                   phr
    ) : m_hEvent            (NULL),
        m_dwPoolSize        (0),
        m_pHostingFilter    (pHostingFilter)
{
    CTSMediaSample *    pMS ;
    DWORD               dw ;

    ASSERT (m_pHostingFilter) ;

    InitializeListHead (& m_leMSPool) ;
    InitializeCriticalSection (& m_crt) ;

    ASSERT (dwPoolSize > 0) ;
    m_hEvent = CreateEvent (NULL, TRUE, TRUE, NULL) ;
    if (m_hEvent == NULL) {
        dw = GetLastError () ;
        (* phr) = HRESULT_FROM_WIN32 (dw) ;
        return ;
    }

    for (m_dwPoolSize = 0; m_dwPoolSize < dwPoolSize; m_dwPoolSize++) {
        pMS = new CTSMediaSample (this) ;
        if (pMS == NULL) {
            (* phr) = E_OUTOFMEMORY ;
            return ;
        }

        InsertHeadList (& m_leMSPool, & pMS -> m_ListEntry) ;
    }

    ASSERT (m_dwPoolSize > 0) ;
}

CTSMediaSamplePool::~CTSMediaSamplePool (
    )
{
    DWORD i ;
    LIST_ENTRY *        pListEntry ;
    CTSMediaSample *    pMS ;

    for (i = 0; i < m_dwPoolSize; i++) {
        ASSERT (!IsListEmpty (& m_leMSPool)) ;
        pListEntry = RemoveHeadList (& m_leMSPool) ;
        pMS = CONTAINING_RECORD (pListEntry, CTSMediaSample, m_ListEntry) ;

        delete pMS ;
    }

    ASSERT (IsListEmpty (& m_leMSPool)) ;

    DeleteCriticalSection (& m_crt) ;
}

void
CTSMediaSamplePool::RecycleMS (
    IN  CTSMediaSample * pMS
    )
{
    ASSERT (pMS) ;

    Lock_ () ;

    //  always signal the event
    SetEvent (m_hEvent) ;
    InsertHeadList (& m_leMSPool, & pMS -> m_ListEntry) ;

    //  media sample's ref to the filter
    m_pHostingFilter -> Release () ;

    Unlock_ () ;
}

HRESULT
CTSMediaSamplePool::GetMediaSample_ (
    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,
    OUT IMediaSample2 **    ppMS
    )
{
    CTSMediaSample *    pTSMS ;
    LIST_ENTRY *        pListEntry ;

    ASSERT (pllMediaStart) ;
    ASSERT (pllMediaEnd) ;
    ASSERT (prtStart) ;
    ASSERT (prtEnd) ;

    Lock_ () ;

    //  while the list is empty, non-signal the event and wait for a media
    //  sample
    while (IsListEmpty (& m_leMSPool)) {
        //  media sample list is empty; setup to wait

        //  non-signal the event
        ResetEvent (m_hEvent) ;

        //  release the lock and wait
        Unlock_ () ;
        WaitForSingleObject (m_hEvent, INFINITE) ;

        //  event has been signaled; reaquire the lock
        Lock_ () ;
    }

    //  remove the head of the media sample list
    pListEntry = RemoveHeadList (& m_leMSPool) ;
    pTSMS = CONTAINING_RECORD (pListEntry, CTSMediaSample, m_ListEntry) ;

    //  media sample's ref to the filter (so the filter does not get deleted
    //  while media samples are outstanding)
    m_pHostingFilter -> AddRef () ;

    //  we have the media sample and have addref'd the filter, so we can
    //   now release the lock
    Unlock_ () ;

    //  set the caller's ref
    ASSERT (pTSMS) ;
    pTSMS -> AddRef () ;

    //  assert we're within the bounds of the io block
    ASSERT (pBuffer -> GetBuffer () <= pbPayload &&
            pbPayload + iPayloadLength <= pBuffer -> GetBuffer () + pBuffer -> GetBufferLength ()) ;

    //  init the media sample wrapper
    pTSMS -> Init (
                pBuffer,
                pbPayload,
                iPayloadLength,
                pllMediaStart,
                pllMediaEnd,
                prtStart,
                prtEnd,
                dwMediaSampleFlags
                ) ;

    //  set the outgoing parameter
    (* ppMS) = pTSMS ;

    return S_OK ;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -