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

📄 transip.cpp

📁 basic class basic classbasic class
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    DbgLog((LOG_TRACE, 2
           , TEXT("CTransInPlaceInputPin::CTransInPlaceInputPin")));
    m_pTIPFilter = pFilter;

} // constructor


// =================================================================
// Implements IMemInputPin interface
// =================================================================


// If the downstream filter has one then offer that (even if our own output
// pin is not using it yet.  If the upstream filter chooses it then we will
// tell our output pin to ReceiveAllocator).
// Else if our output pin is using an allocator then offer that.
//     ( This could mean offering the upstream filter his own allocator,
//       it could mean offerring our own
//     ) or it could mean offering the one from downstream
// Else fail to offer any allocator at all.

STDMETHODIMP CTransInPlaceInputPin::GetAllocator(IMemAllocator ** ppAllocator)
{
    CheckPointer(ppAllocator,E_POINTER);
    ValidateReadWritePtr(ppAllocator,sizeof(IMemAllocator *));
    CAutoLock cObjectLock(m_pLock);

    if ( m_pTIPFilter->m_pOutput->IsConnected() ){
        HRESULT hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()
                                               ->GetAllocator( ppAllocator );
        if( SUCCEEDED( hr ) ){
            // the downstream GetAllocator will have done AddRef on it
            return hr;
        }
        else {
            *ppAllocator = m_pTIPFilter->OutputPin()->PeekAllocator();
            (*ppAllocator)->AddRef();
            return S_OK;
        }

    }

    return VFW_E_NO_ALLOCATOR;

} // GetAllocator



/* Get told which allocator the upstream output pin is actually going to use */

STDMETHODIMP
CTransInPlaceInputPin::NotifyAllocator(
    IMemAllocator * pAllocator,
    BOOL bReadOnly)
{
    HRESULT hr;
    CheckPointer(pAllocator,E_POINTER);
    ValidateReadPtr(pAllocator,sizeof(IMemAllocator));

    m_bReadOnly = bReadOnly;
    // we are an in-place transform.  We scribble on the buffer.
    // But if it's ReadOnly we're going to have to copy it first.

    CAutoLock cObjectLock(m_pLock);

    // It's possible that the old and the new are the same thing.
    // AddRef before release ensures that we don't unload it.
    pAllocator->AddRef();

    if( m_pAllocator != NULL )
        m_pAllocator->Release();

    m_pAllocator = pAllocator;    // We have an allocator for the input pin

    // Propagate the decision downstream - do this always, even if it's
    // a read-only allocator.  The Receive function will take what it can.
    if ( m_pTIPFilter->OutputPin()->IsConnected() ) {
        hr = m_pTIPFilter->OutputPin()->ReceiveAllocator(pAllocator, bReadOnly);
        if (FAILED(hr)) {
            // The output connection would be broken by this input connection
            // so refuse it!
            return hr;
        }
    }

    return NOERROR;

} // NotifyAllocator


// EnumMediaTypes
// - pass through to our downstream filter
STDMETHODIMP CTransInPlaceInputPin::EnumMediaTypes( IEnumMediaTypes **ppEnum )
{
    // Can only pass through if connected
    if( !m_pTIPFilter->m_pOutput->IsConnected() )
        return VFW_E_NOT_CONNECTED;

    return m_pTIPFilter->m_pOutput->GetConnected()->EnumMediaTypes( ppEnum );

} // EnumMediaTypes


// CheckMediaType
// - agree to anything if not connected,
// otherwise pass through to the downstream filter.
// This assumes that the filter does not change the media type.

HRESULT CTransInPlaceInputPin::CheckMediaType(const CMediaType *pmt )
{
    HRESULT hr = m_pTIPFilter->CheckInputType(pmt);
    if (hr!=S_OK) return hr;

    if( m_pTIPFilter->m_pOutput->IsConnected() )
        return m_pTIPFilter->m_pOutput->GetConnected()->QueryAccept( pmt );
    else
        return S_OK;

} // CheckMediaType


// If upstream asks us what our requirements are, we will try to ask downstream
// if that doesn't work, we'll just take the defaults.
STDMETHODIMP
CTransInPlaceInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps)
{

    if( m_pTIPFilter->m_pOutput->IsConnected() )
        return m_pTIPFilter->OutputPin()
               ->ConnectedIMemInputPin()->GetAllocatorRequirements( pProps );
    else
        return E_NOTIMPL;

} // GetAllocatorRequirements



// =================================================================
// Implements the CTransInPlaceOutputPin class
// =================================================================


// constructor

CTransInPlaceOutputPin::CTransInPlaceOutputPin(
    TCHAR *pObjectName,
    CTransInPlaceFilter *pFilter,
    HRESULT * phr,
    LPCWSTR pPinName)
    : CTransformOutputPin( pObjectName
                         , pFilter
                         , phr
                         , pPinName)
{
    DbgLog(( LOG_TRACE, 2
           , TEXT("CTransInPlaceOutputPin::CTransInPlaceOutputPin")));
    m_pTIPFilter = pFilter;

} // constructor


