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

📄 transip.cpp

📁 用DirectX制作高级动画-[Advanced.Animation.with.DirectX]
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Implements the CTransInPlaceInputPin class
// =================================================================


// constructor

CTransInPlaceInputPin::CTransInPlaceInputPin
    ( TCHAR               *pObjectName
    , CTransInPlaceFilter *pFilter
    , HRESULT             *phr
    , LPCWSTR              pName
    )
    : CTransformInputPin(pObjectName,
                         pFilter,
                         phr,
                         pName)
    , m_bReadOnly(FALSE)
    , m_pTIPFilter(pFilter)
{
    DbgLog((LOG_TRACE, 2
           , TEXT("CTransInPlaceInputPin::CTransInPlaceInputPin")));

} // 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);

    HRESULT hr;

    if ( m_pTIPFilter->m_pOutput->IsConnected() ) {
        //  Store the allocator we got
        hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()
                                        ->GetAllocator( ppAllocator );
        if (SUCCEEDED(hr)) {
            m_pTIPFilter->OutputPin()->SetAllocator( *ppAllocator );
        }
    }
    else {
        //  Help upstream filter (eg TIP filter which is having to do a copy)
        //  by providing a temp allocator here - we'll never use
        //  this allocator because when our output is connected we'll
        //  reconnect this pin
        hr = CTransformInputPin::GetAllocator( ppAllocator );
    }
    return hr;

} // GetAllocator



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


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

    CAutoLock cObjectLock(m_pLock);

    m_bReadOnly = bReadOnly;
    //  If we modify data then don't accept the allocator if it's
    //  the same as the output pin's allocator

    //  If our output is not connected just accept the allocator
    //  We're never going to use this allocator because when our
    //  output pin is connected we'll reconnect this pin
    if (!m_pTIPFilter->OutputPin()->IsConnected()) {
        return CTransformInputPin::NotifyAllocator(pAllocator, bReadOnly);
    }

    //  If the allocator is read-only and we're modifying data
    //  and the allocator is the same as the output pin's
    //  then reject
    if (bReadOnly && m_pTIPFilter->m_bModifiesData) {
        IMemAllocator *pOutputAllocator =
            m_pTIPFilter->OutputPin()->PeekAllocator();

        //  Make sure we have an output allocator
        if (pOutputAllocator == NULL) {
            hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()->
                                      GetAllocator(&pOutputAllocator);
            if(FAILED(hr)) {
                hr = CreateMemoryAllocator(&pOutputAllocator);
            }
            if (SUCCEEDED(hr)) {
                m_pTIPFilter->OutputPin()->SetAllocator(pOutputAllocator);
                pOutputAllocator->Release();
            }
        }
        if (pAllocator == pOutputAllocator) {
            hr = E_FAIL;
        } else if(SUCCEEDED(hr)) {
            //  Must copy so set the allocator properties on the output
            ALLOCATOR_PROPERTIES Props, Actual;
            hr = pAllocator->GetProperties(&Props);
            if (SUCCEEDED(hr)) {
                hr = pOutputAllocator->SetProperties(&Props, &Actual);
            }
            if (SUCCEEDED(hr)) {
                if (  (Props.cBuffers > Actual.cBuffers)
                   || (Props.cbBuffer > Actual.cbBuffer)
                   || (Props.cbAlign  > Actual.cbAlign)
                   ) {
                    hr =  E_FAIL;
                }
            }

            //  Set the allocator on the output pin
            if (SUCCEEDED(hr)) {
                hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()
                                       ->NotifyAllocator( pOutputAllocator, FALSE );
            }
        }
    } else {
        hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()
                                   ->NotifyAllocator( pAllocator, bReadOnly );
        if (SUCCEEDED(hr)) {
            m_pTIPFilter->OutputPin()->SetAllocator( pAllocator );
        }
    }

    if (SUCCEEDED(hr)) {

        // 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
    }

    return hr;

} // 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


// CTransInPlaceInputPin::CompleteConnect() calls CBaseInputPin::CompleteConnect()
// and then calls CTransInPlaceFilter::CompleteConnect().  It does this because 
// CTransInPlaceFilter::CompleteConnect() can reconnect a pin and we do not
// want to reconnect a pin if CBaseInputPin::CompleteConnect() fails.
HRESULT
CTransInPlaceInputPin::CompleteConnect(IPin *pReceivePin)
{
    HRESULT hr = CBaseInputPin::CompleteConnect(pReceivePin);
    if (FAILED(hr)) {
        return hr;
    }

    return m_pTransformFilter->CompleteConnect(PINDIR_INPUT,pReceivePin);
} // CompleteConnect


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


// constructor

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

} // 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 )
{
    // Don't accept any output pin type changes if we're copying
    // between allocators - it's too late to change the input
    // allocator size.
    if (m_pTIPFilter->UsingDifferentAllocators() && !m_pFilter->IsStopped()) {
        if (*pmt == m_mt) {
            return S_OK;
        } else {
            return VFW_E_TYPE_NOT_ACCEPTED;
        }
    }

    // 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


/* Save the allocator pointer in the output pin
*/
void
CTransInPlaceOutputPin::SetAllocator(IMemAllocator * pAllocator)
{
    pAllocator->AddRef();
    if (m_pAllocator) {
        m_pAllocator->Release();
    }
    m_pAllocator = pAllocator;
} // SetAllocator


// CTransInPlaceOutputPin::CompleteConnect() calls CBaseOutputPin::CompleteConnect()
// and then calls CTransInPlaceFilter::CompleteConnect().  It does this because 
// CTransInPlaceFilter::CompleteConnect() can reconnect a pin and we do not want to 
// reconnect a pin if CBaseOutputPin::CompleteConnect() fails.  
// CBaseOutputPin::CompleteConnect() often fails when our output pin is being connected 
// to the Video Mixing Renderer.
HRESULT
CTransInPlaceOutputPin::CompleteConnect(IPin *pReceivePin)
{
    HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin);
    if (FAILED(hr)) {
        return hr;
    }

    return m_pTransformFilter->CompleteConnect(PINDIR_OUTPUT,pReceivePin);
} // CompleteConnect

⌨️ 快捷键说明

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