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

📄 splitter.cpp

📁 T264是中国的视频编码自由组织合力开发的264编解码程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//==========================================================================;////  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR//  PURPOSE.////  Copyright (c) 1996 - 1997  Microsoft Corporation.  All Rights Reserved.////--------------------------------------------------------------------------;#include "stdafx.h"#include <streams.h>#include "pullpin.h"#include "alloc.h"#include "splitter.h"/*  Ignore warnings about this pointers being used in member initialization    lists*/#pragma warning(disable:4355)/*  Splitter output pin methds *//*  -- Constructor -- */CSplitterOutputPin::CSplitterOutputPin(        CBaseSplitterFilter *pFilter,        HRESULT *phr,        LPCWSTR pName) :    CBaseOutputPin(        NAME("CSplitterOutputPin"),        pFilter,        &pFilter->m_csFilter,        phr,        pName),    m_Notify(this),    m_bDiscontinuity(FALSE),    m_pOutputQueue(NULL),    m_lTypes(NAME("CSplitterFilter::m_lTypes")){}CSplitterOutputPin::~CSplitterOutputPin(){    while (m_lTypes.GetCount() != 0) {        delete m_lTypes.RemoveHead();    }}/* Override revert to normal ref counting   These pins cannot be finally Release()'d while the input pin is   connected */STDMETHODIMP_(ULONG)CSplitterOutputPin::NonDelegatingAddRef(){    return CUnknown::NonDelegatingAddRef();}/* Override to do normal ref counting */STDMETHODIMP_(ULONG)CSplitterOutputPin::NonDelegatingRelease(){    return CUnknown::NonDelegatingRelease();}STDMETHODIMP CSplitterOutputPin::Notify(IBaseFilter* pSender, Quality q){
    return S_OK;
}// override this to set the buffer size and count. Return an error// if the size/count is not to your liking.HRESULT CSplitterOutputPin::DecideBufferSize(    IMemAllocator * pAlloc,    ALLOCATOR_PROPERTIES * pProp){    pProp->cBuffers = 100;    pProp->cbBuffer = 65536;            /* Don't care about size */    pProp->cbAlign = 1;    pProp->cbPrefix = 0;    ALLOCATOR_PROPERTIES propActual;    return pAlloc->SetProperties(pProp, &propActual);}////  Override DecideAllocator because we insist on our own allocator since//  it's 0 cost in terms of bytes//HRESULT CSplitterOutputPin::DecideAllocator(    IMemInputPin *pPin,    IMemAllocator **ppAlloc){    HRESULT hr = InitAllocator(ppAlloc);    if (SUCCEEDED(hr)) {        ALLOCATOR_PROPERTIES propRequest;        ZeroMemory(&propRequest, sizeof(propRequest));        hr = DecideBufferSize(*ppAlloc, &propRequest);        if (SUCCEEDED(hr)) {            // tell downstream pins that modification            // in-place is not permitted            hr = pPin->NotifyAllocator(*ppAlloc, TRUE);            if (SUCCEEDED(hr)) {                return NOERROR;            }        }    }    /* Likewise we may not have an interface to release */    if (*ppAlloc) {        (*ppAlloc)->Release();        *ppAlloc = NULL;    }    return hr;}// override this to control the connection// We use the subsample allocator derived from the input pin's allocatorHRESULT CSplitterOutputPin::InitAllocator(IMemAllocator **ppAlloc){    ASSERT(m_pAllocator == NULL);    HRESULT hr = NOERROR;    *ppAlloc = new CSubAllocator(NULL, &hr, Filter()->Allocator());    if (*ppAlloc == NULL) {        return E_OUTOFMEMORY;    }    if (FAILED(hr)) {        delete *ppAlloc;        *ppAlloc = NULL;        return hr;    }    /* Get a reference counted IID_IMemAllocator interface */    (*ppAlloc)->AddRef();    return NOERROR;}//  Check if we accept a media type - only accept 1 for nowHRESULT CSplitterOutputPin::CheckMediaType(const CMediaType *pmt){    POSITION pos = m_lTypes.GetHeadPosition();    while (pos) {        CMediaType *pmtList = m_lTypes.GetNext(pos);        if (*pmtList == *pmt) {            return S_OK;        }    }    return S_FALSE;}// returns the preferred formats for a pinHRESULT CSplitterOutputPin::GetMediaType(    int iPosition,    CMediaType *pMediaType){    POSITION pos = m_lTypes.GetHeadPosition();    while (pos) {        CMediaType *pmtList = m_lTypes.GetNext(pos);        if (iPosition-- == 0) {            *pMediaType = *pmtList;            return S_OK;        }    }    return VFW_S_NO_MORE_ITEMS;}/*  Add a media type that's supported */HRESULT CSplitterOutputPin::AddMediaType(    CMediaType const *pmt){    CMediaType *pmtNew = new CMediaType(*pmt);    if (pmtNew) {        if (m_lTypes.AddTail(pmtNew)) {            return S_OK;        }    }    delete pmtNew;    return E_OUTOFMEMORY;}/*  Output pin - Deliver a sample */HRESULT CSplitterOutputPin::SendSample(    const BYTE * pbData,    LONG lData,    REFERENCE_TIME rtStart,    BOOL bSync){    /*  Get a sample from the allocator */    if (!IsConnected()) {        return S_FALSE;    }    CMediaSample *pSample = Allocator()->GetSample((PBYTE)pbData, lData);    ASSERT(pSample != NULL);    if (bSync) {        REFERENCE_TIME rtStop = rtStart + 1;        pSample->SetTime(&rtStart, &rtStop);        /*  Allow for some decoders that only take not of sync points */        pSample->SetSyncPoint(TRUE);    }    /*  First send newsegment etc if discontinuity */    if (m_bDiscontinuity) {        m_bDiscontinuity = FALSE;        pSample->SetDiscontinuity(TRUE);        /*  HACK - fix this for seeking */        m_pOutputQueue->NewSegment(0, 0x7F00000000000000, 1.0);    }    /*  Output queue will release the sample */    return m_pOutputQueue->Receive(pSample);}/*  Base splitter class methods *//* -- Constructor -- */CBaseSplitterFilter::CBaseSplitterFilter(    TCHAR *pName,    LPUNKNOWN pUnk,    REFCLSID rclsid,    HRESULT *phr) :    CBaseFilter(pName, pUnk, &m_csFilter, rclsid, phr),    m_OutputPins(NAME("CBaseSplitterFilter::m_OutputPins")),    m_Notify(this),    m_pInput(NULL),    m_pParser(NULL){}/* -- Destructor -- */CBaseSplitterFilter::~CBaseSplitterFilter(){    ASSERT(m_State == State_Stopped);    /* -- Destroy all pins */    DestroyInputPin();    DestroyOutputPins();}////  Override Pause() so we can prevent the input pin from starting//  the puller before we're ready (ie have exited stopped state)////  Starting the puller in Active() caused a hole where the first//  samples could be rejected becase we seemed to be in 'stopped'//  state//STDMETHODIMPCBaseSplitterFilter::Pause(){    CAutoLock lockFilter(&m_csFilter);    if (m_State == State_Stopped) {        // and do the normal inactive processing        POSITION pos = m_OutputPins.GetHeadPosition();        while (pos) {            CSplitterOutputPin *pPin = m_OutputPins.GetNext(pos);            if (pPin->IsConnected()) {                pPin->Active();            }        }        CAutoLock lockStreaming(&m_csStream);        //  Activate our input pin only if we're connected        if (m_pInput->IsConnected()) {            m_pInput->Active();        }        m_State = State_Paused;        //  Initialize our state        ResetAllocatorAndParser();    } else {        m_State = State_Paused;    }    return S_OK;}/*  Stop the filter    We override this for efficiency and so that we can manage the    locking correctly*/STDMETHODIMP CBaseSplitterFilter::Stop(){    // must get this one first - it serializes state changes    CAutoLock lockFilter(&m_csFilter);    if (m_State == State_Stopped) {        return NOERROR;    }    // decommit the input pin or we can deadlock    if (m_pInput != NULL) {        m_pInput->Inactive();    }    // now hold the Receive critsec to prevent further Receive and EOS calls,    CAutoLock lockStreaming(&m_csStream);    // and do the normal inactive processing    POSITION pos = m_OutputPins.GetHeadPosition();    while (pos) {        CSplitterOutputPin *pPin = m_OutputPins.GetNext(pos);        if (pPin->IsConnected()) {            pPin->Inactive();        }    }    ResetAllocatorAndParser();    m_State = State_Stopped;    return S_OK;}/*  -- Return number of pins */int CBaseSplitterFilter::GetPinCount(){    CAutoLock lck(&m_csPins);    return (m_pInput != NULL ? 1 : 0) +           m_OutputPins.GetCount();}

⌨️ 快捷键说明

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