// EnumMediaTypes
// - pass through to our upstream filter
STDMETHODIMP CTransInPlaceOutputPin::EnumMediaTypes( IEnumMediaTypes **ppEnum )
{
    // Can only pass through if connected.
    if( ! m_pTIPFilter->m_pInput->IsConnected() )
        return VFW_E_NOT_CONNECTED;

    return m_pTIPFilter->m_pInput->GetConnected()->EnumMediaTypes( ppEnum );

} // EnumMediaTypes



// CheckMediaType
// - agree to anything if not connected,
// otherwise pass through to the upstream filter.

HRESULT CTransInPlaceOutputPin::CheckMediaType(const CMediaType *pmt )
{

    // Assumes the type does not change.  That's why we're calling
    // CheckINPUTType here on the OUTPUT pin.
    HRESULT hr = m_pTIPFilter->CheckInputType(pmt);
    if (hr!=S_OK) return hr;

    if( m_pTIPFilter->m_pInput->IsConnected() )
        return m_pTIPFilter->m_pInput->GetConnected()->QueryAccept( pmt );
    else
        return S_OK;

} //CheckMediaType


// Decide on an allocator, override this if you want to use your own allocator
// Override DecideBufferSize to call SetProperties.
// NOTE this is called during Connect() which
// therefore looks after grabbing and locking the object's critical section
//
// pPin is our downstream peer
// ppAlloc is where we return the allocator (Note: if called from filter.cpp in
// the usual way this is in fact a pointer to our own output pin's m_pAllocator)
//
HRESULT
CTransInPlaceOutputPin::DecideAllocator(IMemInputPin *pPin, IMemAllocator **ppAlloc)
{
    // Note that *ppAlloc is almost certainly identical to m_Allocator

    HRESULT hr = NOERROR;

    // If our input pin has an allocator and it's read/write then we use it.
    // Failing that we try to get one from downstream.
    *ppAlloc = NULL;

    bool fNeedToConfigureAllocator = false;

    if (m_pTIPFilter->InputPin()) {
        if (!m_pTIPFilter->InputPin()->ReadOnly()) {
            *ppAlloc = m_pTIPFilter->InputPin()->PeekAllocator();
        }
    }


    if (*ppAlloc!=NULL) {
        // don't need to configure allocator -- upstream filter has
        // already configured it
        (*ppAlloc)->AddRef();
    } else {
        hr = VFW_E_NO_ALLOCATOR;
        if ( IsConnected() ) {
            // Get an addreffed allocator from the downstream input pin.
            hr = m_pInputPin->GetAllocator( ppAlloc );
            fNeedToConfigureAllocator = true;
        }
    }


    if (*ppAlloc==NULL) {
        // Can't get one from upstream or downstream, so must use our own.

        hr = InitAllocator(ppAlloc);
        fNeedToConfigureAllocator = true;
    }

    if(FAILED(hr))
        return hr;

    ASSERT( *ppAlloc != NULL );

    if (fNeedToConfigureAllocator) {

        ALLOCATOR_PROPERTIES prop;
        ZeroMemory(&prop, sizeof(prop));

        // Try to get requirements from downstream
        pPin->GetAllocatorRequirements(&prop);

        // if he doesn't care about alignment, then set it to 1
        if (prop.cbAlign == 0) {
            prop.cbAlign = 1;
        }

        hr = DecideBufferSize(*ppAlloc, &prop);

        if (FAILED(hr)) {
            (*ppAlloc)->Release();
            *ppAlloc = NULL;
        }
    }    

    // Tell the downstream input pin
    return pPin->NotifyAllocator(*ppAlloc, FALSE);

} // DecideAllocator


/* Receive notifications from our own input pin as to which allocator we
   are actually going to use.  Only call if we are connected downstream.
   Propagate the choice to any connected downstream input pin.
*/
HRESULT
CTransInPlaceOutputPin::ReceiveAllocator(IMemAllocator * pAllocator, BOOL bReadOnly)
{
    ASSERT( IsConnected() );
    ALLOCATOR_PROPERTIES Props, Actual;

    if (bReadOnly) {

        // We cannot use a read-only allocator, but we must check that the allocator
        // we have matches the properties that we need.

        HRESULT hr;
        hr = pAllocator->GetProperties(&Props);
        if (FAILED(hr)) {
            return hr;
        }
        hr = m_pAllocator->SetProperties(&Props, &Actual);
        if (FAILED(hr)) {
            return hr;
        }
        if (  (Props.cBuffers > Actual.cBuffers)
           || (Props.cbBuffer > Actual.cbBuffer)
           || (Props.cbAlign  > Actual.cbAlign)
           ) {
            return E_FAIL;
        }
        return S_OK;

    } else {

        // Propagate the allocator.
        // It's possible that the old and the new are the same thing.
        // AddRef before release ensures that we don't unload it.
        pAllocator->AddRef();
        if (m_pAllocator != NULL)
             m_pAllocator->Release();

        m_pAllocator = pAllocator;

        // Propagate the allocator downstream
        return m_pInputPin->NotifyAllocator( pAllocator, FALSE );
    }


} // receiveAllocator

⌨️ 快捷键说明

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