//------------------------------------------------------------------------------
// File: AMFilter.cpp
//
// Desc: DirectShow base classes - implements class hierarchy for streams
//       architecture.
//
// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------


//=====================================================================
//=====================================================================
// The following classes are declared in this header:
//
//
// CBaseMediaFilter            Basic IMediaFilter support (abstract class)
// CBaseFilter                 Support for IBaseFilter (incl. IMediaFilter)
// CEnumPins                   Enumerate input and output pins
// CEnumMediaTypes             Enumerate the preferred pin formats
// CBasePin                    Abstract base class for IPin interface
//    CBaseOutputPin           Adds data provider member functions
//    CBaseInputPin            Implements IMemInputPin interface
// CMediaSample                Basic transport unit for IMemInputPin
// CBaseAllocator              General list guff for most allocators
//    CMemAllocator            Implements memory buffer allocation
//
//=====================================================================
//=====================================================================

#include <streams.h>
#include <strsafe.h>

#ifdef DXMPERF
#include "dxmperf.h"
#endif // DXMPERF


//=====================================================================
// Helpers
//=====================================================================
STDAPI CreateMemoryAllocator(__deref_out IMemAllocator **ppAllocator)
{
    return CoCreateInstance(CLSID_MemoryAllocator,
                            0,
                            CLSCTX_INPROC_SERVER,
                            IID_IMemAllocator,
                            (void **)ppAllocator);
}

//  Put this one here rather than in ctlutil.cpp to avoid linking
//  anything brought in by ctlutil.cpp
STDAPI CreatePosPassThru(
    __in_opt LPUNKNOWN pAgg,
    BOOL bRenderer,
    IPin *pPin,
    __deref_out IUnknown **ppPassThru
)
{
    *ppPassThru = NULL;
    IUnknown *pUnkSeek;
    HRESULT hr = CoCreateInstance(CLSID_SeekingPassThru,
                                  pAgg,
                                  CLSCTX_INPROC_SERVER,
                                  IID_IUnknown,
                                  (void **)&pUnkSeek
                                 );
    if (FAILED(hr)) {
        return hr;
    }

    ISeekingPassThru *pPassThru;
    hr = pUnkSeek->QueryInterface(IID_ISeekingPassThru, (void**)&pPassThru);
    if (FAILED(hr)) {
        pUnkSeek->Release();
        return hr;
    }
    hr = pPassThru->Init(bRenderer, pPin);
    pPassThru->Release();
    if (FAILED(hr)) {
        pUnkSeek->Release();
        return hr;
    }
    *ppPassThru = pUnkSeek;
    return S_OK;
}



#define CONNECT_TRACE_LEVEL 3

//=====================================================================
//=====================================================================
// Implements CBaseMediaFilter
//=====================================================================
//=====================================================================


/* Constructor */

CBaseMediaFilter::CBaseMediaFilter(__in_opt LPCTSTR pName,
                   __inout_opt LPUNKNOWN    pUnk,
                   __in CCritSec *pLock,
                   REFCLSID clsid) :
    CUnknown(pName, pUnk),
    m_pLock(pLock),
    m_clsid(clsid),
    m_State(State_Stopped),
    m_pClock(NULL)
{
}


/* Destructor */

CBaseMediaFilter::~CBaseMediaFilter()
{
    // must be stopped, but can't call Stop here since
    // our critsec has been destroyed.

    /* Release any clock we were using */

    if (m_pClock) {
        m_pClock->Release();
        m_pClock = NULL;
    }
}


/* Override this to say what interfaces we support and where */

STDMETHODIMP
CBaseMediaFilter::NonDelegatingQueryInterface(
    REFIID riid,
    __deref_out void ** ppv)
{
    if (riid == IID_IMediaFilter) {
        return GetInterface((IMediaFilter *) this, ppv);
    } else if (riid == IID_IPersist) {
        return GetInterface((IPersist *) this, ppv);
    } else {
        return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}

/* Return the filter's clsid */
STDMETHODIMP
CBaseMediaFilter::GetClassID(__out CLSID *pClsID)
{
    CheckPointer(pClsID,E_POINTER);
    ValidateReadWritePtr(pClsID,sizeof(CLSID));
    *pClsID = m_clsid;
    return NOERROR;
}

/* Override this if your state changes are not done synchronously */

STDMETHODIMP
CBaseMediaFilter::GetState(DWORD dwMSecs, __out FILTER_STATE *State)
{
    UNREFERENCED_PARAMETER(dwMSecs);
    CheckPointer(State,E_POINTER);
    ValidateReadWritePtr(State,sizeof(FILTER_STATE));

    *State = m_State;
    return S_OK;
}


/* Set the clock we will use for synchronisation */

STDMETHODIMP
CBaseMediaFilter::SetSyncSource(__inout_opt IReferenceClock *pClock)
{
    CAutoLock cObjectLock(m_pLock);

    // Ensure the new one does not go away - even if the same as the old
    if (pClock) {
        pClock->AddRef();
    }

    // if we have a clock, release it
    if (m_pClock) {
        m_pClock->Release();
    }

    // Set the new reference clock (might be NULL)
    // Should we query it to ensure it is a clock?  Consider for a debug build.
    m_pClock = pClock;

    return NOERROR;
}

/* Return the clock we are using for synchronisation */
STDMETHODIMP
CBaseMediaFilter::GetSyncSource(__deref_out_opt IReferenceClock **pClock)
{
    CheckPointer(pClock,E_POINTER);
    ValidateReadWritePtr(pClock,sizeof(IReferenceClock *));
    CAutoLock cObjectLock(m_pLock);

    if (m_pClock) {
        // returning an interface... addref it...
        m_pClock->AddRef();
    }
    *pClock = (IReferenceClock*)m_pClock;
    return NOERROR;
}


/* Put the filter into a stopped state */

STDMETHODIMP
CBaseMediaFilter::Stop()
{
    CAutoLock cObjectLock(m_pLock);

    m_State = State_Stopped;
    return S_OK;
}


/* Put the filter into a paused state */

STDMETHODIMP
CBaseMediaFilter::Pause()
{
    CAutoLock cObjectLock(m_pLock);

    m_State = State_Paused;
    return S_OK;
}


// Put the filter into a running state.

// The time parameter is the offset to be added to the samples'
// stream time to get the reference time at which they should be presented.
//
// you can either add these two and compare it against the reference clock,
// or you can call CBaseMediaFilter::StreamTime and compare that against
// the sample timestamp.

STDMETHODIMP
CBaseMediaFilter::Run(REFERENCE_TIME tStart)
{
    CAutoLock cObjectLock(m_pLock);

    // remember the stream time offset
    m_tStart = tStart;

    if (m_State == State_Stopped){
        HRESULT hr = Pause();

        if (FAILED(hr)) {
            return hr;
        }
    }
    m_State = State_Running;
    return S_OK;
}


//
// return the current stream time - samples with start timestamps of this
// time or before should be rendered by now
HRESULT
CBaseMediaFilter::StreamTime(CRefTime& rtStream)
{
    // Caller must lock for synchronization
    // We can't grab the filter lock because we want to be able to call
    // this from worker threads without deadlocking

    if (m_pClock == NULL) {
        return VFW_E_NO_CLOCK;
    }

    // get the current reference time
    HRESULT hr = m_pClock->GetTime((REFERENCE_TIME*)&rtStream);
    if (FAILED(hr)) {
        return hr;
    }

    // subtract the stream offset to get stream time
    rtStream -= m_tStart;

    return S_OK;
}


//=====================================================================
//=====================================================================
// Implements CBaseFilter
//=====================================================================
//=====================================================================


/* Override this to say what interfaces we support and where */

STDMETHODIMP CBaseFilter::NonDelegatingQueryInterface(REFIID riid,
                                                      __deref_out void **ppv)
{
    /* Do we have this interface */

    if (riid == IID_IBaseFilter) {
        return GetInterface((IBaseFilter *) this, ppv);
    } else if (riid == IID_IMediaFilter) {
        return GetInterface((IMediaFilter *) this, ppv);
    } else if (riid == IID_IPersist) {
        return GetInterface((IPersist *) this, ppv);
    } else if (riid == IID_IAMovieSetup) {
        return GetInterface((IAMovieSetup *) this, ppv);
    } else {
        return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}

#ifdef DEBUG
STDMETHODIMP_(ULONG) CBaseFilter::NonDelegatingRelease()
{
    if (m_cRef == 1) {
        KASSERT(m_pGraph == NULL);
    }
    return CUnknown::NonDelegatingRelease();
}
#endif


/* Constructor */

CBaseFilter::CBaseFilter(__in_opt LPCTSTR pName,
             __inout_opt LPUNKNOWN  pUnk,
             __in CCritSec   *pLock,
             REFCLSID   clsid) :
    CUnknown( pName, pUnk ),
    m_pLock(pLock),
    m_clsid(clsid),
    m_State(State_Stopped),
    m_pClock(NULL),
    m_pGraph(NULL),
    m_pSink(NULL),
    m_pName(NULL),
    m_PinVersion(1)
{
#ifdef DXMPERF
    PERFLOG_CTOR( pName ? pName : L"CBaseFilter", (IBaseFilter *) this );
#endif // DXMPERF

    ASSERT(pLock != NULL);
}

/* Passes in a redundant HRESULT argument */

CBaseFilter::CBaseFilter(__in_opt LPCTSTR pName,
                         __in_opt LPUNKNOWN  pUnk,
                         __in CCritSec  *pLock,
                         REFCLSID   clsid,
                         __inout HRESULT   *phr) :
    CUnknown( pName, pUnk ),
    m_pLock(pLock),
    m_clsid(clsid),
    m_State(State_Stopped),
    m_pClock(NULL),
    m_pGraph(NULL),
    m_pSink(NULL),
    m_pName(NULL),
    m_PinVersion(1)
{
#ifdef DXMPERF
    PERFLOG_CTOR( pName ? pName : L"CBaseFilter", (IBaseFilter *) this );
#endif // DXMPERF

    ASSERT(pLock != NULL);
    UNREFERENCED_PARAMETER(phr);
}

#ifdef UNICODE
CBaseFilter::CBaseFilter(__in_opt LPCSTR pName,
             __in_opt LPUNKNOWN  pUnk,
             __in CCritSec   *pLock,
             REFCLSID   clsid) :
    CUnknown( pName, pUnk ),
    m_pLock(pLock),
    m_clsid(clsid),
    m_State(State_Stopped),
    m_pClock(NULL),
    m_pGraph(NULL),
    m_pSink(NULL),
    m_pName(NULL),
    m_PinVersion(1)
{
#ifdef DXMPERF
    PERFLOG_CTOR( L"CBaseFilter", (IBaseFilter *) this );
#endif // DXMPERF

    ASSERT(pLock != NULL);
}
CBaseFilter::CBaseFilter(__in_opt LPCSTR pName,
                         __in_opt LPUNKNOWN  pUnk,
                         __in CCritSec  *pLock,
                         REFCLSID   clsid,
                         __inout HRESULT   *phr) :
    CUnknown( pName, pUnk ),
    m_pLock(pLock),
    m_clsid(clsid),
    m_State(State_Stopped),
    m_pClock(NULL),
    m_pGraph(NULL),
    m_pSink(NULL),
    m_pName(NULL),
    m_PinVersion(1)
{
#ifdef DXMPERF
    PERFLOG_CTOR( L"CBaseFilter", (IBaseFilter *) this );
#endif // DXMPERF

    ASSERT(pLock != NULL);
    UNREFERENCED_PARAMETER(phr);
}
#endif

/* Destructor */

CBaseFilter::~CBaseFilter()
{
#ifdef DXMPERF
    PERFLOG_DTOR( L"CBaseFilter", (IBaseFilter *) this );
#endif // DXMPERF

    // NOTE we do NOT hold references on the filtergraph for m_pGraph or m_pSink
    // When we did we had the circular reference problem.  Nothing would go away.

    delete[] m_pName;

    // must be stopped, but can't call Stop here since
    // our critsec has been destroyed.

    /* Release any clock we were using */
    if (m_pClock) {
        m_pClock->Release();
        m_pClock = NULL;
    }
}

/* Return the filter's clsid */
STDMETHODIMP
CBaseFilter::GetClassID(__out CLSID *pClsID)
{
    CheckPointer(pClsID,E_POINTER);
    ValidateReadWritePtr(pClsID,sizeof(CLSID));
    *pClsID = m_clsid;
    return NOERROR;
}

/* Override this if your state changes are not done synchronously */
STDMETHODIMP
CBaseFilter::GetState(DWORD dwMSecs, __out FILTER_STATE *State)
{
    UNREFERENCED_PARAMETER(dwMSecs);
    CheckPointer(State,E_POINTER);
    ValidateReadWritePtr(State,sizeof(FILTER_STATE));

    *State = m_State;
    return S_OK;
}


/* Set the clock we will use for synchronisation */

STDMETHODIMP
CBaseFilter::SetSyncSource(__in_opt IReferenceClock *pClock)
{
    CAutoLock cObjectLock(m_pLock);

    // Ensure the new one does not go away - even if the same as the old
    if (pClock) {
        pClock->AddRef();
    }

    // if we have a clock, release it
    if (m_pClock) {
        m_pClock->Release();
    }

    // Set the new reference clock (might be NULL)
    // Should we query it to ensure it is a clock?  Consider for a debug build.
    m_pClock = pClock;

    return NOERROR;
}

/* Return the clock we are using for synchronisation */
STDMETHODIMP
CBaseFilter::GetSyncSource(__deref_out_opt IReferenceClock **pClock)
{
    CheckPointer(pClock,E_POINTER);
    ValidateReadWritePtr(pClock,sizeof(IReferenceClock *));
    CAutoLock cObjectLock(m_pLock);

    if (m_pClock) {
        // returning an interface... addref it...
        m_pClock->AddRef();
    }
    *pClock = (IReferenceClock*)m_pClock;
    return NOERROR;
}



// override CBaseMediaFilter Stop method, to deactivate any pins this
// filter has.
STDMETHODIMP
CBaseFilter::Stop()
{
    CAutoLock cObjectLock(m_pLock);
    HRESULT hr = NOERROR;

    // notify all pins of the state change
    if (m_State != State_Stopped) {
        int cPins = GetPinCount();
        for (int c = 0; c < cPins; c++) {

            CBasePin *pPin = GetPin(c);
            if (NULL == pPin) {
                break;
            }

            // Disconnected pins are not activated - this saves pins worrying
            // about this state themselves. We ignore the return code to make
            // sure everyone is inactivated regardless. The base input pin
            // class can return an error if it has no allocator but Stop can
            // be used to resync the graph state after something has gone bad

            if (pPin->IsConnected()) {
                HRESULT hrTmp = pPin->Inactive();
                if (FAILED(hrTmp) && SUCCEEDED(hr)) {
                    hr = hrTmp;
                }
            }
        }
    }

#ifdef DXMPERF
    PERFLOG_STOP( m_pName ? m_pName : L"CBaseFilter", (IBaseFilter *) this, m_State );
#endif // DXMPERF

    m_State = State_Stopped;
    return hr;
}


// override CBaseMediaFilter Pause method to activate any pins
// this filter has (also called from Run)

STDMETHODIMP
CBaseFilter::Pause()
{
    CAutoLock cObjectLock(m_pLock);

    // notify all pins of the change to active state
    if (m_State == State_Stopped) {
        int cPins = GetPinCount();
        for (int c = 0; c < cPins; c++) {

            CBasePin *pPin = GetPin(c);
            if (NULL == pPin) {
                break;
            }

            // Disconnected pins are not activated - this saves pins
            // worrying about this state themselves

            if (pPin->IsConnected()) {
                HRESULT hr = pPin->Active();
                if (FAILED(hr)) {
                    return hr;
                }
            }
        }
    }


#ifdef DXMPERF
    PERFLOG_PAUSE( m_pName ? m_pName : L"CBaseFilter", (IBaseFilter *) this, m_State );
#endif // DXMPERF

    m_State = State_Paused;
    return S_OK;
}

// Put the filter into a running state.

// The time parameter is the offset to be added to the samples'
// stream time to get the reference time at which they should be presented.
//
// you can either add these two and compare it against the reference clock,
// or you can call CBaseFilter::StreamTime and compare that against
// the sample timestamp.

STDMETHODIMP
CBaseFilter::Run(REFERENCE_TIME tStart)
{
    CAutoLock cObjectLock(m_pLock);

    // remember the stream time offset
    m_tStart = tStart;

    if (m_State == State_Stopped){
    HRESULT hr = Pause();

    if (FAILED(hr)) {
        return hr;
    }
    }
    // notify all pins of the change to active state
    if (m_State != State_Running) {
        int cPins = GetPinCount();
        for (int c = 0; c < cPins; c++) {

            CBasePin *pPin = GetPin(c);
            if (NULL == pPin) {
                break;
            }

            // Disconnected pins are not activated - this saves pins
            // worrying about this state themselves

            if (pPin->IsConnected()) {
                HRESULT hr = pPin->Run(tStart);
                if (FAILED(hr)) {
                    return hr;
                }
            }
        }
    }

#ifdef DXMPERF
    PERFLOG_RUN( m_pName ? m_pName : L"CBaseFilter", (IBaseFilter *) this, tStart, m_State );
#endif // DXMPERF

    m_State = State_Running;
    return S_OK;
}

//
// return the current stream time - samples with start timestamps of this
// time or before should be rendered by now
HRESULT
CBaseFilter::StreamTime(CRefTime& rtStream)
{
    // Caller must lock for synchronization
    // We can't grab the filter lock because we want to be able to call
    // this from worker threads without deadlocking

    if (m_pClock == NULL) {
        return VFW_E_NO_CLOCK;
    }

    // get the current reference time
    HRESULT hr = m_pClock->GetTime((REFERENCE_TIME*)&rtStream);
    if (FAILED(hr)) {
        return hr;
    }

    // subtract the stream offset to get stream time
    rtStream -= m_tStart;

    return S_OK;
}


/* Create an enumerator for the pins attached to this filter */

STDMETHODIMP
CBaseFilter::EnumPins(__deref_out IEnumPins **ppEnum)
{
    CheckPointer(ppEnum,E_POINTER);
    ValidateReadWritePtr(ppEnum,sizeof(IEnumPins *));

    /* Create a new ref counted enumerator */

    *ppEnum = new CEnumPins(this,
                        NULL);

    return *ppEnum == NULL ? E_OUTOFMEMORY : NOERROR;
}


// default behaviour of FindPin is to assume pins are named
// by their pin names
STDMETHODIMP
CBaseFilter::FindPin(
    LPCWSTR Id,
    __deref_out IPin ** ppPin
)
{
    CheckPointer(ppPin,E_POINTER);
    ValidateReadWritePtr(ppPin,sizeof(IPin *));

    //  We're going to search the pin list so maintain integrity
    CAutoLock lck(m_pLock);
    int iCount = GetPinCount();
    for (int i = 0; i < iCount; i++) {
        CBasePin *pPin = GetPin(i);
        if (NULL == pPin) {
            break;
        }

        if (0 == lstrcmpW(pPin->Name(), Id)) {
            //  Found one that matches
            //
            //  AddRef() and return it
            *ppPin = pPin;
            pPin->AddRef();
            return S_OK;
        }
    }
    *ppPin = NULL;
    return VFW_E_NOT_FOUND;
}

/* Return information about this filter */

STDMETHODIMP
CBaseFilter::QueryFilterInfo(__out FILTER_INFO * pInfo)
{
    CheckPointer(pInfo,E_POINTER);
    ValidateReadWritePtr(pInfo,sizeof(FILTER_INFO));

    if (m_pName) {
        (void)StringCchCopyW(pInfo->achName, NUMELMS(pInfo->achName), m_pName);
    } else {
        pInfo->achName[0] = L'\0';
    }
    pInfo->pGraph = m_pGraph;
    if (m_pGraph)
        m_pGraph->AddRef();
    return NOERROR;
}


/* Provide the filter with a filter graph */

STDMETHODIMP
CBaseFilter::JoinFilterGraph(
    __inout_opt IFilterGraph * pGraph,
    __in_opt LPCWSTR pName)
{
    CAutoLock cObjectLock(m_pLock);

    // NOTE: we no longer hold references on the graph (m_pGraph, m_pSink)

    m_pGraph = pGraph;
    if (m_pGraph) {
        HRESULT hr = m_pGraph->QueryInterface(IID_IMediaEventSink,
                        (void**) &m_pSink);
        if (FAILED(hr)) {
            ASSERT(m_pSink == NULL);
        }
        else m_pSink->Release();        // we do NOT keep a reference on it.
    } else {
        // if graph pointer is null, then we should
        // also release the IMediaEventSink on the same object - we don't
        // refcount it, so just set it to null
        m_pSink = NULL;
    }


    if (m_pName) {
        delete[] m_pName;
        m_pName = NULL;
    }

    if (pName) {
        size_t namelen;
        HRESULT hr = StringCchLengthW(pName, STRSAFE_MAX_CCH, &namelen);
        if (FAILED(hr)) {
            return hr;
        }
        m_pName = new WCHAR[namelen + 1];
        if (m_pName) {
            (void)StringCchCopyW(m_pName, namelen + 1, pName);
        } else {
            return E_OUTOFMEMORY;
        }
    }

#ifdef DXMPERF
    PERFLOG_JOINGRAPH( m_pName ? m_pName : L"CBaseFilter",(IBaseFilter *) this, pGraph );
#endif // DXMPERF

    return NOERROR;
}


// return a Vendor information string. Optional - may return E_NOTIMPL.
// memory returned should be freed using CoTaskMemFree
// default implementation returns E_NOTIMPL
STDMETHODIMP
CBaseFilter::QueryVendorInfo(
    __deref_out LPWSTR* pVendorInfo)
{
    UNREFERENCED_PARAMETER(pVendorInfo);
    return E_NOTIMPL;
}


// send an event notification to the filter graph if we know about it.
// returns S_OK if delivered, S_FALSE if the filter graph does not sink
// events, or an error otherwise.
HRESULT
CBaseFilter::NotifyEvent(
    long EventCode,
    LONG_PTR EventParam1,
    LONG_PTR EventParam2)
{
    // Snapshot so we don't have to lock up
    IMediaEventSink *pSink = m_pSink;
    if (pSink) {
        if (EC_COMPLETE == EventCode) {
            EventParam2 = (LONG_PTR)(IBaseFilter*)this;
        }

        return pSink->Notify(EventCode, EventParam1, EventParam2);
    } else {
        return E_NOTIMPL;
    }
}

// Request reconnect
// pPin is the pin to reconnect
// pmt is the type to reconnect with - can be NULL
// Calls ReconnectEx on the filter graph
HRESULT
CBaseFilter::ReconnectPin(
    IPin *pPin,
    __in_opt AM_MEDIA_TYPE const *pmt
)
{
    IFilterGraph2 *pGraph2;
    if (m_pGraph != NULL) {
        HRESULT hr = m_pGraph->QueryInterface(IID_IFilterGraph2, (void **)&pGraph2);
        if (SUCCEEDED(hr)) {
            hr = pGraph2->ReconnectEx(pPin, pmt);
            pGraph2->Release();
            return hr;
        } else {
            return m_pGraph->Reconnect(pPin);
        }
    } else {
        return E_NOINTERFACE;
    }
}



/* This is the same idea as the media type version does for type enumeration
   on pins but for the list of pins available. So if the list of pins you
   provide changes dynamically then either override this virtual function
   to provide the version number, or more simply call IncrementPinVersion */

LONG CBaseFilter::GetPinVersion()
{
    return m_PinVersion;
}


/* Increment the current pin version cookie */

void CBaseFilter::IncrementPinVersion()
{
    InterlockedIncrement(&m_PinVersion);
}

/* register filter */

STDMETHODIMP CBaseFilter::Register()
{
    // get setup data, if it exists
    //
    LPAMOVIESETUP_FILTER psetupdata = GetSetupData();

    // check we've got data
    //
    if( NULL == psetupdata ) return S_FALSE;

    // init is ref counted so call just in case
    // we're being called cold.
    //
    HRESULT hr = CoInitialize( (LPVOID)NULL );
    ASSERT( SUCCEEDED(hr) );

    // get hold of IFilterMapper
    //
    IFilterMapper *pIFM;
    hr = CoCreateInstance( CLSID_FilterMapper
                             , NULL
                             , CLSCTX_INPROC_SERVER
                             , IID_IFilterMapper
                             , (void **)&pIFM       );
    if( SUCCEEDED(hr) )
    {
        hr = AMovieSetupRegisterFilter( psetupdata, pIFM, TRUE );
        pIFM->Release();
    }

    // and clear up
    //
    CoFreeUnusedLibraries();
    CoUninitialize();

    return NOERROR;
}


/* unregister filter */

STDMETHODIMP CBaseFilter::Unregister()
{
    // get setup data, if it exists
    //
    LPAMOVIESETUP_FILTER psetupdata = GetSetupData();

    // check we've got data
    //
    if( NULL == psetupdata ) return S_FALSE;

    // OLE init is ref counted so call
    // just in case we're being called cold.
    //
    HRESULT hr = CoInitialize( (LPVOID)NULL );
    ASSERT( SUCCEEDED(hr) );

    // get hold of IFilterMapper
    //
    IFilterMapper *pIFM;
    hr = CoCreateInstance( CLSID_FilterMapper
                             , NULL
                             , CLSCTX_INPROC_SERVER
                             , IID_IFilterMapper
                             , (void **)&pIFM       );
    if( SUCCEEDED(hr) )
    {
        hr = AMovieSetupRegisterFilter( psetupdata, pIFM, FALSE );

        // release interface
        //
        pIFM->Release();
    }

    // clear up
    //
    CoFreeUnusedLibraries();
    CoUninitialize();

    // handle one acceptable "error" - that
    // of filter not being registered!
    // (couldn't find a suitable #define'd
    // name for the error!)
    //
    if( 0x80070002 == hr)
      return NOERROR;
    else
      return hr;
}


//=====================================================================
//=====================================================================
// Implements CEnumPins
//=====================================================================
//=====================================================================


CEnumPins::CEnumPins(__in CBaseFilter *pFilter,
                     __in_opt CEnumPins *pEnumPins) :
    m_Position(0),
    m_PinCount(0),
    m_pFilter(pFilter),
    m_cRef(1),               // Already ref counted
    m_PinCache(NAME("Pin Cache"))
{

#ifdef DEBUG
    m_dwCookie = DbgRegisterObjectCreation("CEnumPins", 0);
#endif

    /* We must be owned by a filter derived from CBaseFilter */

    ASSERT(pFilter != NULL);

    /* Hold a reference count on our filter */
    m_pFilter->AddRef();

    /* Are we creating a new enumerator */

    if (pEnumPins == NULL) {
        m_Version = m_pFilter->GetPinVersion();
        m_PinCount = m_pFilter->GetPinCount();
    } else {
        ASSERT(m_Position <= m_PinCount);
        m_Position = pEnumPins->m_Position;
        m_PinCount = pEnumPins->m_PinCount;
        m_Version = pEnumPins->m_Version;
        m_PinCache.AddTail(&(pEnumPins->m_PinCache));
    }
}


/* Destructor releases the reference count on our filter NOTE since we hold
   a reference count on the filter who created us we know it is safe to
   release it, no access can be made to it afterwards though as we have just
   caused the last reference count to go and the object to be deleted */

CEnumPins::~CEnumPins()
{
    m_pFilter->Release();

#ifdef DEBUG
    DbgRegisterObjectDestruction(m_dwCookie);
#endif
}


/* Override this to say what interfaces we support where */

STDMETHODIMP
CEnumPins::QueryInterface(REFIID riid, __deref_out void **ppv)
{
    CheckPointer(ppv, E_POINTER);

    /* Do we have this interface */

    if (riid == IID_IEnumPins || riid == IID_IUnknown) {
        return GetInterface((IEnumPins *) this, ppv);
    } else {
        *ppv = NULL;
        return E_NOINTERFACE;
    }
}

STDMETHODIMP_(ULONG)
CEnumPins::AddRef()
{
    return InterlockedIncrement(&m_cRef);
}

STDMETHODIMP_(ULONG)
CEnumPins::Release()
{
    ULONG cRef = InterlockedDecrement(&m_cRef);
    if (cRef == 0) {
        delete this;
    }
    return cRef;
}

/* One of an enumerator's basic member functions allows us to create a cloned
   interface that initially has the same state. Since we are taking a snapshot
   of an object (current position and all) we must lock access at the start */

STDMETHODIMP 
CEnumPins::Clone(__deref_out IEnumPins **ppEnum)
{
    CheckPointer(ppEnum,E_POINTER);
    ValidateReadWritePtr(ppEnum,sizeof(IEnumPins *));
    HRESULT hr = NOERROR;

    /* Check we are still in sync with the filter */
    if (AreWeOutOfSync() == TRUE) {
        *ppEnum = NULL;
        hr =  VFW_E_ENUM_OUT_OF_SYNC;
    } else {
        *ppEnum = new CEnumPins(m_pFilter, 
                                this);
        if (*ppEnum == NULL) {
            hr = E_OUTOFMEMORY;
        }
    }
    return hr;
}


/* Return the next pin after the current position */

STDMETHODIMP
CEnumPins::Next(ULONG cPins,        // place this many pins...
        __out_ecount(cPins) IPin **ppPins,      // ...in this array
        __out_opt ULONG *pcFetched)   // actual count passed returned here
{
    CheckPointer(ppPins,E_POINTER);
    ValidateReadWritePtr(ppPins,cPins * sizeof(IPin *));

    ASSERT(ppPins);

    if (pcFetched!=NULL) {
        ValidateWritePtr(pcFetched, sizeof(ULONG));
        *pcFetched = 0;           // default unless we succeed
    }
    // now check that the parameter is valid
    else if (cPins>1) {   // pcFetched == NULL
        return E_INVALIDARG;
    }
    ULONG cFetched = 0;           // increment as we get each one.

    /* Check we are still in sync with the filter */
    if (AreWeOutOfSync() == TRUE) {
        // If we are out of sync, we should refresh the enumerator.
        // This will reset the position and update the other members, but
        // will not clear cache of pins we have already returned.
        Refresh();
    }

    /* Return each pin interface NOTE GetPin returns CBasePin * not addrefed
       so we must QI for the IPin (which increments its reference count)
       If while we are retrieving a pin from the filter an error occurs we
       assume that our internal state is stale with respect to the filter
       (for example someone has deleted a pin) so we
       return VFW_E_ENUM_OUT_OF_SYNC                            */

    while (cFetched < cPins && m_PinCount > m_Position) {

        /* Get the next pin object from the filter */

        CBasePin *pPin = m_pFilter->GetPin(m_Position++);
        if (pPin == NULL) {
            // If this happend, and it's not the first time through, then we've got a problem,
            // since we should really go back and release the iPins, which we have previously
            // AddRef'ed.
            ASSERT( cFetched==0 );
            return VFW_E_ENUM_OUT_OF_SYNC;
        }

        /* We only want to return this pin, if it is not in our cache */
        if (0 == m_PinCache.Find(pPin))
        {
            /* From the object get an IPin interface */

            *ppPins = pPin;
            pPin->AddRef();

            cFetched++;
            ppPins++;

            m_PinCache.AddTail(pPin);
        }
    }

    if (pcFetched!=NULL) {
        *pcFetched = cFetched;
    }

    return (cPins==cFetched ? NOERROR : S_FALSE);
}


/* Skip over one or more entries in the enumerator */

STDMETHODIMP
CEnumPins::Skip(ULONG cPins)
{
    /* Check we are still in sync with the filter */
    if (AreWeOutOfSync() == TRUE) {
        return VFW_E_ENUM_OUT_OF_SYNC;
    }

    /* Work out how many pins are left to skip over */
    /* We could position at the end if we are asked to skip too many... */
    /* ..which would match the base implementation for CEnumMediaTypes::Skip */

    ULONG PinsLeft = m_PinCount - m_Position;
    if (cPins > PinsLeft) {
        return S_FALSE;
    }
    m_Position += cPins;
    return NOERROR;
}


/* Set the current position back to the start */
/* Reset has 4 simple steps:
 *
 * Set position to head of list
 * Sync enumerator with object being enumerated
 * Clear the cache of pins already returned
 * return S_OK
 */

STDMETHODIMP
CEnumPins::Reset()
{
    m_Version = m_pFilter->GetPinVersion();
    m_PinCount = m_pFilter->GetPinCount();

    m_Position = 0;

    // Clear the cache
    m_PinCache.RemoveAll();

    return S_OK;
}


/* Set the current position back to the start */
/* Refresh has 3 simple steps:
 *
 * Set position to head of list
 * Sync enumerator with object being enumerated
 * return S_OK
 */

STDMETHODIMP
CEnumPins::Refresh()
{
    m_Version = m_pFilter->GetPinVersion();
    m_PinCount = m_pFilter->GetPinCount();

    m_Position = 0;
    return S_OK;
}


//=====================================================================
//=====================================================================
// Implements CEnumMediaTypes
//=====================================================================
//=====================================================================


CEnumMediaTypes::CEnumMediaTypes(__in CBasePin *pPin,
                                 __in_opt CEnumMediaTypes *pEnumMediaTypes) :
    m_Position(0),
    m_pPin(pPin),
    m_cRef(1)
{

#ifdef DEBUG
    m_dwCookie = DbgRegisterObjectCreation("CEnumMediaTypes", 0);
#endif

    /* We must be owned by a pin derived from CBasePin */

    ASSERT(pPin != NULL);

    /* Hold a reference count on our pin */
    m_pPin->AddRef();

    /* Are we creating a new enumerator */

    if (pEnumMediaTypes == NULL) {
        m_Version = m_pPin->GetMediaTypeVersion();
        return;
    }

    m_Position = pEnumMediaTypes->m_Position;
    m_Version = pEnumMediaTypes->m_Version;
}


/* Destructor releases the reference count on our base pin. NOTE since we hold
   a reference count on the pin who created us we know it is safe to release
   it, no access can be made to it afterwards though as we might have just
   caused the last reference count to go and the object to be deleted */

CEnumMediaTypes::~CEnumMediaTypes()
{
#ifdef DEBUG
    DbgRegisterObjectDestruction(m_dwCookie);
#endif
    m_pPin->Release();
}


/* Override this to say what interfaces we support where */

STDMETHODIMP
CEnumMediaTypes::QueryInterface(REFIID riid, __deref_out void **ppv)
{
    CheckPointer(ppv, E_POINTER);

    /* Do we have this interface */

    if (riid == IID_IEnumMediaTypes || riid == IID_IUnknown) {
        return GetInterface((IEnumMediaTypes *) this, ppv);
    } else {
        *ppv = NULL;
        return E_NOINTERFACE;
    }
}

STDMETHODIMP_(ULONG)
CEnumMediaTypes::AddRef()
{
    return InterlockedIncrement(&m_cRef);
}

STDMETHODIMP_(ULONG)
CEnumMediaTypes::Release()
{
    ULONG cRef = InterlockedDecrement(&m_cRef);
    if (cRef == 0) {
        delete this;
    }
    return cRef;
}

/* One of an enumerator's basic member functions allows us to create a cloned
   interface that initially has the same state. Since we are taking a snapshot
   of an object (current position and all) we must lock access at the start */

STDMETHODIMP
CEnumMediaTypes::Clone(__deref_out IEnumMediaTypes **ppEnum)
{
    CheckPointer(ppEnum,E_POINTER);
    ValidateReadWritePtr(ppEnum,sizeof(IEnumMediaTypes *));
    HRESULT hr = NOERROR;

    /* Check we are still in sync with the pin */
    if (AreWeOutOfSync() == TRUE) {
        *ppEnum = NULL;
        hr = VFW_E_ENUM_OUT_OF_SYNC;
    } else {

        *ppEnum = new CEnumMediaTypes(m_pPin,
                                      this);

        if (*ppEnum == NULL) {
            hr =  E_OUTOFMEMORY;
        }
    }
    return hr;
}


/* Enumerate the next pin(s) after the current position. The client using this
   interface passes in a pointer to an array of pointers each of which will
   be filled in with a pointer to a fully initialised media type format
   Return NOERROR if it all works,
          S_FALSE if fewer than cMediaTypes were enumerated.
          VFW_E_ENUM_OUT_OF_SYNC if the enumerator has been broken by
                                 state changes in the filter
   The actual count always correctly reflects the number of types in the array.
*/

STDMETHODIMP
CEnumMediaTypes::Next(ULONG cMediaTypes,          // place this many types...
                      __out_ecount(cMediaTypes) AM_MEDIA_TYPE **ppMediaTypes,   // ...in this array
                      __out ULONG *pcFetched)           // actual count passed
{
    CheckPointer(ppMediaTypes,E_POINTER);
    ValidateReadWritePtr(ppMediaTypes,cMediaTypes * sizeof(AM_MEDIA_TYPE *));
    /* Check we are still in sync with the pin */
    if (AreWeOutOfSync() == TRUE) {
        return VFW_E_ENUM_OUT_OF_SYNC;
    }

    if (pcFetched!=NULL) {
        ValidateWritePtr(pcFetched, sizeof(ULONG));
        *pcFetched = 0;           // default unless we succeed
    }
    // now check that the parameter is valid
    else if (cMediaTypes>1) {     // pcFetched == NULL
        return E_INVALIDARG;
    }
    ULONG cFetched = 0;           // increment as we get each one.

    /* Return each media type by asking the filter for them in turn - If we
       have an error code retured to us while we are retrieving a media type
       we assume that our internal state is stale with respect to the filter
       (for example the window size changing) so we return
       VFW_E_ENUM_OUT_OF_SYNC */

    while (cMediaTypes) {

        CMediaType cmt;

        HRESULT hr = m_pPin->GetMediaType(m_Position++, &cmt);
        if (S_OK != hr) {
            break;
        }

        /* We now have a CMediaType object that contains the next media type
           but when we assign it to the array position we CANNOT just assign
           the AM_MEDIA_TYPE structure because as soon as the object goes out of
           scope it will delete the memory we have just copied. The function
           we use is CreateMediaType which allocates a task memory block */

        /*  Transfer across the format block manually to save an allocate
            and free on the format block and generally go faster */

        *ppMediaTypes = (AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
        if (*ppMediaTypes == NULL) {
            break;
        }

        /*  Do a regular copy */
        **ppMediaTypes = cmt;

        /*  Make sure the destructor doesn't free these */
        cmt.pbFormat = NULL;
        cmt.cbFormat = NULL;
        cmt.pUnk     = NULL;


        ppMediaTypes++;
        cFetched++;
        cMediaTypes--;
    }

    if (pcFetched!=NULL) {
        *pcFetched = cFetched;
    }

    return ( cMediaTypes==0 ? NOERROR : S_FALSE );
}


/* Skip over one or more entries in the enumerator */

STDMETHODIMP
CEnumMediaTypes::Skip(ULONG cMediaTypes)
{
    //  If we're skipping 0 elements we're guaranteed to skip the
    //  correct number of elements
    if (cMediaTypes == 0) {
        return S_OK;
    }

    /* Check we are still in sync with the pin */
    if (AreWeOutOfSync() == TRUE) {
        return VFW_E_ENUM_OUT_OF_SYNC;
    }

    m_Position += cMediaTypes;

    /*  See if we're over the end */
    CMediaType cmt;
    return S_OK == m_pPin->GetMediaType(m_Position - 1, &cmt) ? S_OK : S_FALSE;
}


/* Set the current position back to the start */
/* Reset has 3 simple steps:
 *
 * set position to head of list
 * sync enumerator with object being enumerated
 * return S_OK
 */

STDMETHODIMP
CEnumMediaTypes::Reset()

{
    m_Position = 0;

    // Bring the enumerator back into step with the current state.  This
    // may be a noop but ensures that the enumerator will be valid on the
    // next call.
    m_Version = m_pPin->GetMediaTypeVersion();
    return NOERROR;
}


//=====================================================================
//=====================================================================
// Implements CBasePin
//=====================================================================
//=====================================================================


/* NOTE The implementation of this class calls the CUnknown constructor with
   a NULL outer unknown pointer. This has the effect of making us a self
   contained class, ie any QueryInterface, AddRef or Release calls will be
   routed to the class's NonDelegatingUnknown methods. You will typically
   find that the classes that do this then override one or more of these
   virtual functions to provide more specialised behaviour. A good example
   of this is where a class wants to keep the QueryInterface internal but
   still wants its lifetime controlled by the external object */

/* Constructor */

CBasePin::CBasePin(__in_opt LPCTSTR pObjectName,
           __in CBaseFilter *pFilter,
           __in CCritSec *pLock,
           __inout HRESULT *phr,
           __in_opt LPCWSTR pName,
           PIN_DIRECTION dir) :
    CUnknown( pObjectName, NULL ),
    m_pFilter(pFilter),
    m_pLock(pLock),
    m_pName(NULL),
    m_Connected(NULL),
    m_dir(dir),
    m_bRunTimeError(FALSE),
    m_pQSink(NULL),
    m_TypeVersion(1),
    m_tStart(),
    m_tStop(MAX_TIME),
    m_bCanReconnectWhenActive(false),
    m_bTryMyTypesFirst(false),
    m_dRate(1.0)
{
    /*  WARNING - pFilter is often not a properly constituted object at
        this state (in particular QueryInterface may not work) - this
        is because its owner is often its containing object and we
        have been called from the containing object's constructor so
        the filter's owner has not yet had its CUnknown constructor
        called
    */
#ifdef DXMPERF
    PERFLOG_CTOR( pName ? pName : L"CBasePin", (IPin *) this );
#endif // DXMPERF

    ASSERT(pFilter != NULL);
    ASSERT(pLock != NULL);

    if (pName) {
        size_t cchName;
        HRESULT hr = StringCchLengthW(pName, STRSAFE_MAX_CCH, &cchName);
        if (SUCCEEDED(hr)) {
            m_pName = new WCHAR[cchName + 1];
            if (m_pName) {
                (void)StringCchCopyW(m_pName, cchName + 1, pName);
            }
        }
    }

#ifdef DEBUG
    m_cRef = 0;
#endif
}

#ifdef UNICODE
CBasePin::CBasePin(__in_opt LPCSTR pObjectName,
           __in CBaseFilter *pFilter,
           __in CCritSec *pLock,
           __inout HRESULT *phr,
           __in_opt LPCWSTR pName,
           PIN_DIRECTION dir) :
    CUnknown( pObjectName, NULL ),
    m_pFilter(pFilter),
    m_pLock(pLock),
    m_pName(NULL),
    m_Connected(NULL),
    m_dir(dir),
    m_bRunTimeError(FALSE),
    m_pQSink(NULL),
    m_TypeVersion(1),
    m_tStart(),
    m_tStop(MAX_TIME),
    m_bCanReconnectWhenActive(false),
    m_bTryMyTypesFirst(false),
    m_dRate(1.0)
{
    /*  WARNING - pFilter is often not a properly constituted object at
        this state (in particular QueryInterface may not work) - this
        is because its owner is often its containing object and we
        have been called from the containing object's constructor so
        the filter's owner has not yet had its CUnknown constructor
        called
    */
#ifdef DXMPERF
    PERFLOG_CTOR( pName ? pName : L"CBasePin", (IPin *) this );
#endif // DXMPERF

    ASSERT(pFilter != NULL);
    ASSERT(pLock != NULL);

    if (pName) {
        size_t cchName;
        HRESULT hr = StringCchLengthW(pName, STRSAFE_MAX_CCH, &cchName);
        if (SUCCEEDED(hr)) {
            m_pName = new WCHAR[cchName + 1];
            if (m_pName) {
                (void)StringCchCopyW(m_pName, cchName + 1, pName);
            }
        }
    }


#ifdef DEBUG
    m_cRef = 0;
#endif
}
#endif

/* Destructor since a connected pin holds a reference count on us there is
   no way that we can be deleted unless we are not currently connected */

CBasePin::~CBasePin()
{
#ifdef DXMPERF
    PERFLOG_DTOR( m_pName ? m_pName : L"CBasePin", (IPin *) this );
#endif // DXMPERF

    //  We don't call disconnect because if the filter is going away
    //  all the pins must have a reference count of zero so they must
    //  have been disconnected anyway - (but check the assumption)
    ASSERT(m_Connected == FALSE);

    delete[] m_pName;

    // check the internal reference count is consistent
    ASSERT(m_cRef == 0);
}


/* Override this to say what interfaces we support and where */

STDMETHODIMP
CBasePin::NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv)
{
    /* Do we have this interface */

    if (riid == IID_IPin) {
        return GetInterface((IPin *) this, ppv);
    } else if (riid == IID_IQualityControl) {
        return GetInterface((IQualityControl *) this, ppv);
    } else {
        return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


/* Override to increment the owning filter's reference count */

STDMETHODIMP_(ULONG)
CBasePin::NonDelegatingAddRef()
{
    ASSERT(InterlockedIncrement(&m_cRef) > 0);
    return m_pFilter->AddRef();
}


/* Override to decrement the owning filter's reference count */

STDMETHODIMP_(ULONG)
CBasePin::NonDelegatingRelease()
{
    ASSERT(InterlockedDecrement(&m_cRef) >= 0);
    return m_pFilter->Release();
}


/* Displays pin connection information */

#ifdef DEBUG
void
CBasePin::DisplayPinInfo(IPin *pReceivePin)
{

    if (DbgCheckModuleLevel(LOG_TRACE, CONNECT_TRACE_LEVEL)) {
        PIN_INFO ConnectPinInfo;
        PIN_INFO ReceivePinInfo;

        if (FAILED(QueryPinInfo(&ConnectPinInfo))) {
            StringCchCopyW(ConnectPinInfo.achName, sizeof(ConnectPinInfo.achName)/sizeof(WCHAR), L"Bad Pin");
        } else {
            QueryPinInfoReleaseFilter(ConnectPinInfo);
        }

        if (FAILED(pReceivePin->QueryPinInfo(&ReceivePinInfo))) {
            StringCchCopyW(ReceivePinInfo.achName, sizeof(ReceivePinInfo.achName)/sizeof(WCHAR), L"Bad Pin");
        } else {
            QueryPinInfoReleaseFilter(ReceivePinInfo);
        }

        DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Trying to connect Pins :")));
        DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("    <%ls>"), ConnectPinInfo.achName));
        DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("    <%ls>"), ReceivePinInfo.achName));
    }
}
#endif


/* Displays general information on the pin media type */

#ifdef DEBUG
void CBasePin::DisplayTypeInfo(IPin *pPin, const CMediaType *pmt)
{
    UNREFERENCED_PARAMETER(pPin);
    if (DbgCheckModuleLevel(LOG_TRACE, CONNECT_TRACE_LEVEL)) {
        DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Trying media type:")));
        DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("    major type:  %hs"),
               GuidNames[*pmt->Type()]));
        DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("    sub type  :  %hs"),
               GuidNames[*pmt->Subtype()]));
    }
}
#endif

/* Asked to connect to a pin. A pin is always attached to an owning filter
   object so we always delegate our locking to that object. We first of all
   retrieve a media type enumerator for the input pin and see if we accept
   any of the formats that it would ideally like, failing that we retrieve
   our enumerator and see if it will accept any of our preferred types */

STDMETHODIMP
CBasePin::Connect(
    IPin * pReceivePin,
    __in_opt const AM_MEDIA_TYPE *pmt   // optional media type
)
{
    CheckPointer(pReceivePin,E_POINTER);
    ValidateReadPtr(pReceivePin,sizeof(IPin));
    CAutoLock cObjectLock(m_pLock);
    DisplayPinInfo(pReceivePin);

    /* See if we are already connected */

    if (m_Connected) {
        DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Already connected")));
        return VFW_E_ALREADY_CONNECTED;
    }

    /* See if the filter is active */
    if (!IsStopped() && !m_bCanReconnectWhenActive) {
        return VFW_E_NOT_STOPPED;
    }


    // Find a mutually agreeable media type -
    // Pass in the template media type. If this is partially specified,
    // each of the enumerated media types will need to be checked against
    // it. If it is non-null and fully specified, we will just try to connect
    // with this.

    const CMediaType * ptype = (CMediaType*)pmt;
    HRESULT hr = AgreeMediaType(pReceivePin, ptype);
    if (FAILED(hr)) {
        DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Failed to agree type")));

        // Since the procedure is already returning an error code, there
        // is nothing else this function can do to report the error.
        EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );

#ifdef DXMPERF
        PERFLOG_CONNECT( (IPin *) this, pReceivePin, hr, pmt );
#endif // DXMPERF

        return hr;
    }

    DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Connection succeeded")));

#ifdef DXMPERF
    PERFLOG_CONNECT( (IPin *) this, pReceivePin, NOERROR, pmt );
#endif // DXMPERF

    return NOERROR;
}

// given a specific media type, attempt a connection (includes
// checking that the type is acceptable to this pin)
HRESULT
CBasePin::AttemptConnection(
    IPin* pReceivePin,      // connect to this pin
    const CMediaType* pmt   // using this type
)
{
    // The caller should hold the filter lock becasue this function
    // uses m_Connected.  The caller should also hold the filter lock
    // because this function calls SetMediaType(), IsStopped() and
    // CompleteConnect().
    ASSERT(CritCheckIn(m_pLock));

    // Check that the connection is valid  -- need to do this for every
    // connect attempt since BreakConnect will undo it.
    HRESULT hr = CheckConnect(pReceivePin);
    if (FAILED(hr)) {
        DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("CheckConnect failed")));

        // Since the procedure is already returning an error code, there
        // is nothing else this function can do to report the error.
        EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );

        return hr;
    }

    DisplayTypeInfo(pReceivePin, pmt);

    /* Check we will accept this media type */

    hr = CheckMediaType(pmt);
    if (hr == NOERROR) {

        /*  Make ourselves look connected otherwise ReceiveConnection
            may not be able to complete the connection
        */
        m_Connected = pReceivePin;
        m_Connected->AddRef();
        hr = SetMediaType(pmt);
        if (SUCCEEDED(hr)) {
            /* See if the other pin will accept this type */

            hr = pReceivePin->ReceiveConnection((IPin *)this, pmt);
            if (SUCCEEDED(hr)) {
                /* Complete the connection */

                hr = CompleteConnect(pReceivePin);
                if (SUCCEEDED(hr)) {
                    return hr;
                } else {
                    DbgLog((LOG_TRACE,
                            CONNECT_TRACE_LEVEL,
                            TEXT("Failed to complete connection")));
                    pReceivePin->Disconnect();
                }
            }
        }
    } else {
        // we cannot use this media type

        // return a specific media type error if there is one
        // or map a general failure code to something more helpful
        // (in particular S_FALSE gets changed to an error code)
        if (SUCCEEDED(hr) ||
            (hr == E_FAIL) ||
            (hr == E_INVALIDARG)) {
            hr = VFW_E_TYPE_NOT_ACCEPTED;
        }
    }

    // BreakConnect and release any connection here in case CheckMediaType
    // failed, or if we set anything up during a call back during
    // ReceiveConnection.

    // Since the procedure is already returning an error code, there
    // is nothing else this function can do to report the error.
    EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );

    /*  If failed then undo our state */
    if (m_Connected) {
        m_Connected->Release();
        m_Connected = NULL;
    }

    return hr;
}

/* Given an enumerator we cycle through all the media types it proposes and
   firstly suggest them to our derived pin class and if that succeeds try
   them with the pin in a ReceiveConnection call. This means that if our pin
   proposes a media type we still check in here that we can support it. This
   is deliberate so that in simple cases the enumerator can hold all of the
   media types even if some of them are not really currently available */

HRESULT CBasePin::TryMediaTypes(
    IPin *pReceivePin,
    __in_opt const CMediaType *pmt,
    IEnumMediaTypes *pEnum)
{
    /* Reset the current enumerator position */

    HRESULT hr = pEnum->Reset();
    if (FAILED(hr)) {
        return hr;
    }

    CMediaType *pMediaType = NULL;
    ULONG ulMediaCount = 0;

    // attempt to remember a specific error code if there is one
    HRESULT hrFailure = S_OK;

    for (;;) {

        /* Retrieve the next media type NOTE each time round the loop the
           enumerator interface will allocate another AM_MEDIA_TYPE structure
           If we are successful then we copy it into our output object, if
           not then we must delete the memory allocated before returning */

        hr = pEnum->Next(1, (AM_MEDIA_TYPE**)&pMediaType,&ulMediaCount);
        if (hr != S_OK) {
            if (S_OK == hrFailure) {
                hrFailure = VFW_E_NO_ACCEPTABLE_TYPES;
            }
            return hrFailure;
        }


        ASSERT(ulMediaCount == 1);
        ASSERT(pMediaType);

        // check that this matches the partial type (if any)

        if (pMediaType &&
            ((pmt == NULL) ||
            pMediaType->MatchesPartial(pmt))) {

            hr = AttemptConnection(pReceivePin, pMediaType);

            // attempt to remember a specific error code
            if (FAILED(hr) &&
            SUCCEEDED(hrFailure) &&
            (hr != E_FAIL) &&
            (hr != E_INVALIDARG) &&
            (hr != VFW_E_TYPE_NOT_ACCEPTED)) {
                hrFailure = hr;
            }
        } else {
            hr = VFW_E_NO_ACCEPTABLE_TYPES;
        }

        if(pMediaType) {
            DeleteMediaType(pMediaType);
            pMediaType = NULL;
        }

        if (S_OK == hr) {
            return hr;
        }
    }
}


/* This is called to make the connection, including the taask of finding
   a media type for the pin connection. pmt is the proposed media type
   from the Connect call: if this is fully specified, we will try that.
   Otherwise we enumerate and try all the input pin's types first and
   if that fails we then enumerate and try all our preferred media types.
   For each media type we check it against pmt (if non-null and partially
   specified) as well as checking that both pins will accept it.
 */

HRESULT CBasePin::AgreeMediaType(
    IPin *pReceivePin,
    const CMediaType *pmt)
{
    ASSERT(pReceivePin);
    IEnumMediaTypes *pEnumMediaTypes = NULL;

    // if the media type is fully specified then use that
    if ( (pmt != NULL) && (!pmt->IsPartiallySpecified())) {

        // if this media type fails, then we must fail the connection
        // since if pmt is nonnull we are only allowed to connect
        // using a type that matches it.

        return AttemptConnection(pReceivePin, pmt);
    }


    /* Try the other pin's enumerator */

    HRESULT hrFailure = VFW_E_NO_ACCEPTABLE_TYPES;

    for (int i = 0; i < 2; i++) {
        HRESULT hr;
        if (i == (int)m_bTryMyTypesFirst) {
            hr = pReceivePin->EnumMediaTypes(&pEnumMediaTypes);
        } else {
            hr = EnumMediaTypes(&pEnumMediaTypes);
        }
        if (SUCCEEDED(hr)) {
            ASSERT(pEnumMediaTypes);
            hr = TryMediaTypes(pReceivePin,pmt,pEnumMediaTypes);
            pEnumMediaTypes->Release();
            if (SUCCEEDED(hr)) {
                return NOERROR;
            } else {
                // try to remember specific error codes if there are any
                if ((hr != E_FAIL) &&
                    (hr != E_INVALIDARG) &&
                    (hr != VFW_E_TYPE_NOT_ACCEPTED)) {
                    hrFailure = hr;
                }
            }
        }
    }

    return hrFailure;
}


/* Called when we want to complete a connection to another filter. Failing
   this will also fail the connection and disconnect the other pin as well */

HRESULT
CBasePin::CompleteConnect(IPin *pReceivePin)
{
    UNREFERENCED_PARAMETER(pReceivePin);
    return NOERROR;
}


/* This is called to set the format for a pin connection - CheckMediaType
   will have been called to check the connection format and if it didn't
   return an error code then this (virtual) function will be invoked */

HRESULT
CBasePin::SetMediaType(const CMediaType *pmt)
{
    HRESULT hr = m_mt.Set(*pmt);
    if (FAILED(hr)) {
        return hr;
    }

    return NOERROR;
}


/* This is called during Connect() to provide a virtual method that can do
   any specific check needed for connection such as QueryInterface. This
   base class method just checks that the pin directions don't match */

HRESULT
CBasePin::CheckConnect(IPin * pPin)
{
    /* Check that pin directions DONT match */

    PIN_DIRECTION pd;
    pPin->QueryDirection(&pd);

    ASSERT((pd == PINDIR_OUTPUT) || (pd == PINDIR_INPUT));
    ASSERT((m_dir == PINDIR_OUTPUT) || (m_dir == PINDIR_INPUT));

    // we should allow for non-input and non-output connections?
    if (pd == m_dir) {
        return VFW_E_INVALID_DIRECTION;
    }
    return NOERROR;
}


/* This is called when we realise we can't make a connection to the pin and
   must undo anything we did in CheckConnect - override to release QIs done */

HRESULT
CBasePin::BreakConnect()
{
    return NOERROR;
}


/* Called normally by an output pin on an input pin to try and establish a
   connection.
*/

STDMETHODIMP
CBasePin::ReceiveConnection(
    IPin * pConnector,   // this is the pin who we will connect to
    const AM_MEDIA_TYPE *pmt  // this is the media type we will exchange
)
{
    CheckPointer(pConnector,E_POINTER);
    CheckPointer(pmt,E_POINTER);
    ValidateReadPtr(pConnector,sizeof(IPin));
    ValidateReadPtr(pmt,sizeof(AM_MEDIA_TYPE));
    CAutoLock cObjectLock(m_pLock);

    /* Are we already connected */
    if (m_Connected) {
        return VFW_E_ALREADY_CONNECTED;
    }

    /* See if the filter is active */
    if (!IsStopped() && !m_bCanReconnectWhenActive) {
        return VFW_E_NOT_STOPPED;
    }

    HRESULT hr = CheckConnect(pConnector);
    if (FAILED(hr)) {
        // Since the procedure is already returning an error code, there
        // is nothing else this function can do to report the error.
        EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );

#ifdef DXMPERF
        PERFLOG_RXCONNECT( pConnector, (IPin *) this, hr, pmt );
#endif // DXMPERF

        return hr;
    }

    /* Ask derived class if this media type is ok */

    CMediaType * pcmt = (CMediaType*) pmt;
    hr = CheckMediaType(pcmt);
    if (hr != NOERROR) {
        // no -we don't support this media type

        // Since the procedure is already returning an error code, there
        // is nothing else this function can do to report the error.
        EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );

        // return a specific media type error if there is one
        // or map a general failure code to something more helpful
        // (in particular S_FALSE gets changed to an error code)
        if (SUCCEEDED(hr) ||
            (hr == E_FAIL) ||
            (hr == E_INVALIDARG)) {
            hr = VFW_E_TYPE_NOT_ACCEPTED;
        }

#ifdef DXMPERF
        PERFLOG_RXCONNECT( pConnector, (IPin *) this, hr, pmt );
#endif // DXMPERF

        return hr;
    }

    /* Complete the connection */

    m_Connected = pConnector;
    m_Connected->AddRef();
    hr = SetMediaType(pcmt);
    if (SUCCEEDED(hr)) {
        hr = CompleteConnect(pConnector);
        if (SUCCEEDED(hr)) {

#ifdef DXMPERF
            PERFLOG_RXCONNECT( pConnector, (IPin *) this, NOERROR, pmt );
#endif // DXMPERF

            return NOERROR;
        }
    }

    DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Failed to set the media type or failed to complete the connection.")));
    m_Connected->Release();
    m_Connected = NULL;

    // Since the procedure is already returning an error code, there
    // is nothing else this function can do to report the error.
    EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) );

#ifdef DXMPERF
    PERFLOG_RXCONNECT( pConnector, (IPin *) this, hr, pmt );
#endif // DXMPERF

    return hr;
}


/* Called when we want to terminate a pin connection */

STDMETHODIMP
CBasePin::Disconnect()
{
    CAutoLock cObjectLock(m_pLock);

    /* See if the filter is active */
    if (!IsStopped()) {
        return VFW_E_NOT_STOPPED;
    }

    return DisconnectInternal();
}

STDMETHODIMP
CBasePin::DisconnectInternal()
{
    ASSERT(CritCheckIn(m_pLock));

    if (m_Connected) {
        HRESULT hr = BreakConnect();
        if( FAILED( hr ) ) {

#ifdef DXMPERF
            PERFLOG_DISCONNECT( (IPin *) this, m_Connected, hr );
#endif // DXMPERF

            // There is usually a bug in the program if BreakConnect() fails.
            DbgBreak( "WARNING: BreakConnect() failed in CBasePin::Disconnect()." );
            return hr;
        }

        m_Connected->Release();
        m_Connected = NULL;

#ifdef DXMPERF
        PERFLOG_DISCONNECT( (IPin *) this, m_Connected, S_OK );
#endif // DXMPERF

        return S_OK;
    } else {
        // no connection - not an error

#ifdef DXMPERF
        PERFLOG_DISCONNECT( (IPin *) this, m_Connected, S_FALSE );
#endif // DXMPERF

        return S_FALSE;
    }
}


/* Return an AddRef()'d pointer to the connected pin if there is one */
STDMETHODIMP
CBasePin::ConnectedTo(
    __deref_out IPin **ppPin
)
{
    CheckPointer(ppPin,E_POINTER);
    ValidateReadWritePtr(ppPin,sizeof(IPin *));
    //
    //  It's pointless to lock here.
    //  The caller should ensure integrity.
    //

    IPin *pPin = m_Connected;
    *ppPin = pPin;
    if (pPin != NULL) {
        pPin->AddRef();
        return S_OK;
    } else {
        ASSERT(*ppPin == NULL);
        return VFW_E_NOT_CONNECTED;
    }
}

/* Return the media type of the connection */
STDMETHODIMP
CBasePin::ConnectionMediaType(
    __out AM_MEDIA_TYPE *pmt
)
{
    CheckPointer(pmt,E_POINTER);
    ValidateReadWritePtr(pmt,sizeof(AM_MEDIA_TYPE));
    CAutoLock cObjectLock(m_pLock);

    /*  Copy constructor of m_mt allocates the memory */
    if (IsConnected()) {
        CopyMediaType( pmt, &m_mt );
        return S_OK;
    } else {
        ((CMediaType *)pmt)->InitMediaType();
        return VFW_E_NOT_CONNECTED;
    }
}

/* Return information about the filter we are connect to */

STDMETHODIMP
CBasePin::QueryPinInfo(
    __out PIN_INFO * pInfo
)
{
    CheckPointer(pInfo,E_POINTER);
    ValidateReadWritePtr(pInfo,sizeof(PIN_INFO));

    pInfo->pFilter = m_pFilter;
    if (m_pFilter) {
        m_pFilter->AddRef();
    }

    if (m_pName) {
        (void)StringCchCopyW(pInfo->achName, NUMELMS(pInfo->achName), m_pName);
    } else {
        pInfo->achName[0] = L'\0';
    }

    pInfo->dir = m_dir;

    return NOERROR;
}

STDMETHODIMP
CBasePin::QueryDirection(
    __out PIN_DIRECTION * pPinDir
)
{
    CheckPointer(pPinDir,E_POINTER);
    ValidateReadWritePtr(pPinDir,sizeof(PIN_DIRECTION));

    *pPinDir = m_dir;
    return NOERROR;
}

// Default QueryId to return the pin's name
STDMETHODIMP
CBasePin::QueryId(
    __deref_out LPWSTR * Id
)
{
    //  We're not going away because someone's got a pointer to us
    //  so there's no need to lock

    return AMGetWideString(Name(), Id);
}

/* Does this pin support this media type WARNING this interface function does
   not lock the main object as it is meant to be asynchronous by nature - if
   the media types you support depend on some internal state that is updated
   dynamically then you will need to implement locking in a derived class */

STDMETHODIMP
CBasePin::QueryAccept(
    const AM_MEDIA_TYPE *pmt
)
{
    CheckPointer(pmt,E_POINTER);
    ValidateReadPtr(pmt,sizeof(AM_MEDIA_TYPE));

    /* The CheckMediaType method is valid to return error codes if the media
       type is horrible, an example might be E_INVALIDARG. What we do here
       is map all the error codes into either S_OK or S_FALSE regardless */

    HRESULT hr = CheckMediaType((CMediaType*)pmt);
    if (FAILED(hr)) {
        return S_FALSE;
    }
    // note that the only defined success codes should be S_OK and S_FALSE...
    return hr;
}


/* This can be called to return an enumerator for the pin's list of preferred
   media types. An input pin is not obliged to have any preferred formats
   although it can do. For example, the window renderer has a preferred type
   which describes a video image that matches the current window size. All
   output pins should expose at least one preferred format otherwise it is
   possible that neither pin has any types and so no connection is possible */

STDMETHODIMP
CBasePin::EnumMediaTypes(
    __deref_out IEnumMediaTypes **ppEnum
)
{
    CheckPointer(ppEnum,E_POINTER);
    ValidateReadWritePtr(ppEnum,sizeof(IEnumMediaTypes *));

    /* Create a new ref counted enumerator */

    *ppEnum = new CEnumMediaTypes(this,
                              NULL);

    if (*ppEnum == NULL) {
        return E_OUTOFMEMORY;
    }

    return NOERROR;
}



/* This is a virtual function that returns a media type corresponding with
   place iPosition in the list. This base class simply returns an error as
   we support no media types by default but derived classes should override */

HRESULT CBasePin::GetMediaType(int iPosition, __inout CMediaType *pMediaType)
{
    UNREFERENCED_PARAMETER(iPosition);
    UNREFERENCED_PARAMETER(pMediaType);
    return E_UNEXPECTED;
}


/* This is a virtual function that returns the current media type version.
   The base class initialises the media type enumerators with the value 1
   By default we always returns that same value. A Derived class may change
   the list of media types available and after doing so it should increment
   the version either in a method derived from this, or more simply by just
   incrementing the m_TypeVersion base pin variable. The type enumerators
   call this when they want to see if their enumerations are out of date */

LONG CBasePin::GetMediaTypeVersion()
{
    return m_TypeVersion;
}


/* Increment the cookie representing the current media type version */

void CBasePin::IncrementTypeVersion()
{
    InterlockedIncrement(&m_TypeVersion);
}


/* Called by IMediaFilter implementation when the state changes from Stopped
   to either paused or running and in derived classes could do things like
   commit memory and grab hardware resource (the default is to do nothing) */

HRESULT
CBasePin::Active(void)
{
    return NOERROR;
}

/* Called by IMediaFilter implementation when the state changes from
   to either paused to running and in derived classes could do things like
   commit memory and grab hardware resource (the default is to do nothing) */

HRESULT
CBasePin::Run(REFERENCE_TIME tStart)
{
    UNREFERENCED_PARAMETER(tStart);
    return NOERROR;
}


/* Also called by the IMediaFilter implementation when the state changes to
   Stopped at which point you should decommit allocators and free hardware
   resources you grabbed in the Active call (default is also to do nothing) */

HRESULT
CBasePin::Inactive(void)
{
    m_bRunTimeError = FALSE;
    return NOERROR;
}


// Called when no more data will arrive
STDMETHODIMP
CBasePin::EndOfStream(void)
{
    return S_OK;
}


STDMETHODIMP
CBasePin::SetSink(IQualityControl * piqc)
{
    CAutoLock cObjectLock(m_pLock);
    if (piqc) ValidateReadPtr(piqc,sizeof(IQualityControl));
    m_pQSink = piqc;
    return NOERROR;
} // SetSink


STDMETHODIMP
CBasePin::Notify(IBaseFilter * pSender, Quality q)
{
    UNREFERENCED_PARAMETER(q);
    UNREFERENCED_PARAMETER(pSender);
    DbgBreak("IQualityControl::Notify not over-ridden from CBasePin.  (IGNORE is OK)");
    return E_NOTIMPL;
} //Notify


// NewSegment notifies of the start/stop/rate applying to the data
// about to be received. Default implementation records data and
// returns S_OK.
// Override this to pass downstream.
STDMETHODIMP
CBasePin::NewSegment(
                REFERENCE_TIME tStart,
                REFERENCE_TIME tStop,
                double dRate)
{
    m_tStart = tStart;
    m_tStop = tStop;
    m_dRate = dRate;

    return S_OK;
}


//=====================================================================
//=====================================================================
// Implements CBaseOutputPin
//=====================================================================
//=====================================================================


CBaseOutputPin::CBaseOutputPin(__in_opt LPCTSTR pObjectName,
                   __in CBaseFilter *pFilter,
                   __in CCritSec *pLock,
                   __inout HRESULT *phr,
                   __in_opt LPCWSTR pName) :
    CBasePin(pObjectName, pFilter, pLock, phr, pName, PINDIR_OUTPUT),
    m_pAllocator(NULL),
    m_pInputPin(NULL)
{
    ASSERT(pFilter);
}

#ifdef UNICODE
CBaseOutputPin::CBaseOutputPin(__in_opt LPCSTR pObjectName,
                   __in CBaseFilter *pFilter,
                   __in CCritSec *pLock,
                   __inout HRESULT *phr,
                   __in_opt LPCWSTR pName) :
    CBasePin(pObjectName, pFilter, pLock, phr, pName, PINDIR_OUTPUT),
    m_pAllocator(NULL),
    m_pInputPin(NULL)
{
    ASSERT(pFilter);
}
#endif

/*   This is called after a media type has been proposed

     Try to complete the connection by agreeing the allocator
*/
HRESULT
CBaseOutputPin::CompleteConnect(IPin *pReceivePin)
{
    UNREFERENCED_PARAMETER(pReceivePin);
    return DecideAllocator(m_pInputPin, &m_pAllocator);
}


/* This method is called when the output pin is about to try and connect to
   an input pin. It is at this point that you should try and grab any extra
   interfaces that you need, in this case IMemInputPin. Because this is
   only called if we are not currently connected we do NOT need to call
   BreakConnect. This also makes it easier to derive classes from us as
   BreakConnect is only called when we actually have to break a connection
   (or a partly made connection) and not when we are checking a connection */

/* Overriden from CBasePin */

HRESULT
CBaseOutputPin::CheckConnect(IPin * pPin)
{
    HRESULT hr = CBasePin::CheckConnect(pPin);
    if (FAILED(hr)) {
    return hr;
    }

    // get an input pin and an allocator interface
    hr = pPin->QueryInterface(IID_IMemInputPin, (void **) &m_pInputPin);
    if (FAILED(hr)) {
        return hr;
    }
    return NOERROR;
}


/* Overriden from CBasePin */

HRESULT
CBaseOutputPin::BreakConnect()
{
    /* Release any allocator we hold */

    if (m_pAllocator) {
        // Always decommit the allocator because a downstream filter may or
        // may not decommit the connection's allocator.  A memory leak could
        // occur if the allocator is not decommited when a connection is broken.
        HRESULT hr = m_pAllocator->Decommit();
        if( FAILED( hr ) ) {
            return hr;
        }

        m_pAllocator->Release();
        m_pAllocator = NULL;
    }

    /* Release any input pin interface we hold */

    if (m_pInputPin) {
        m_pInputPin->Release();
        m_pInputPin = NULL;
    }
    return NOERROR;
}


/* This is called when the input pin didn't give us a valid allocator */

HRESULT
CBaseOutputPin::InitAllocator(__deref_out IMemAllocator **ppAlloc)
{
    return CreateMemoryAllocator(ppAlloc);
}


/* Decide on an allocator, override this if you want to use your own allocator
   Override DecideBufferSize to call SetProperties. If the input pin fails
   the GetAllocator call then this will construct a CMemAllocator and call
   DecideBufferSize on that, and if that fails then we are completely hosed.
   If the you succeed the DecideBufferSize call, we will notify the input
   pin of the selected allocator. NOTE this is called during Connect() which
   therefore looks after grabbing and locking the object's critical section */

// We query the input pin for its requested properties and pass this to
// DecideBufferSize to allow it to fulfill requests that it is happy
// with (eg most people don't care about alignment and are thus happy to
// use the downstream pin's alignment request).

HRESULT
CBaseOutputPin::DecideAllocator(IMemInputPin *pPin, __deref_out IMemAllocator **ppAlloc)
{
    HRESULT hr = NOERROR;
    *ppAlloc = NULL;

    // get downstream prop request
    // the derived class may modify this in DecideBufferSize, but
    // we assume that he will consistently modify it the same way,
    // so we only get it once
    ALLOCATOR_PROPERTIES prop;
    ZeroMemory(&prop, sizeof(prop));

    // whatever he returns, we assume prop is either all zeros
    // or he has filled it out.
    pPin->GetAllocatorRequirements(&prop);

    // if he doesn't care about alignment, then set it to 1
    if (prop.cbAlign == 0) {
        prop.cbAlign = 1;
    }

    /* Try the allocator provided by the input pin */

    hr = pPin->GetAllocator(ppAlloc);
    if (SUCCEEDED(hr)) {

        hr = DecideBufferSize(*ppAlloc, &prop);
        if (SUCCEEDED(hr)) {
            hr = pPin->NotifyAllocator(*ppAlloc, FALSE);
            if (SUCCEEDED(hr)) {
                return NOERROR;
            }
        }
    }

    /* If the GetAllocator failed we may not have an interface */

    if (*ppAlloc) {
        (*ppAlloc)->Release();
        *ppAlloc = NULL;
    }

    /* Try the output pin's allocator by the same method */

    hr = InitAllocator(ppAlloc);
    if (SUCCEEDED(hr)) {

        // note - the properties passed here are in the same
        // structure as above and may have been modified by
        // the previous call to DecideBufferSize
        hr = DecideBufferSize(*ppAlloc, &prop);
        if (SUCCEEDED(hr)) {
            hr = pPin->NotifyAllocator(*ppAlloc, FALSE);
            if (SUCCEEDED(hr)) {
                return NOERROR;
            }
        }
    }

    /* Likewise we may not have an interface to release */

    if (*ppAlloc) {
        (*ppAlloc)->Release();
        *ppAlloc = NULL;
    }
    return hr;
}


/* This returns an empty sample buffer from the allocator WARNING the same
   dangers and restrictions apply here as described below for Deliver() */

HRESULT
CBaseOutputPin::GetDeliveryBuffer(__deref_out IMediaSample ** ppSample,
                                  __in_opt REFERENCE_TIME * pStartTime,
                                  __in_opt REFERENCE_TIME * pEndTime,
                                  DWORD dwFlags)
{
    if (m_pAllocator != NULL) {
        return m_pAllocator->GetBuffer(ppSample,pStartTime,pEndTime,dwFlags);
    } else {
        return E_NOINTERFACE;
    }
}


/* Deliver a filled-in sample to the connected input pin. NOTE the object must
   have locked itself before calling us otherwise we may get halfway through
   executing this method only to find the filter graph has got in and
   disconnected us from the input pin. If the filter has no worker threads
   then the lock is best applied on Receive(), otherwise it should be done
   when the worker thread is ready to deliver. There is a wee snag to worker
   threads that this shows up. The worker thread must lock the object when
   it is ready to deliver a sample, but it may have to wait until a state
   change has completed, but that may never complete because the state change
   is waiting for the worker thread to complete. The way to handle this is for
   the state change code to grab the critical section, then set an abort event
   for the worker thread, then release the critical section and wait for the
   worker thread to see the event we set and then signal that it has finished
   (with another event). At which point the state change code can complete */

// note (if you've still got any breath left after reading that) that you
// need to release the sample yourself after this call. if the connected
// input pin needs to hold onto the sample beyond the call, it will addref
// the sample itself.

// of course you must release this one and call GetDeliveryBuffer for the
// next. You cannot reuse it directly.

HRESULT
CBaseOutputPin::Deliver(IMediaSample * pSample)
{
    if (m_pInputPin == NULL) {
        return VFW_E_NOT_CONNECTED;
    }

#ifdef DXMPERF
    PERFLOG_DELIVER( m_pName ? m_pName : L"CBaseOutputPin", (IPin *) this, (IPin  *) m_pInputPin, pSample, &m_mt );
#endif // DXMPERF

    return m_pInputPin->Receive(pSample);
}


// called from elsewhere in our filter to pass EOS downstream to
// our connected input pin
HRESULT
CBaseOutputPin::DeliverEndOfStream(void)
{
    // remember this is on IPin not IMemInputPin
    if (m_Connected == NULL) {
        return VFW_E_NOT_CONNECTED;
    }
    return m_Connected->EndOfStream();
}


/* Commit the allocator's memory, this is called through IMediaFilter
   which is responsible for locking the object before calling us */

HRESULT
CBaseOutputPin::Active(void)
{
    if (m_pAllocator == NULL) {
        return VFW_E_NO_ALLOCATOR;
    }
    return m_pAllocator->Commit();
}


/* Free up or unprepare allocator's memory, this is called through
   IMediaFilter which is responsible for locking the object first */

HRESULT
CBaseOutputPin::Inactive(void)
{
    m_bRunTimeError = FALSE;
    if (m_pAllocator == NULL) {
        return VFW_E_NO_ALLOCATOR;
    }
    return m_pAllocator->Decommit();
}

// we have a default handling of EndOfStream which is to return
// an error, since this should be called on input pins only
STDMETHODIMP
CBaseOutputPin::EndOfStream(void)
{
    return E_UNEXPECTED;
}


// BeginFlush should be called on input pins only
STDMETHODIMP
CBaseOutputPin::BeginFlush(void)
{
    return E_UNEXPECTED;
}

// EndFlush should be called on input pins only
STDMETHODIMP
CBaseOutputPin::EndFlush(void)
{
    return E_UNEXPECTED;
}

// call BeginFlush on the connected input pin
HRESULT
CBaseOutputPin::DeliverBeginFlush(void)
{
    // remember this is on IPin not IMemInputPin
    if (m_Connected == NULL) {
        return VFW_E_NOT_CONNECTED;
    }
    return m_Connected->BeginFlush();
}

// call EndFlush on the connected input pin
HRESULT
CBaseOutputPin::DeliverEndFlush(void)
{
    // remember this is on IPin not IMemInputPin
    if (m_Connected == NULL) {
        return VFW_E_NOT_CONNECTED;
    }
    return m_Connected->EndFlush();
}
// deliver NewSegment to connected pin
HRESULT
CBaseOutputPin::DeliverNewSegment(
    REFERENCE_TIME tStart,
    REFERENCE_TIME tStop,
    double dRate)
{
    if (m_Connected == NULL) {
        return VFW_E_NOT_CONNECTED;
    }
    return m_Connected->NewSegment(tStart, tStop, dRate);
}


//=====================================================================
//=====================================================================
// Implements CBaseInputPin
//=====================================================================
//=====================================================================


/* Constructor creates a default allocator object */

CBaseInputPin::CBaseInputPin(__in_opt LPCTSTR pObjectName,
                 __in CBaseFilter *pFilter,
                 __in CCritSec *pLock,
                 __inout HRESULT *phr,
                 __in_opt LPCWSTR pPinName) :
    CBasePin(pObjectName, pFilter, pLock, phr, pPinName, PINDIR_INPUT),
    m_pAllocator(NULL),
    m_bReadOnly(FALSE),
    m_bFlushing(FALSE)
{
    ZeroMemory(&m_SampleProps, sizeof(m_SampleProps));
}

#ifdef UNICODE
CBaseInputPin::CBaseInputPin(__in LPCSTR pObjectName,
                 __in CBaseFilter *pFilter,
                 __in CCritSec *pLock,
                 __inout HRESULT *phr,
                 __in_opt LPCWSTR pPinName) :
    CBasePin(pObjectName, pFilter, pLock, phr, pPinName, PINDIR_INPUT),
    m_pAllocator(NULL),
    m_bReadOnly(FALSE),
    m_bFlushing(FALSE)
{
    ZeroMemory(&m_SampleProps, sizeof(m_SampleProps));
}
#endif

/* Destructor releases it's reference count on the default allocator */

CBaseInputPin::~CBaseInputPin()
{
    if (m_pAllocator != NULL) {
    m_pAllocator->Release();
    m_pAllocator = NULL;
    }
}


// override this to publicise our interfaces
STDMETHODIMP
CBaseInputPin::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    /* Do we know about this interface */

    if (riid == IID_IMemInputPin) {
        return GetInterface((IMemInputPin *) this, ppv);
    } else {
        return CBasePin::NonDelegatingQueryInterface(riid, ppv);
    }
}


/* Return the allocator interface that this input pin would like the output
   pin to use. NOTE subsequent calls to GetAllocator should all return an
   interface onto the SAME object so we create one object at the start

   Note:
       The allocator is Release()'d on disconnect and replaced on
       NotifyAllocator().

   Override this to provide your own allocator.
*/

STDMETHODIMP
CBaseInputPin::GetAllocator(
    __deref_out IMemAllocator **ppAllocator)
{
    CheckPointer(ppAllocator,E_POINTER);
    ValidateReadWritePtr(ppAllocator,sizeof(IMemAllocator *));
    CAutoLock cObjectLock(m_pLock);

    if (m_pAllocator == NULL) {
        HRESULT hr = CreateMemoryAllocator(&m_pAllocator);
        if (FAILED(hr)) {
            return hr;
        }
    }
    ASSERT(m_pAllocator != NULL);
    *ppAllocator = m_pAllocator;
    m_pAllocator->AddRef();
    return NOERROR;
}


/* Tell the input pin which allocator the output pin is actually going to use
   Override this if you care - NOTE the locking we do both here and also in
   GetAllocator is unnecessary but derived classes that do something useful
   will undoubtedly have to lock the object so this might help remind people */

STDMETHODIMP
CBaseInputPin::NotifyAllocator(
    IMemAllocator * pAllocator,
    BOOL bReadOnly)
{
    CheckPointer(pAllocator,E_POINTER);
    ValidateReadPtr(pAllocator,sizeof(IMemAllocator));
    CAutoLock cObjectLock(m_pLock);

    IMemAllocator *pOldAllocator = m_pAllocator;
    pAllocator->AddRef();
    m_pAllocator = pAllocator;

    if (pOldAllocator != NULL) {
        pOldAllocator->Release();
    }

    // the readonly flag indicates whether samples from this allocator should
    // be regarded as readonly - if true, then inplace transforms will not be
    // allowed.
    m_bReadOnly = (BYTE)bReadOnly;
    return NOERROR;
}


HRESULT
CBaseInputPin::BreakConnect()
{
    /* We don't need our allocator any more */
    if (m_pAllocator) {
        // Always decommit the allocator because a downstream filter may or
        // may not decommit the connection's allocator.  A memory leak could
        // occur if the allocator is not decommited when a pin is disconnected.
        HRESULT hr = m_pAllocator->Decommit();
        if( FAILED( hr ) ) {
            return hr;
        }

        m_pAllocator->Release();
        m_pAllocator = NULL;
    }

    return S_OK;
}


/* Do something with this media sample - this base class checks to see if the
   format has changed with this media sample and if so checks that the filter
   will accept it, generating a run time error if not. Once we have raised a
   run time error we set a flag so that no more samples will be accepted

   It is important that any filter should override this method and implement
   synchronization so that samples are not processed when the pin is
   disconnected etc
*/

STDMETHODIMP
CBaseInputPin::Receive(IMediaSample *pSample)
{
    CheckPointer(pSample,E_POINTER);
    ValidateReadPtr(pSample,sizeof(IMediaSample));
    ASSERT(pSample);

    HRESULT hr = CheckStreaming();
    if (S_OK != hr) {
        return hr;
    }

#ifdef DXMPERF
    PERFLOG_RECEIVE( m_pName ? m_pName : L"CBaseInputPin", (IPin *) m_Connected, (IPin *) this, pSample, &m_mt );
#endif // DXMPERF


    /* Check for IMediaSample2 */
    IMediaSample2 *pSample2;
    if (SUCCEEDED(pSample->QueryInterface(IID_IMediaSample2, (void **)&pSample2))) {
        hr = pSample2->GetProperties(sizeof(m_SampleProps), (PBYTE)&m_SampleProps);
        pSample2->Release();
        if (FAILED(hr)) {
            return hr;
        }
    } else {
        /*  Get the properties the hard way */
        m_SampleProps.cbData = sizeof(m_SampleProps);
        m_SampleProps.dwTypeSpecificFlags = 0;
        m_SampleProps.dwStreamId = AM_STREAM_MEDIA;
        m_SampleProps.dwSampleFlags = 0;
        if (S_OK == pSample->IsDiscontinuity()) {
            m_SampleProps.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
        }
        if (S_OK == pSample->IsPreroll()) {
            m_SampleProps.dwSampleFlags |= AM_SAMPLE_PREROLL;
        }
        if (S_OK == pSample->IsSyncPoint()) {
            m_SampleProps.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
        }
        if (SUCCEEDED(pSample->GetTime(&m_SampleProps.tStart,
                                       &m_SampleProps.tStop))) {
            m_SampleProps.dwSampleFlags |= AM_SAMPLE_TIMEVALID |
                                           AM_SAMPLE_STOPVALID;
        }
        if (S_OK == pSample->GetMediaType(&m_SampleProps.pMediaType)) {
            m_SampleProps.dwSampleFlags |= AM_SAMPLE_TYPECHANGED;
        }
        pSample->GetPointer(&m_SampleProps.pbBuffer);
        m_SampleProps.lActual = pSample->GetActualDataLength();
        m_SampleProps.cbBuffer = pSample->GetSize();
    }

    /* Has the format changed in this sample */

    if (!(m_SampleProps.dwSampleFlags & AM_SAMPLE_TYPECHANGED)) {
        return NOERROR;
    }

    /* Check the derived class accepts this format */
    /* This shouldn't fail as the source must call QueryAccept first */

    hr = CheckMediaType((CMediaType *)m_SampleProps.pMediaType);

    if (hr == NOERROR) {
        return NOERROR;
    }

    /* Raise a runtime error if we fail the media type */

    m_bRunTimeError = TRUE;
    EndOfStream();
    m_pFilter->NotifyEvent(EC_ERRORABORT,VFW_E_TYPE_NOT_ACCEPTED,0);
    return VFW_E_INVALIDMEDIATYPE;
}


/*  Receive multiple samples */
STDMETHODIMP
CBaseInputPin::ReceiveMultiple (
    __in_ecount(nSamples) IMediaSample **pSamples,
    long nSamples,
    __out long *nSamplesProcessed)
{
    CheckPointer(pSamples,E_POINTER);
    ValidateReadPtr(pSamples,nSamples * sizeof(IMediaSample *));

    HRESULT hr = S_OK;
    *nSamplesProcessed = 0;
    while (nSamples-- > 0) {
         hr = Receive(pSamples[*nSamplesProcessed]);

         /*  S_FALSE means don't send any more */
         if (hr != S_OK) {
             break;
         }
         (*nSamplesProcessed)++;
    }
    return hr;
}

/*  See if Receive() might block */
STDMETHODIMP
CBaseInputPin::ReceiveCanBlock()
{
    /*  Ask all the output pins if they block
        If there are no output pin assume we do block
    */
    int cPins = m_pFilter->GetPinCount();
    int cOutputPins = 0;
    for (int c = 0; c < cPins; c++) {
        CBasePin *pPin = m_pFilter->GetPin(c);
        if (NULL == pPin) {
            break;
        }
        PIN_DIRECTION pd;
        HRESULT hr = pPin->QueryDirection(&pd);
        if (FAILED(hr)) {
            return hr;
        }

        if (pd == PINDIR_OUTPUT) {

            IPin *pConnected;
            hr = pPin->ConnectedTo(&pConnected);
            if (SUCCEEDED(hr)) {
                ASSERT(pConnected != NULL);
                cOutputPins++;
                IMemInputPin *pInputPin;
                hr = pConnected->QueryInterface(
                                              IID_IMemInputPin,
                                              (void **)&pInputPin);
                pConnected->Release();
                if (SUCCEEDED(hr)) {
                    hr = pInputPin->ReceiveCanBlock();
                    pInputPin->Release();
                    if (hr != S_FALSE) {
                        return S_OK;
                    }
                } else {
                    /*  There's a transport we don't understand here */
                    return S_OK;
                }
            }
        }
    }
    return cOutputPins == 0 ? S_OK : S_FALSE;
}

// Default handling for BeginFlush - call at the beginning
// of your implementation (makes sure that all Receive calls
// fail). After calling this, you need to free any queued data
// and then call downstream.
STDMETHODIMP
CBaseInputPin::BeginFlush(void)
{
    //  BeginFlush is NOT synchronized with streaming but is part of
    //  a control action - hence we synchronize with the filter
    CAutoLock lck(m_pLock);

    // if we are already in mid-flush, this is probably a mistake
    // though not harmful - try to pick it up for now so I can think about it
    ASSERT(!m_bFlushing);

    // first thing to do is ensure that no further Receive calls succeed
    m_bFlushing = TRUE;

    // now discard any data and call downstream - must do that
    // in derived classes
    return S_OK;
}

// default handling for EndFlush - call at end of your implementation
// - before calling this, ensure that there is no queued data and no thread
// pushing any more without a further receive, then call downstream,
// then call this method to clear the m_bFlushing flag and re-enable
// receives
STDMETHODIMP
CBaseInputPin::EndFlush(void)
{
    //  Endlush is NOT synchronized with streaming but is part of
    //  a control action - hence we synchronize with the filter
    CAutoLock lck(m_pLock);

    // almost certainly a mistake if we are not in mid-flush
    ASSERT(m_bFlushing);

    // before calling, sync with pushing thread and ensure
    // no more data is going downstream, then call EndFlush on
    // downstream pins.

    // now re-enable Receives
    m_bFlushing = FALSE;

    // No more errors
    m_bRunTimeError = FALSE;

    return S_OK;
}


STDMETHODIMP
CBaseInputPin::Notify(IBaseFilter * pSender, Quality q)
{
    UNREFERENCED_PARAMETER(q);
    CheckPointer(pSender,E_POINTER);
    ValidateReadPtr(pSender,sizeof(IBaseFilter));
    DbgBreak("IQuality::Notify called on an input pin");
    return NOERROR;
} // Notify

/* Free up or unprepare allocator's memory, this is called through
   IMediaFilter which is responsible for locking the object first */

HRESULT
CBaseInputPin::Inactive(void)
{
    m_bRunTimeError = FALSE;
    if (m_pAllocator == NULL) {
        return VFW_E_NO_ALLOCATOR;
    }

    m_bFlushing = FALSE;

    return m_pAllocator->Decommit();
}

// what requirements do we have of the allocator - override if you want
// to support other people's allocators but need a specific alignment
// or prefix.
STDMETHODIMP
CBaseInputPin::GetAllocatorRequirements(__out ALLOCATOR_PROPERTIES*pProps)
{
    UNREFERENCED_PARAMETER(pProps);
    return E_NOTIMPL;
}

//  Check if it's OK to process data
//
HRESULT
CBaseInputPin::CheckStreaming()
{
    //  Shouldn't be able to get any data if we're not connected!
    ASSERT(IsConnected());

    //  Don't process stuff in Stopped state
    if (IsStopped()) {
        return VFW_E_WRONG_STATE;
    }
    if (m_bFlushing) {
        return S_FALSE;
    }
    if (m_bRunTimeError) {
        return VFW_E_RUNTIME_ERROR;
    }
    return S_OK;
}

// Pass on the Quality notification q to
// a. Our QualityControl sink (if we have one) or else
// b. to our upstream filter
// and if that doesn't work, throw it away with a bad return code
HRESULT
CBaseInputPin::PassNotify(Quality& q)
{
    // We pass the message on, which means that we find the quality sink
    // for our input pin and send it there

    DbgLog((LOG_TRACE,3,TEXT("Passing Quality notification through transform")));
    if (m_pQSink!=NULL) {
        return m_pQSink->Notify(m_pFilter, q);
    } else {
        // no sink set, so pass it upstream
        HRESULT hr;
        IQualityControl * pIQC;

        hr = VFW_E_NOT_FOUND;                   // default
        if (m_Connected) {
            m_Connected->QueryInterface(IID_IQualityControl, (void**)&pIQC);

            if (pIQC!=NULL) {
                hr = pIQC->Notify(m_pFilter, q);
                pIQC->Release();
            }
        }
        return hr;
    }

} // PassNotify

//=====================================================================
//=====================================================================
// Memory allocation class, implements CMediaSample
//=====================================================================
//=====================================================================


/* NOTE The implementation of this class calls the CUnknown constructor with
   a NULL outer unknown pointer. This has the effect of making us a self
   contained class, ie any QueryInterface, AddRef or Release calls will be
   routed to the class's NonDelegatingUnknown methods. You will typically
   find that the classes that do this then override one or more of these
   virtual functions to provide more specialised behaviour. A good example
   of this is where a class wants to keep the QueryInterface internal but
   still wants it's lifetime controlled by the external object */

/* The last two parameters have default values of NULL and zero */

CMediaSample::CMediaSample(__in_opt LPCTSTR pName,
               __in_opt CBaseAllocator *pAllocator,
               __inout_opt HRESULT *phr,
               __in_bcount_opt(length) LPBYTE pBuffer,
               LONG length) :
    m_pBuffer(pBuffer),             // Initialise the buffer
    m_cbBuffer(length),             // And it's length
    m_lActual(length),              // By default, actual = length
    m_pMediaType(NULL),             // No media type change
    m_dwFlags(0),                   // Nothing set
    m_cRef(0),                      // 0 ref count
    m_dwTypeSpecificFlags(0),       // Type specific flags
    m_dwStreamId(AM_STREAM_MEDIA),  // Stream id
    m_pAllocator(pAllocator)        // Allocator
{
#ifdef DXMPERF
    PERFLOG_CTOR( pName ? pName : L"CMediaSample", (IMediaSample *) this );
#endif // DXMPERF

    /* We must have an owner and it must also be derived from class
       CBaseAllocator BUT we do not hold a reference count on it */

    ASSERT(pAllocator);

    if (length < 0) {
        *phr = VFW_E_BUFFER_OVERFLOW;
        m_cbBuffer = 0;
    }
}

#ifdef UNICODE
CMediaSample::CMediaSample(__in_opt LPCSTR pName,
               __in_opt CBaseAllocator *pAllocator,
               __inout_opt HRESULT *phr,
               __in_bcount_opt(length) LPBYTE pBuffer,
               LONG length) :
    m_pBuffer(pBuffer),             // Initialise the buffer
    m_cbBuffer(length),             // And it's length
    m_lActual(length),              // By default, actual = length
    m_pMediaType(NULL),             // No media type change
    m_dwFlags(0),                   // Nothing set
    m_cRef(0),                      // 0 ref count
    m_dwTypeSpecificFlags(0),       // Type specific flags
    m_dwStreamId(AM_STREAM_MEDIA),  // Stream id
    m_pAllocator(pAllocator)        // Allocator
{
#ifdef DXMPERF
    PERFLOG_CTOR( L"CMediaSample", (IMediaSample *) this );
#endif // DXMPERF

    /* We must have an owner and it must also be derived from class
       CBaseAllocator BUT we do not hold a reference count on it */

    ASSERT(pAllocator);
}
#endif

/* Destructor deletes the media type memory */

CMediaSample::~CMediaSample()
{
#ifdef DXMPERF
    PERFLOG_DTOR( L"CMediaSample", (IMediaSample *) this );
#endif // DXMPERF

    if (m_pMediaType) {
    DeleteMediaType(m_pMediaType);
    }
}

/* Override this to publicise our interfaces */

STDMETHODIMP
CMediaSample::QueryInterface(REFIID riid, __deref_out void **ppv)
{
    if (riid == IID_IMediaSample ||
        riid == IID_IMediaSample2 ||
        riid == IID_IUnknown) {
        return GetInterface((IMediaSample *) this, ppv);
    } else {
        *ppv = NULL;
        return E_NOINTERFACE;
    }
}

STDMETHODIMP_(ULONG)
CMediaSample::AddRef()
{
    return InterlockedIncrement(&m_cRef);
}


// --  CMediaSample lifetimes --
//
// On final release of this sample buffer it is not deleted but
// returned to the freelist of the owning memory allocator
//
// The allocator may be waiting for the last buffer to be placed on the free
// list in order to decommit all the memory, so the ReleaseBuffer() call may
// result in this sample being deleted. We also need to hold a refcount on
// the allocator to stop that going away until we have finished with this.
// However, we cannot release the allocator before the ReleaseBuffer, as the
// release may cause us to be deleted. Similarly we can't do it afterwards.
//
// Thus we must leave it to the allocator to hold an addref on our behalf.
// When he issues us in GetBuffer, he addref's himself. When ReleaseBuffer
// is called, he releases himself, possibly causing us and him to be deleted.


STDMETHODIMP_(ULONG)
CMediaSample::Release()
{
    /* Decrement our own private reference count */
    LONG lRef;
    if (m_cRef == 1) {
        lRef = 0;
        m_cRef = 0;
    } else {
        lRef = InterlockedDecrement(&m_cRef);
    }
    ASSERT(lRef >= 0);

    DbgLog((LOG_MEMORY,3,TEXT("    Unknown %X ref-- = %d"),
        this, m_cRef));

    /* Did we release our final reference count */
    if (lRef == 0) {
        /* Free all resources */
        if (m_dwFlags & Sample_TypeChanged) {
            SetMediaType(NULL);
        }
        ASSERT(m_pMediaType == NULL);
        m_dwFlags = 0;
        m_dwTypeSpecificFlags = 0;
        m_dwStreamId = AM_STREAM_MEDIA;

        /* This may cause us to be deleted */
        // Our refcount is reliably 0 thus no-one will mess with us
        m_pAllocator->ReleaseBuffer(this);
    }
    return (ULONG)lRef;
}


// set the buffer pointer and length. Used by allocators that
// want variable sized pointers or pointers into already-read data.
// This is only available through a CMediaSample* not an IMediaSample*
// and so cannot be changed by clients.
HRESULT
CMediaSample::SetPointer(__in_bcount(cBytes) BYTE * ptr, LONG cBytes)
{
    if (cBytes < 0) {
        return VFW_E_BUFFER_OVERFLOW;
    }
    m_pBuffer = ptr;            // new buffer area (could be null)
    m_cbBuffer = cBytes;        // length of buffer
    m_lActual = cBytes;         // length of data in buffer (assume full)

    return S_OK;
}


// get me a read/write pointer to this buffer's memory. I will actually
// want to use sizeUsed bytes.
STDMETHODIMP
CMediaSample::GetPointer(__deref_out BYTE ** ppBuffer)
{
    ValidateReadWritePtr(ppBuffer,sizeof(BYTE *));

    // creator must have set pointer either during
    // constructor or by SetPointer
    ASSERT(m_pBuffer);

    *ppBuffer = m_pBuffer;
    return NOERROR;
}


// return the size in bytes of this buffer
STDMETHODIMP_(LONG)
CMediaSample::GetSize(void)
{
    return m_cbBuffer;
}


// get the stream time at which this sample should start and finish.
STDMETHODIMP
CMediaSample::GetTime(
    __out REFERENCE_TIME * pTimeStart,     // put time here
    __out REFERENCE_TIME * pTimeEnd
)
{
    ValidateReadWritePtr(pTimeStart,sizeof(REFERENCE_TIME));
    ValidateReadWritePtr(pTimeEnd,sizeof(REFERENCE_TIME));

    if (!(m_dwFlags & Sample_StopValid)) {
        if (!(m_dwFlags & Sample_TimeValid)) {
            return VFW_E_SAMPLE_TIME_NOT_SET;
        } else {
            *pTimeStart = m_Start;

            //  Make sure old stuff works
            *pTimeEnd = m_Start + 1;
            return VFW_S_NO_STOP_TIME;
        }
    }

    *pTimeStart = m_Start;
    *pTimeEnd = m_End;
    return NOERROR;
}


// Set the stream time at which this sample should start and finish.
// NULL pointers means the time is reset
STDMETHODIMP
CMediaSample::SetTime(
    __in_opt REFERENCE_TIME * pTimeStart,
    __in_opt REFERENCE_TIME * pTimeEnd
)
{
    if (pTimeStart == NULL) {
        ASSERT(pTimeEnd == NULL);
        m_dwFlags &= ~(Sample_TimeValid | Sample_StopValid);
    } else {
        if (pTimeEnd == NULL) {
            m_Start = *pTimeStart;
            m_dwFlags |= Sample_TimeValid;
            m_dwFlags &= ~Sample_StopValid;
        } else {
            ValidateReadPtr(pTimeStart,sizeof(REFERENCE_TIME));
            ValidateReadPtr(pTimeEnd,sizeof(REFERENCE_TIME));
            ASSERT(*pTimeEnd >= *pTimeStart);

            m_Start = *pTimeStart;
            m_End = *pTimeEnd;
            m_dwFlags |= Sample_TimeValid | Sample_StopValid;
        }
    }
    return NOERROR;
}


// get the media times (eg bytes) for this sample
STDMETHODIMP
CMediaSample::GetMediaTime(
    __out LONGLONG * pTimeStart,
    __out LONGLONG * pTimeEnd
)
{
    ValidateReadWritePtr(pTimeStart,sizeof(LONGLONG));
    ValidateReadWritePtr(pTimeEnd,sizeof(LONGLONG));

    if (!(m_dwFlags & Sample_MediaTimeValid)) {
        return VFW_E_MEDIA_TIME_NOT_SET;
    }

    *pTimeStart = m_MediaStart;
    *pTimeEnd = (m_MediaStart + m_MediaEnd);
    return NOERROR;
}


// Set the media times for this sample
STDMETHODIMP
CMediaSample::SetMediaTime(
    __in_opt LONGLONG * pTimeStart,
    __in_opt LONGLONG * pTimeEnd
)
{
    if (pTimeStart == NULL) {
        ASSERT(pTimeEnd == NULL);
        m_dwFlags &= ~Sample_MediaTimeValid;
    } else {
        if (NULL == pTimeEnd) {
            return E_POINTER;
        }
        ValidateReadPtr(pTimeStart,sizeof(LONGLONG));
        ValidateReadPtr(pTimeEnd,sizeof(LONGLONG));
        ASSERT(*pTimeEnd >= *pTimeStart);

        m_MediaStart = *pTimeStart;
        m_MediaEnd = (LONG)(*pTimeEnd - *pTimeStart);
        m_dwFlags |= Sample_MediaTimeValid;
    }
    return NOERROR;
}


STDMETHODIMP
CMediaSample::IsSyncPoint(void)
{
    if (m_dwFlags & Sample_SyncPoint) {
        return S_OK;
    } else {
        return S_FALSE;
    }
}


STDMETHODIMP
CMediaSample::SetSyncPoint(BOOL bIsSyncPoint)
{
    if (bIsSyncPoint) {
        m_dwFlags |= Sample_SyncPoint;
    } else {
        m_dwFlags &= ~Sample_SyncPoint;
    }
    return NOERROR;
}

// returns S_OK if there is a discontinuity in the data (this same is
// not a continuation of the previous stream of data
// - there has been a seek).
STDMETHODIMP
CMediaSample::IsDiscontinuity(void)
{
    if (m_dwFlags & Sample_Discontinuity) {
        return S_OK;
    } else {
        return S_FALSE;
    }
}

// set the discontinuity property - TRUE if this sample is not a
// continuation, but a new sample after a seek.
STDMETHODIMP
CMediaSample::SetDiscontinuity(BOOL bDiscont)
{
    // should be TRUE or FALSE
    if (bDiscont) {
        m_dwFlags |= Sample_Discontinuity;
    } else {
        m_dwFlags &= ~Sample_Discontinuity;
    }
    return S_OK;
}

STDMETHODIMP
CMediaSample::IsPreroll(void)
{
    if (m_dwFlags & Sample_Preroll) {
        return S_OK;
    } else {
        return S_FALSE;
    }
}


STDMETHODIMP
CMediaSample::SetPreroll(BOOL bIsPreroll)
{
    if (bIsPreroll) {
        m_dwFlags |= Sample_Preroll;
    } else {
        m_dwFlags &= ~Sample_Preroll;
    }
    return NOERROR;
}

STDMETHODIMP_(LONG)
CMediaSample::GetActualDataLength(void)
{
    return m_lActual;
}


STDMETHODIMP
CMediaSample::SetActualDataLength(LONG lActual)
{
    if (lActual > m_cbBuffer || lActual < 0) {
        ASSERT(lActual <= GetSize());
        return VFW_E_BUFFER_OVERFLOW;
    }
    m_lActual = lActual;
    return NOERROR;
}


/* These allow for limited format changes in band */

STDMETHODIMP
CMediaSample::GetMediaType(__deref_out AM_MEDIA_TYPE **ppMediaType)
{
    ValidateReadWritePtr(ppMediaType,sizeof(AM_MEDIA_TYPE *));
    ASSERT(ppMediaType);

    /* Do we have a new media type for them */

    if (!(m_dwFlags & Sample_TypeChanged)) {
        ASSERT(m_pMediaType == NULL);
        *ppMediaType = NULL;
        return S_FALSE;
    }

    ASSERT(m_pMediaType);

    /* Create a copy of our media type */

    *ppMediaType = CreateMediaType(m_pMediaType);
    if (*ppMediaType == NULL) {
        return E_OUTOFMEMORY;
    }
    return NOERROR;
}


/* Mark this sample as having a different format type */

STDMETHODIMP
CMediaSample::SetMediaType(__in_opt AM_MEDIA_TYPE *pMediaType)
{
    /* Delete the current media type */

    if (m_pMediaType) {
        DeleteMediaType(m_pMediaType);
        m_pMediaType = NULL;
    }

    /* Mechanism for resetting the format type */

    if (pMediaType == NULL) {
        m_dwFlags &= ~Sample_TypeChanged;
        return NOERROR;
    }

    ASSERT(pMediaType);
    ValidateReadPtr(pMediaType,sizeof(AM_MEDIA_TYPE));

    /* Take a copy of the media type */

    m_pMediaType = CreateMediaType(pMediaType);
    if (m_pMediaType == NULL) {
        m_dwFlags &= ~Sample_TypeChanged;
        return E_OUTOFMEMORY;
    }

    m_dwFlags |= Sample_TypeChanged;
    return NOERROR;
}

// Set and get properties (IMediaSample2)
STDMETHODIMP CMediaSample::GetProperties(
    DWORD cbProperties,
    __out_bcount(cbProperties) BYTE * pbProperties
)
{
    if (0 != cbProperties) {
        CheckPointer(pbProperties, E_POINTER);
        //  Return generic stuff up to the length
        AM_SAMPLE2_PROPERTIES Props;
        Props.cbData     = min(cbProperties, sizeof(Props));
        Props.dwSampleFlags = m_dwFlags & ~Sample_MediaTimeValid;
        Props.dwTypeSpecificFlags = m_dwTypeSpecificFlags;
        Props.pbBuffer   = m_pBuffer;
        Props.cbBuffer   = m_cbBuffer;
        Props.lActual    = m_lActual;
        Props.tStart     = m_Start;
        Props.tStop      = m_End;
        Props.dwStreamId = m_dwStreamId;
        if (m_dwFlags & AM_SAMPLE_TYPECHANGED) {
            Props.pMediaType = m_pMediaType;
        } else {
            Props.pMediaType = NULL;
        }
        CopyMemory(pbProperties, &Props, Props.cbData);
    }
    return S_OK;
}

#define CONTAINS_FIELD(type, field, offset) \
    ((FIELD_OFFSET(type, field) + sizeof(((type *)0)->field)) <= offset)

HRESULT CMediaSample::SetProperties(
    DWORD cbProperties,
    __in_bcount(cbProperties) const BYTE * pbProperties
)
{

    /*  Generic properties */
    AM_MEDIA_TYPE *pMediaType = NULL;

    if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, cbData, cbProperties)) {
        CheckPointer(pbProperties, E_POINTER);
        AM_SAMPLE2_PROPERTIES *pProps =
            (AM_SAMPLE2_PROPERTIES *)pbProperties;

        /*  Don't use more data than is actually there */
        if (pProps->cbData < cbProperties) {
            cbProperties = pProps->cbData;
        }
        /*  We only handle IMediaSample2 */
        if (cbProperties > sizeof(*pProps) ||
            pProps->cbData > sizeof(*pProps)) {
            return E_INVALIDARG;
        }
        /*  Do checks first, the assignments (for backout) */
        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwSampleFlags, cbProperties)) {
            /*  Check the flags */
            if (pProps->dwSampleFlags &
                    (~Sample_ValidFlags | Sample_MediaTimeValid)) {
                return E_INVALIDARG;
            }
            /*  Check a flag isn't being set for a property
                not being provided
            */
            if ((pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID) &&
                 !(m_dwFlags & AM_SAMPLE_TIMEVALID) &&
                 !CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, tStop, cbProperties)) {
                 return E_INVALIDARG;
            }
        }
        /*  NB - can't SET the pointer or size */
        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, pbBuffer, cbProperties)) {

            /*  Check pbBuffer */
            if (pProps->pbBuffer != 0 && pProps->pbBuffer != m_pBuffer) {
                return E_INVALIDARG;
            }
        }
        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, cbBuffer, cbProperties)) {

            /*  Check cbBuffer */
            if (pProps->cbBuffer != 0 && pProps->cbBuffer != m_cbBuffer) {
                return E_INVALIDARG;
            }
        }
        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, cbBuffer, cbProperties) &&
            CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, lActual, cbProperties)) {

            /*  Check lActual */
            if (pProps->cbBuffer < pProps->lActual) {
                return E_INVALIDARG;
            }
        }

        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, pMediaType, cbProperties)) {

            /*  Check pMediaType */
            if (pProps->dwSampleFlags & AM_SAMPLE_TYPECHANGED) {
                CheckPointer(pProps->pMediaType, E_POINTER);
                pMediaType = CreateMediaType(pProps->pMediaType);
                if (pMediaType == NULL) {
                    return E_OUTOFMEMORY;
                }
            }
        }

        /*  Now do the assignments */
        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwStreamId, cbProperties)) {
            m_dwStreamId = pProps->dwStreamId;
        }
        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwSampleFlags, cbProperties)) {
            /*  Set the flags */
            m_dwFlags = pProps->dwSampleFlags |
                                (m_dwFlags & Sample_MediaTimeValid);
            m_dwTypeSpecificFlags = pProps->dwTypeSpecificFlags;
        } else {
            if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwTypeSpecificFlags, cbProperties)) {
                m_dwTypeSpecificFlags = pProps->dwTypeSpecificFlags;
            }
        }

        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, lActual, cbProperties)) {
            /*  Set lActual */
            m_lActual = pProps->lActual;
        }

        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, tStop, cbProperties)) {

            /*  Set the times */
            m_End   = pProps->tStop;
        }
        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, tStart, cbProperties)) {

            /*  Set the times */
            m_Start = pProps->tStart;
        }

        if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, pMediaType, cbProperties)) {
            /*  Set pMediaType */
            if (pProps->dwSampleFlags & AM_SAMPLE_TYPECHANGED) {
                if (m_pMediaType != NULL) {
                    DeleteMediaType(m_pMediaType);
                }
                m_pMediaType = pMediaType;
            }
        }

        /*  Fix up the type changed flag to correctly reflect the current state
            If, for instance the input contained no type change but the
            output does then if we don't do this we'd lose the
            output media type.
        */
        if (m_pMediaType) {
            m_dwFlags |= Sample_TypeChanged;
        } else {
            m_dwFlags &= ~Sample_TypeChanged;
        }
    }

    return S_OK;
}


//
// The streaming thread calls IPin::NewSegment(), IPin::EndOfStream(),
// IMemInputPin::Receive() and IMemInputPin::ReceiveMultiple() on the
// connected input pin.  The application thread calls Block().  The
// following class members can only be called by the streaming thread.
//
//    Deliver()
//    DeliverNewSegment()
//    StartUsingOutputPin()
//    StopUsingOutputPin()
//    ChangeOutputFormat()
//    ChangeMediaType()
//    DynamicReconnect()
//
// The following class members can only be called by the application thread.
//
//    Block()
//    SynchronousBlockOutputPin()
//    AsynchronousBlockOutputPin()
//

CDynamicOutputPin::CDynamicOutputPin(
    __in_opt LPCTSTR pObjectName,
    __in CBaseFilter *pFilter,
    __in CCritSec *pLock,
    __inout HRESULT *phr,
    __in_opt LPCWSTR pName) :
        CBaseOutputPin(pObjectName, pFilter, pLock, phr, pName),
        m_hStopEvent(NULL),
        m_pGraphConfig(NULL),
        m_bPinUsesReadOnlyAllocator(FALSE),
        m_BlockState(NOT_BLOCKED),
        m_hUnblockOutputPinEvent(NULL),
        m_hNotifyCallerPinBlockedEvent(NULL),
        m_dwBlockCallerThreadID(0),
        m_dwNumOutstandingOutputPinUsers(0)
{
    HRESULT hr = Initialize();
    if( FAILED( hr ) ) {
        *phr = hr;
        return;
    }
}

#ifdef UNICODE
CDynamicOutputPin::CDynamicOutputPin(
    __in_opt LPCSTR pObjectName,
    __in CBaseFilter *pFilter,
    __in CCritSec *pLock,
    __inout HRESULT *phr,
    __in_opt LPCWSTR pName) :
        CBaseOutputPin(pObjectName, pFilter, pLock, phr, pName),
        m_hStopEvent(NULL),
        m_pGraphConfig(NULL),
        m_bPinUsesReadOnlyAllocator(FALSE),
        m_BlockState(NOT_BLOCKED),
        m_hUnblockOutputPinEvent(NULL),
        m_hNotifyCallerPinBlockedEvent(NULL),
        m_dwBlockCallerThreadID(0),
        m_dwNumOutstandingOutputPinUsers(0)
{
    HRESULT hr = Initialize();
    if( FAILED( hr ) ) {
        *phr = hr;
        return;
    }
}
#endif

CDynamicOutputPin::~CDynamicOutputPin()
{
    if(NULL != m_hUnblockOutputPinEvent) {
        // This call should not fail because we have access to m_hUnblockOutputPinEvent
        // and m_hUnblockOutputPinEvent is a valid event.
        EXECUTE_ASSERT(::CloseHandle(m_hUnblockOutputPinEvent));
    }

    if(NULL != m_hNotifyCallerPinBlockedEvent) {
        // This call should not fail because we have access to m_hNotifyCallerPinBlockedEvent
        // and m_hNotifyCallerPinBlockedEvent is a valid event.
        EXECUTE_ASSERT(::CloseHandle(m_hNotifyCallerPinBlockedEvent));
    }
}

HRESULT CDynamicOutputPin::Initialize(void)
{
    m_hUnblockOutputPinEvent = ::CreateEvent( NULL,   // The event will have the default security descriptor.
                                              TRUE,   // This is a manual reset event.
                                              TRUE,   // The event is initially signaled.
                                              NULL ); // The event is not named.

    // CreateEvent() returns NULL if an error occurs.
    if(NULL == m_hUnblockOutputPinEvent) {
        return AmGetLastErrorToHResult();
    }

    //  Set flag to say we can reconnect while streaming.
    SetReconnectWhenActive(true);

    return S_OK;
}

STDMETHODIMP CDynamicOutputPin::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    if(riid == IID_IPinFlowControl) {
        return GetInterface(static_cast<IPinFlowControl*>(this), ppv);
    } else {
        return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
    }
}

STDMETHODIMP CDynamicOutputPin::Disconnect(void)
{
    CAutoLock cObjectLock(m_pLock);
    return DisconnectInternal();
}

STDMETHODIMP CDynamicOutputPin::Block(DWORD dwBlockFlags, HANDLE hEvent)
{
    const DWORD VALID_FLAGS = AM_PIN_FLOW_CONTROL_BLOCK;

    // Check for illegal flags.
    if(dwBlockFlags & ~VALID_FLAGS) {
        return E_INVALIDARG;
    }

    // Make sure the event is unsignaled.
    if((dwBlockFlags & AM_PIN_FLOW_CONTROL_BLOCK) && (NULL != hEvent)) {
        if( !::ResetEvent( hEvent ) ) {
            return AmGetLastErrorToHResult();
        }
    }

    // No flags are set if we are unblocking the output pin.
    if(0 == dwBlockFlags) {

        // This parameter should be NULL because unblock operations are always synchronous.
        // There is no need to notify the caller when the event is done.
        if(NULL != hEvent) {
            return E_INVALIDARG;
        }
    }

    #ifdef DEBUG
    AssertValid();
    #endif // DEBUG

    HRESULT hr;

    if(dwBlockFlags & AM_PIN_FLOW_CONTROL_BLOCK) {
        // IPinFlowControl::Block()'s hEvent parameter is NULL if the block is synchronous.
        // If hEvent is not NULL, the block is asynchronous.
        if(NULL == hEvent) {
            hr = SynchronousBlockOutputPin();
        } else {
            hr = AsynchronousBlockOutputPin(hEvent);
        }
    } else {
        hr = UnblockOutputPin();
    }

    #ifdef DEBUG
    AssertValid();
    #endif // DEBUG

    if(FAILED(hr)) {
        return hr;
    }

    return S_OK;
}

HRESULT CDynamicOutputPin::SynchronousBlockOutputPin(void)
{
    HANDLE hNotifyCallerPinBlockedEvent = :: CreateEvent( NULL,   // The event will have the default security attributes.
                                                          FALSE,  // This is an automatic reset event.
                                                          FALSE,  // The event is initially unsignaled.
                                                          NULL ); // The event is not named.

    // CreateEvent() returns NULL if an error occurs.
    if(NULL == hNotifyCallerPinBlockedEvent) {
        return AmGetLastErrorToHResult();
    }

    HRESULT hr = AsynchronousBlockOutputPin(hNotifyCallerPinBlockedEvent);
    if(FAILED(hr)) {
        // This call should not fail because we have access to hNotifyCallerPinBlockedEvent
        // and hNotifyCallerPinBlockedEvent is a valid event.
        EXECUTE_ASSERT(::CloseHandle(hNotifyCallerPinBlockedEvent));

        return hr;
    }

    hr = WaitEvent(hNotifyCallerPinBlockedEvent);

    // This call should not fail because we have access to hNotifyCallerPinBlockedEvent
    // and hNotifyCallerPinBlockedEvent is a valid event.
    EXECUTE_ASSERT(::CloseHandle(hNotifyCallerPinBlockedEvent));

    if(FAILED(hr)) {
        return hr;
    }

    return S_OK;
}

HRESULT CDynamicOutputPin::AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent)
{
    // This function holds the m_BlockStateLock because it uses
    // m_dwBlockCallerThreadID, m_BlockState and
    // m_hNotifyCallerPinBlockedEvent.
    CAutoLock alBlockStateLock(&m_BlockStateLock);

    if(NOT_BLOCKED != m_BlockState) {
        if(m_dwBlockCallerThreadID == ::GetCurrentThreadId()) {
            return VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD;
        } else {
            return VFW_E_PIN_ALREADY_BLOCKED;
        }
    }

    BOOL fSuccess = ::DuplicateHandle( ::GetCurrentProcess(),
                                       hNotifyCallerPinBlockedEvent,
                                       ::GetCurrentProcess(),
                                       &m_hNotifyCallerPinBlockedEvent,
                                       EVENT_MODIFY_STATE,
                                       FALSE,
                                       0 );
    if( !fSuccess ) {
        return AmGetLastErrorToHResult();
    }

    m_BlockState = PENDING;
    m_dwBlockCallerThreadID = ::GetCurrentThreadId();

    // The output pin cannot be blocked if the streaming thread is
    // calling IPin::NewSegment(), IPin::EndOfStream(), IMemInputPin::Receive()
    // or IMemInputPin::ReceiveMultiple() on the connected input pin.  Also, it
    // cannot be blocked if the streaming thread is calling DynamicReconnect(),
    // ChangeMediaType() or ChangeOutputFormat().
    if(!StreamingThreadUsingOutputPin()) {

        // The output pin can be immediately blocked.
        BlockOutputPin();
    }

    return S_OK;
}

void CDynamicOutputPin::BlockOutputPin(void)
{
    // The caller should always hold the m_BlockStateLock because this function
    // uses m_BlockState and m_hNotifyCallerPinBlockedEvent.
    ASSERT(CritCheckIn(&m_BlockStateLock));

    // This function should not be called if the streaming thread is modifying
    // the connection state or it's passing data downstream.
    ASSERT(!StreamingThreadUsingOutputPin());

    // This should not fail because we successfully created the event
    // and we have the security permissions to change it's state.
    EXECUTE_ASSERT(::ResetEvent(m_hUnblockOutputPinEvent));

    // This event should not fail because AsynchronousBlockOutputPin() successfully
    // duplicated this handle and we have the appropriate security permissions.
    EXECUTE_ASSERT(::SetEvent(m_hNotifyCallerPinBlockedEvent));
    EXECUTE_ASSERT(::CloseHandle(m_hNotifyCallerPinBlockedEvent));

    m_BlockState = BLOCKED;
    m_hNotifyCallerPinBlockedEvent = NULL;
}

HRESULT CDynamicOutputPin::UnblockOutputPin(void)
{
    // UnblockOutputPin() holds the m_BlockStateLock because it
    // uses m_BlockState, m_dwBlockCallerThreadID and
    // m_hNotifyCallerPinBlockedEvent.
    CAutoLock alBlockStateLock(&m_BlockStateLock);

    if(NOT_BLOCKED == m_BlockState) {
        return S_FALSE;
    }

    // This should not fail because we successfully created the event
    // and we have the security permissions to change it's state.
    EXECUTE_ASSERT(::SetEvent(m_hUnblockOutputPinEvent));

    // Cancel the block operation if it's still pending.
    if(NULL != m_hNotifyCallerPinBlockedEvent) {
        // This event should not fail because AsynchronousBlockOutputPin() successfully
        // duplicated this handle and we have the appropriate security permissions.
        EXECUTE_ASSERT(::SetEvent(m_hNotifyCallerPinBlockedEvent));
        EXECUTE_ASSERT(::CloseHandle(m_hNotifyCallerPinBlockedEvent));
    }

    m_BlockState = NOT_BLOCKED;
    m_dwBlockCallerThreadID = 0;
    m_hNotifyCallerPinBlockedEvent = NULL;

    return S_OK;
}

HRESULT CDynamicOutputPin::StartUsingOutputPin(void)
{
    // The caller should not hold m_BlockStateLock.  If the caller does,
    // a deadlock could occur.
    ASSERT(CritCheckOut(&m_BlockStateLock));

    CAutoLock alBlockStateLock(&m_BlockStateLock);

    #ifdef DEBUG
    AssertValid();
    #endif // DEBUG

    // Are we in the middle of a block operation?
    while(BLOCKED == m_BlockState) {
        m_BlockStateLock.Unlock();

        // If this ASSERT fires, a deadlock could occur.  The caller should make sure
        // that this thread never acquires the Block State lock more than once.
        ASSERT(CritCheckOut( &m_BlockStateLock ));

        // WaitForMultipleObjects() returns WAIT_OBJECT_0 if the unblock event
        // is fired.  It returns WAIT_OBJECT_0 + 1 if the stop event if fired.
        // See the Windows SDK documentation for more information on
        // WaitForMultipleObjects().
        const DWORD UNBLOCK = WAIT_OBJECT_0;
        const DWORD STOP = WAIT_OBJECT_0 + 1;

        HANDLE ahWaitEvents[] = { m_hUnblockOutputPinEvent, m_hStopEvent };
        DWORD dwNumWaitEvents = sizeof(ahWaitEvents)/sizeof(HANDLE);

        DWORD dwReturnValue = ::WaitForMultipleObjects( dwNumWaitEvents, ahWaitEvents, FALSE, INFINITE );

        m_BlockStateLock.Lock();

        #ifdef DEBUG
        AssertValid();
        #endif // DEBUG

        switch( dwReturnValue ) {
        case UNBLOCK:
            break;

        case STOP:
            return VFW_E_STATE_CHANGED;

        case WAIT_FAILED:
            return AmGetLastErrorToHResult();

        default:
            DbgBreak( "An Unexpected case occured in CDynamicOutputPin::StartUsingOutputPin()." );
            return E_UNEXPECTED;
        }
    }

    m_dwNumOutstandingOutputPinUsers++;

    #ifdef DEBUG
    AssertValid();
    #endif // DEBUG

    return S_OK;
}

void CDynamicOutputPin::StopUsingOutputPin(void)
{
    CAutoLock alBlockStateLock(&m_BlockStateLock);

    #ifdef DEBUG
    AssertValid();
    #endif // DEBUG

    m_dwNumOutstandingOutputPinUsers--;

    if((m_dwNumOutstandingOutputPinUsers == 0) && (NOT_BLOCKED != m_BlockState)) {
        BlockOutputPin();
    }

    #ifdef DEBUG
    AssertValid();
    #endif // DEBUG
}

bool CDynamicOutputPin::StreamingThreadUsingOutputPin(void)
{
    CAutoLock alBlockStateLock(&m_BlockStateLock);

    return (m_dwNumOutstandingOutputPinUsers > 0);
}

void CDynamicOutputPin::SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent)
{
    // This pointer is not addrefed because filters are not allowed to
    // hold references to the filter graph manager.  See the documentation for
    // IBaseFilter::JoinFilterGraph() in the Direct Show SDK for more information.
    m_pGraphConfig = pGraphConfig;

    m_hStopEvent = hStopEvent;
}

HRESULT CDynamicOutputPin::Active(void)
{
    // Make sure the user initialized the object by calling SetConfigInfo().
    if((NULL == m_hStopEvent) || (NULL == m_pGraphConfig)) {
        DbgBreak( ERROR: CDynamicOutputPin::Active() failed because m_pGraphConfig and m_hStopEvent were not initialized.  Call SetConfigInfo() to initialize them. );
        return E_FAIL;
    }

    // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo().
    // The ASSERT can also fire if the event if destroyed and then Active() is called.  An event
    // handle is invalid if 1) the event does not exist or the user does not have the security
    // permissions to use the event.
    EXECUTE_ASSERT(ResetEvent(m_hStopEvent));

    return CBaseOutputPin::Active();
}

HRESULT CDynamicOutputPin::Inactive(void)
{
    // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo().
    // The ASSERT can also fire if the event if destroyed and then Active() is called.  An event
    // handle is invalid if 1) the event does not exist or the user does not have the security
    // permissions to use the event.
    EXECUTE_ASSERT(SetEvent(m_hStopEvent));

    return CBaseOutputPin::Inactive();
}

HRESULT CDynamicOutputPin::DeliverBeginFlush(void)
{
    // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo().
    // The ASSERT can also fire if the event if destroyed and then DeliverBeginFlush() is called.
    // An event handle is invalid if 1) the event does not exist or the user does not have the security
    // permissions to use the event.
    EXECUTE_ASSERT(SetEvent(m_hStopEvent));

    return CBaseOutputPin::DeliverBeginFlush();
}

HRESULT CDynamicOutputPin::DeliverEndFlush(void)
{
    // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo().
    // The ASSERT can also fire if the event if destroyed and then DeliverBeginFlush() is called.
    // An event handle is invalid if 1) the event does not exist or the user does not have the security
    // permissions to use the event.
    EXECUTE_ASSERT(ResetEvent(m_hStopEvent));

    return CBaseOutputPin::DeliverEndFlush();
}


// ChangeOutputFormat() either dynamicly changes the connection's format type or it dynamicly
// reconnects the output pin.
HRESULT CDynamicOutputPin::ChangeOutputFormat
    (
    const AM_MEDIA_TYPE *pmt,
    REFERENCE_TIME tSegmentStart,
    REFERENCE_TIME tSegmentStop,
    double dSegmentRate
    )
{
    // The caller should call StartUsingOutputPin() before calling this
    // method.
    ASSERT(StreamingThreadUsingOutputPin());

    // Callers should always pass a valid media type to ChangeOutputFormat() .
    ASSERT(NULL != pmt);

    CMediaType cmt(*pmt);
    HRESULT hr = ChangeMediaType(&cmt);
    if (FAILED(hr)) {
        return hr;
    }

    hr = DeliverNewSegment(tSegmentStart, tSegmentStop, dSegmentRate);
    if( FAILED( hr ) ) {
        return hr;
    }

    return S_OK;
}

HRESULT CDynamicOutputPin::ChangeMediaType(const CMediaType *pmt)
{
    // The caller should call StartUsingOutputPin() before calling this
    // method.
    ASSERT(StreamingThreadUsingOutputPin());

    // This function assumes the filter graph is running.
    ASSERT(!IsStopped());

    if(!IsConnected()) {
        return VFW_E_NOT_CONNECTED;
    }

    /*  First check if the downstream pin will accept a dynamic
        format change
    */
    QzCComPtr<IPinConnection> pConnection;

    m_Connected->QueryInterface(IID_IPinConnection, (void **)&pConnection);
    if(pConnection != NULL) {

        if(S_OK == pConnection->DynamicQueryAccept(pmt)) {

            HRESULT hr = ChangeMediaTypeHelper(pmt);
            if(FAILED(hr)) {
                return hr;
            }

            return S_OK;
        }
    }

    /*  Can't do the dynamic connection */
    return DynamicReconnect(pmt);
}

HRESULT CDynamicOutputPin::ChangeMediaTypeHelper(const CMediaType *pmt)
{
    // The caller should call StartUsingOutputPin() before calling this
    // method.
    ASSERT(StreamingThreadUsingOutputPin());

    HRESULT hr = m_Connected->ReceiveConnection(this, pmt);
    if(FAILED(hr)) {
        return hr;
    }

    hr = SetMediaType(pmt);
    if(FAILED(hr)) {
        return hr;
    }

    // Does this pin use the local memory transport?
    if(NULL != m_pInputPin) {
        // This function assumes that m_pInputPin and m_Connected are
        // two different interfaces to the same object.
        ASSERT(::IsEqualObject(m_Connected, m_pInputPin));

        ALLOCATOR_PROPERTIES apInputPinRequirements;
        apInputPinRequirements.cbAlign = 0;
        apInputPinRequirements.cbBuffer = 0;
        apInputPinRequirements.cbPrefix = 0;
        apInputPinRequirements.cBuffers = 0;

        m_pInputPin->GetAllocatorRequirements(&apInputPinRequirements);

        // A zero allignment does not make any sense.
        if(0 == apInputPinRequirements.cbAlign) {
            apInputPinRequirements.cbAlign = 1;
        }

        hr = m_pAllocator->Decommit();
        if(FAILED(hr)) {
            return hr;
        }

        hr = DecideBufferSize(m_pAllocator,  &apInputPinRequirements);
        if(FAILED(hr)) {
            return hr;
        }

        hr = m_pAllocator->Commit();
        if(FAILED(hr)) {
            return hr;
        }

        hr = m_pInputPin->NotifyAllocator(m_pAllocator, m_bPinUsesReadOnlyAllocator);
        if(FAILED(hr)) {
            return hr;
        }
    }

    return S_OK;
}

// this method has to be called from the thread that is pushing data,
// and it's the caller's responsibility to make sure that the thread
// has no outstand samples because they cannot be delivered after a
// reconnect
//
HRESULT CDynamicOutputPin::DynamicReconnect( const CMediaType* pmt )
{
    // The caller should call StartUsingOutputPin() before calling this
    // method.
    ASSERT(StreamingThreadUsingOutputPin());

    if((m_pGraphConfig == NULL) || (NULL == m_hStopEvent)) {
        return E_FAIL;
    }

    HRESULT hr = m_pGraphConfig->Reconnect(
        this,
        NULL,
        pmt,
        NULL,
        m_hStopEvent,
        AM_GRAPH_CONFIG_RECONNECT_CACHE_REMOVED_FILTERS );

    return hr;
}

HRESULT CDynamicOutputPin::CompleteConnect(IPin *pReceivePin)
{
    HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin);
    if(SUCCEEDED(hr)) {
        if(!IsStopped() && m_pAllocator) {
            hr = m_pAllocator->Commit();
            ASSERT(hr != VFW_E_ALREADY_COMMITTED);
        }
    }

    return hr;
}

#ifdef DEBUG
void CDynamicOutputPin::AssertValid(void)
{
    // Make sure the object was correctly initialized.

    // This ASSERT only fires if the object failed to initialize
    // and the user ignored the constructor's return code (phr).
    ASSERT(NULL != m_hUnblockOutputPinEvent);

    // If either of these ASSERTs fire, the user did not correctly call
    // SetConfigInfo().
    ASSERT(NULL != m_hStopEvent);
    ASSERT(NULL != m_pGraphConfig);

    // Make sure the block state is consistent.

    CAutoLock alBlockStateLock(&m_BlockStateLock);

    // BLOCK_STATE variables only have three legal values: PENDING, BLOCKED and NOT_BLOCKED.
    ASSERT((NOT_BLOCKED == m_BlockState) || (PENDING == m_BlockState) || (BLOCKED == m_BlockState));

    // m_hNotifyCallerPinBlockedEvent is only needed when a block operation cannot complete
    // immediately.
    ASSERT(((NULL == m_hNotifyCallerPinBlockedEvent) && (PENDING != m_BlockState)) ||
           ((NULL != m_hNotifyCallerPinBlockedEvent) && (PENDING == m_BlockState)) );

    // m_dwBlockCallerThreadID should always be 0 if the pin is not blocked and
    // the user is not trying to block the pin.
    ASSERT((0 == m_dwBlockCallerThreadID) || (NOT_BLOCKED != m_BlockState));

    // If this ASSERT fires, the streaming thread is using the output pin and the
    // output pin is blocked.
    ASSERT(((0 != m_dwNumOutstandingOutputPinUsers) && (BLOCKED != m_BlockState)) ||
           ((0 == m_dwNumOutstandingOutputPinUsers) && (NOT_BLOCKED != m_BlockState)) ||
           ((0 == m_dwNumOutstandingOutputPinUsers) && (NOT_BLOCKED == m_BlockState)) );
}
#endif // DEBUG

HRESULT CDynamicOutputPin::WaitEvent(HANDLE hEvent)
{
    const DWORD EVENT_SIGNALED = WAIT_OBJECT_0;

    DWORD dwReturnValue = ::WaitForSingleObject(hEvent, INFINITE);

    switch( dwReturnValue ) {
    case EVENT_SIGNALED:
        return S_OK;

    case WAIT_FAILED:
        return AmGetLastErrorToHResult();

    default:
        DbgBreak( "An Unexpected case occured in CDynamicOutputPin::WaitEvent()." );
        return E_UNEXPECTED;
    }
}

//=====================================================================
//=====================================================================
// Implements CBaseAllocator
//=====================================================================
//=====================================================================


/* Constructor overrides the default settings for the free list to request
   that it be alertable (ie the list can be cast to a handle which can be
   passed to WaitForSingleObject). Both of the allocator lists also ask for
   object locking, the all list matches the object default settings but I
   have included them here just so it is obvious what kind of list it is */

CBaseAllocator::CBaseAllocator(__in_opt LPCTSTR pName,
                               __inout_opt LPUNKNOWN pUnk,
                               __inout HRESULT *phr,
                               BOOL bEvent,
                               BOOL fEnableReleaseCallback
                               ) :
    CUnknown(pName, pUnk),
    m_lAllocated(0),
    m_bChanged(FALSE),
    m_bCommitted(FALSE),
    m_bDecommitInProgress(FALSE),
    m_lSize(0),
    m_lCount(0),
    m_lAlignment(0),
    m_lPrefix(0),
    m_hSem(NULL),
    m_lWaiting(0),
    m_fEnableReleaseCallback(fEnableReleaseCallback),
    m_pNotify(NULL)
{
#ifdef DXMPERF
    PERFLOG_CTOR( pName ? pName : L"CBaseAllocator", (IMemAllocator *) this );
#endif // DXMPERF

    if (bEvent) {
        m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
        if (m_hSem == NULL) {
            *phr = E_OUTOFMEMORY;
            return;
        }
    }
}

#ifdef UNICODE
CBaseAllocator::CBaseAllocator(__in_opt LPCSTR pName,
                               __inout_opt LPUNKNOWN pUnk,
                               __inout HRESULT *phr,
                               BOOL bEvent,
                               BOOL fEnableReleaseCallback) :
    CUnknown(pName, pUnk),
    m_lAllocated(0),
    m_bChanged(FALSE),
    m_bCommitted(FALSE),
    m_bDecommitInProgress(FALSE),
    m_lSize(0),
    m_lCount(0),
    m_lAlignment(0),
    m_lPrefix(0),
    m_hSem(NULL),
    m_lWaiting(0),
    m_fEnableReleaseCallback(fEnableReleaseCallback),
    m_pNotify(NULL)
{
#ifdef DXMPERF
    PERFLOG_CTOR( L"CBaseAllocator", (IMemAllocator *) this );
#endif // DXMPERF

    if (bEvent) {
        m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL);
        if (m_hSem == NULL) {
            *phr = E_OUTOFMEMORY;
            return;
        }
    }
}
#endif

/* Destructor */

CBaseAllocator::~CBaseAllocator()
{
    // we can't call Decommit here since that would mean a call to a
    // pure virtual in destructor.
    // We must assume that the derived class has gone into decommit state in
    // its destructor.
#ifdef DXMPERF
    PERFLOG_DTOR( L"CBaseAllocator", (IMemAllocator *) this );
#endif // DXMPERF

    ASSERT(!m_bCommitted);
    if (m_hSem != NULL) {
        EXECUTE_ASSERT(CloseHandle(m_hSem));
    }
    if (m_pNotify) {
        m_pNotify->Release();
    }
}


/* Override this to publicise our interfaces */

STDMETHODIMP
CBaseAllocator::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    /* Do we know about this interface */

    if (riid == IID_IMemAllocator ||
        riid == IID_IMemAllocatorCallbackTemp && m_fEnableReleaseCallback) {
        return GetInterface((IMemAllocatorCallbackTemp *) this, ppv);
    } else {
        return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


/* This sets the size and count of the required samples. The memory isn't
   actually allocated until Commit() is called, if memory has already been
   allocated then assuming no samples are outstanding the user may call us
   to change the buffering, the memory will be released in Commit() */

STDMETHODIMP
CBaseAllocator::SetProperties(
                __in ALLOCATOR_PROPERTIES* pRequest,
                __out ALLOCATOR_PROPERTIES* pActual)
{
    CheckPointer(pRequest, E_POINTER);
    CheckPointer(pActual, E_POINTER);
    ValidateReadWritePtr(pActual, sizeof(ALLOCATOR_PROPERTIES));
    CAutoLock cObjectLock(this);

    ZeroMemory(pActual, sizeof(ALLOCATOR_PROPERTIES));

    ASSERT(pRequest->cbBuffer > 0);

    /*  Check the alignment requested */
    if (pRequest->cbAlign != 1) {
        DbgLog((LOG_ERROR, 2, TEXT("Alignment requested was 0x%x, not 1"),
               pRequest->cbAlign));
        return VFW_E_BADALIGN;
    }

    /* Can't do this if already committed, there is an argument that says we
       should not reject the SetProperties call if there are buffers still
       active. However this is called by the source filter, which is the same
       person who is holding the samples. Therefore it is not unreasonable
       for them to free all their samples before changing the requirements */

    if (m_bCommitted) {
        return VFW_E_ALREADY_COMMITTED;
    }

    /* Must be no outstanding buffers */

    if (m_lAllocated != m_lFree.GetCount()) {
        return VFW_E_BUFFERS_OUTSTANDING;
    }

    /* There isn't any real need to check the parameters as they
       will just be rejected when the user finally calls Commit */

    pActual->cbBuffer = m_lSize = pRequest->cbBuffer;
    pActual->cBuffers = m_lCount = pRequest->cBuffers;
    pActual->cbAlign = m_lAlignment = pRequest->cbAlign;
    pActual->cbPrefix = m_lPrefix = pRequest->cbPrefix;

    m_bChanged = TRUE;
    return NOERROR;
}

STDMETHODIMP
CBaseAllocator::GetProperties(
    __out ALLOCATOR_PROPERTIES * pActual)
{
    CheckPointer(pActual,E_POINTER);
    ValidateReadWritePtr(pActual,sizeof(ALLOCATOR_PROPERTIES));

    CAutoLock cObjectLock(this);
    pActual->cbBuffer = m_lSize;
    pActual->cBuffers = m_lCount;
    pActual->cbAlign = m_lAlignment;
    pActual->cbPrefix = m_lPrefix;
    return NOERROR;
}

// get container for a sample. Blocking, synchronous call to get the
// next free buffer (as represented by an IMediaSample interface).
// on return, the time etc properties will be invalid, but the buffer
// pointer and size will be correct.

HRESULT CBaseAllocator::GetBuffer(__deref_out IMediaSample **ppBuffer,
                                  __in_opt REFERENCE_TIME *pStartTime,
                                  __in_opt REFERENCE_TIME *pEndTime,
                                  DWORD dwFlags
                                  )
{
    UNREFERENCED_PARAMETER(pStartTime);
    UNREFERENCED_PARAMETER(pEndTime);
    UNREFERENCED_PARAMETER(dwFlags);
    CMediaSample *pSample;

    *ppBuffer = NULL;
    for (;;)
    {
        {  // scope for lock
            CAutoLock cObjectLock(this);

            /* Check we are committed */
            if (!m_bCommitted) {
                return VFW_E_NOT_COMMITTED;
            }
            pSample = (CMediaSample *) m_lFree.RemoveHead();
            if (pSample == NULL) {
                SetWaiting();
            }
        }

        /* If we didn't get a sample then wait for the list to signal */

        if (pSample) {
            break;
        }
        if (dwFlags & AM_GBF_NOWAIT) {
            return VFW_E_TIMEOUT;
        }
        ASSERT(m_hSem != NULL);
        WaitForSingleObject(m_hSem, INFINITE);
    }

    /* Addref the buffer up to one. On release
       back to zero instead of being deleted, it will requeue itself by
       calling the ReleaseBuffer member function. NOTE the owner of a
       media sample must always be derived from CBaseAllocator */


    ASSERT(pSample->m_cRef == 0);
    pSample->m_cRef = 1;
    *ppBuffer = pSample;

#ifdef DXMPERF
    PERFLOG_GETBUFFER( (IMemAllocator *) this, pSample );
#endif // DXMPERF

    return NOERROR;
}


/* Final release of a CMediaSample will call this */

STDMETHODIMP
CBaseAllocator::ReleaseBuffer(IMediaSample * pSample)
{
    CheckPointer(pSample,E_POINTER);
    ValidateReadPtr(pSample,sizeof(IMediaSample));

#ifdef DXMPERF
    PERFLOG_RELBUFFER( (IMemAllocator *) this, pSample );
#endif // DXMPERF


    BOOL bRelease = FALSE;
    {
        CAutoLock cal(this);

        /* Put back on the free list */

        m_lFree.Add((CMediaSample *)pSample);
        if (m_lWaiting != 0) {
            NotifySample();
        }

        // if there is a pending Decommit, then we need to complete it by
        // calling Free() when the last buffer is placed on the free list

        LONG l1 = m_lFree.GetCount();
        if (m_bDecommitInProgress && (l1 == m_lAllocated)) {
            Free();
            m_bDecommitInProgress = FALSE;
            bRelease = TRUE;
        }
    }

    if (m_pNotify) {

        ASSERT(m_fEnableReleaseCallback);

        //
        // Note that this is not synchronized with setting up a notification
        // method.
        //
        m_pNotify->NotifyRelease();
    }

    /* For each buffer there is one AddRef, made in GetBuffer and released
       here. This may cause the allocator and all samples to be deleted */

    if (bRelease) {
        Release();
    }
    return NOERROR;
}

STDMETHODIMP
CBaseAllocator::SetNotify(
    IMemAllocatorNotifyCallbackTemp* pNotify
    )
{
    ASSERT(m_fEnableReleaseCallback);
    CAutoLock lck(this);
    if (pNotify) {
        pNotify->AddRef();
    }
    if (m_pNotify) {
        m_pNotify->Release();
    }
    m_pNotify = pNotify;
    return S_OK;
}

STDMETHODIMP
CBaseAllocator::GetFreeCount(
    __out LONG* plBuffersFree
    )
{
    ASSERT(m_fEnableReleaseCallback);
    CAutoLock cObjectLock(this);
    *plBuffersFree = m_lCount - m_lAllocated + m_lFree.GetCount();
    return NOERROR;
}

void
CBaseAllocator::NotifySample()
{
    if (m_lWaiting != 0) {
        ASSERT(m_hSem != NULL);
        ReleaseSemaphore(m_hSem, m_lWaiting, 0);
        m_lWaiting = 0;
    }
}

STDMETHODIMP
CBaseAllocator::Commit()
{
    /* Check we are not decommitted */
    CAutoLock cObjectLock(this);

    // cannot need to alloc or re-alloc if we are committed
    if (m_bCommitted) {
        return NOERROR;
    }

    /* Allow GetBuffer calls */

    m_bCommitted = TRUE;

    // is there a pending decommit ? if so, just cancel it
    if (m_bDecommitInProgress) {
        m_bDecommitInProgress = FALSE;

        // don't call Alloc at this point. He cannot allow SetProperties
        // between Decommit and the last free, so the buffer size cannot have
        // changed. And because some of the buffers are not free yet, he
        // cannot re-alloc anyway.
        return NOERROR;
    }

    DbgLog((LOG_MEMORY, 1, TEXT("Allocating: %ldx%ld"), m_lCount, m_lSize));

    // actually need to allocate the samples
    HRESULT hr = Alloc();
    if (FAILED(hr)) {
        m_bCommitted = FALSE;
        return hr;
    }
    AddRef();
    return NOERROR;
}


STDMETHODIMP
CBaseAllocator::Decommit()
{
    BOOL bRelease = FALSE;
    {
        /* Check we are not already decommitted */
        CAutoLock cObjectLock(this);
        if (m_bCommitted == FALSE) {
            if (m_bDecommitInProgress == FALSE) {
                return NOERROR;
            }
        }

        /* No more GetBuffer calls will succeed */
        m_bCommitted = FALSE;

        // are any buffers outstanding?
        if (m_lFree.GetCount() < m_lAllocated) {
            // please complete the decommit when last buffer is freed
            m_bDecommitInProgress = TRUE;
        } else {
            m_bDecommitInProgress = FALSE;

            // need to complete the decommit here as there are no
            // outstanding buffers

            Free();
            bRelease = TRUE;
        }

        // Tell anyone waiting that they can go now so we can
        // reject their call
#pragma warning(push)
#ifndef _PREFAST_
#pragma warning(disable:4068)
#endif
#pragma prefast(suppress:__WARNING_DEREF_NULL_PTR, "Suppress warning related to Free() invalidating 'this' which is no applicable to CBaseAllocator::Free()")
        NotifySample();

#pragma warning(pop)
    }

    if (bRelease) {
        Release();
    }
    return NOERROR;
}


/* Base definition of allocation which checks we are ok to go ahead and do
   the full allocation. We return S_FALSE if the requirements are the same */

HRESULT
CBaseAllocator::Alloc(void)
{
    /* Error if he hasn't set the size yet */
    if (m_lCount <= 0 || m_lSize <= 0 || m_lAlignment <= 0) {
        return VFW_E_SIZENOTSET;
    }

    /* should never get here while buffers outstanding */
    ASSERT(m_lFree.GetCount() == m_lAllocated);

    /* If the requirements haven't changed then don't reallocate */
    if (m_bChanged == FALSE) {
        return S_FALSE;
    }

    return NOERROR;
}

/*  Implement CBaseAllocator::CSampleList::Remove(pSample)
    Removes pSample from the list
*/
void
CBaseAllocator::CSampleList::Remove(__inout CMediaSample * pSample)
{
    CMediaSample **pSearch;
    for (pSearch = &m_List;
         *pSearch != NULL;
         pSearch = &(CBaseAllocator::NextSample(*pSearch))) {
       if (*pSearch == pSample) {
           *pSearch = CBaseAllocator::NextSample(pSample);
           CBaseAllocator::NextSample(pSample) = NULL;
           m_nOnList--;
           return;
       }
    }
    DbgBreak("Couldn't find sample in list");
}

//=====================================================================
//=====================================================================
// Implements CMemAllocator
//=====================================================================
//=====================================================================


/* This goes in the factory template table to create new instances */
CUnknown *CMemAllocator::CreateInstance(__inout_opt LPUNKNOWN pUnk, __inout HRESULT *phr)
{
    CUnknown *pUnkRet = new CMemAllocator(NAME("CMemAllocator"), pUnk, phr);
    return pUnkRet;
}

CMemAllocator::CMemAllocator(
    __in_opt LPCTSTR pName,
    __inout_opt LPUNKNOWN pUnk,
    __inout HRESULT *phr)
    : CBaseAllocator(pName, pUnk, phr, TRUE, TRUE),
    m_pBuffer(NULL)
{
}

#ifdef UNICODE
CMemAllocator::CMemAllocator(
    __in_opt LPCSTR pName,
    __inout_opt LPUNKNOWN pUnk,
    __inout HRESULT *phr)
    : CBaseAllocator(pName, pUnk, phr, TRUE, TRUE),
    m_pBuffer(NULL)
{
}
#endif

/* This sets the size and count of the required samples. The memory isn't
   actually allocated until Commit() is called, if memory has already been
   allocated then assuming no samples are outstanding the user may call us
   to change the buffering, the memory will be released in Commit() */
STDMETHODIMP
CMemAllocator::SetProperties(
                __in ALLOCATOR_PROPERTIES* pRequest,
                __out ALLOCATOR_PROPERTIES* pActual)
{
    CheckPointer(pActual,E_POINTER);
    ValidateReadWritePtr(pActual,sizeof(ALLOCATOR_PROPERTIES));
    CAutoLock cObjectLock(this);

    ZeroMemory(pActual, sizeof(ALLOCATOR_PROPERTIES));

    ASSERT(pRequest->cbBuffer > 0);

    SYSTEM_INFO SysInfo;
    GetSystemInfo(&SysInfo);

    /*  Check the alignment request is a power of 2 */
    if ((-pRequest->cbAlign & pRequest->cbAlign) != pRequest->cbAlign) {
        DbgLog((LOG_ERROR, 1, TEXT("Alignment requested 0x%x not a power of 2!"),
               pRequest->cbAlign));
    }
    /*  Check the alignment requested */
    if (pRequest->cbAlign == 0 ||
    (SysInfo.dwAllocationGranularity & (pRequest->cbAlign - 1)) != 0) {
        DbgLog((LOG_ERROR, 1, TEXT("Invalid alignment 0x%x requested - granularity = 0x%x"),
               pRequest->cbAlign, SysInfo.dwAllocationGranularity));
        return VFW_E_BADALIGN;
    }

    /* Can't do this if already committed, there is an argument that says we
       should not reject the SetProperties call if there are buffers still
       active. However this is called by the source filter, which is the same
       person who is holding the samples. Therefore it is not unreasonable
       for them to free all their samples before changing the requirements */

    if (m_bCommitted == TRUE) {
        return VFW_E_ALREADY_COMMITTED;
    }

    /* Must be no outstanding buffers */

    if (m_lFree.GetCount() < m_lAllocated) {
        return VFW_E_BUFFERS_OUTSTANDING;
    }

    /* There isn't any real need to check the parameters as they
       will just be rejected when the user finally calls Commit */

    // round length up to alignment - remember that prefix is included in
    // the alignment
    LONG lSize = pRequest->cbBuffer + pRequest->cbPrefix;
    LONG lRemainder = lSize % pRequest->cbAlign;
    if (lRemainder != 0) {
        lSize = lSize - lRemainder + pRequest->cbAlign;
    }
    pActual->cbBuffer = m_lSize = (lSize - pRequest->cbPrefix);

    pActual->cBuffers = m_lCount = pRequest->cBuffers;
    pActual->cbAlign = m_lAlignment = pRequest->cbAlign;
    pActual->cbPrefix = m_lPrefix = pRequest->cbPrefix;

    m_bChanged = TRUE;
    return NOERROR;
}

// override this to allocate our resources when Commit is called.
//
// note that our resources may be already allocated when this is called,
// since we don't free them on Decommit. We will only be called when in
// decommit state with all buffers free.
//
// object locked by caller
HRESULT
CMemAllocator::Alloc(void)
{
    CAutoLock lck(this);

    /* Check he has called SetProperties */
    HRESULT hr = CBaseAllocator::Alloc();
    if (FAILED(hr)) {
        return hr;
    }

    /* If the requirements haven't changed then don't reallocate */
    if (hr == S_FALSE) {
        ASSERT(m_pBuffer);
        return NOERROR;
    }
    ASSERT(hr == S_OK); // we use this fact in the loop below

    /* Free the old resources */
    if (m_pBuffer) {
        ReallyFree();
    }

    /* Make sure we've got reasonable values */
    if ( m_lSize < 0 || m_lPrefix < 0 || m_lCount < 0 ) {
        return E_OUTOFMEMORY;
    }

    /* Compute the aligned size */
    LONG lAlignedSize = m_lSize + m_lPrefix;

    /*  Check overflow */
    if (lAlignedSize < m_lSize) {
        return E_OUTOFMEMORY;
    }

    if (m_lAlignment > 1) {
        LONG lRemainder = lAlignedSize % m_lAlignment;
        if (lRemainder != 0) {
            LONG lNewSize = lAlignedSize + m_lAlignment - lRemainder;
            if (lNewSize < lAlignedSize) {
                return E_OUTOFMEMORY;
            }
            lAlignedSize = lNewSize;
        }
    }

    /* Create the contiguous memory block for the samples
       making sure it's properly aligned (64K should be enough!)
    */
    ASSERT(lAlignedSize % m_lAlignment == 0);

    LONGLONG lToAllocate = m_lCount * (LONGLONG)lAlignedSize;

    /*  Check overflow */
    if (lToAllocate > MAXLONG) {
        return E_OUTOFMEMORY;
    }

    m_pBuffer = (PBYTE)VirtualAlloc(NULL,
                    (LONG)lToAllocate,
                    MEM_COMMIT,
                    PAGE_READWRITE);

    if (m_pBuffer == NULL) {
        return E_OUTOFMEMORY;
    }

    LPBYTE pNext = m_pBuffer;
    CMediaSample *pSample;

    ASSERT(m_lAllocated == 0);

    // Create the new samples - we have allocated m_lSize bytes for each sample
    // plus m_lPrefix bytes per sample as a prefix. We set the pointer to
    // the memory after the prefix - so that GetPointer() will return a pointer
    // to m_lSize bytes.
    for (; m_lAllocated < m_lCount; m_lAllocated++, pNext += lAlignedSize) {


        pSample = new CMediaSample(
                            NAME("Default memory media sample"),
                this,
                            &hr,
                            pNext + m_lPrefix,      // GetPointer() value
                            m_lSize);               // not including prefix

            ASSERT(SUCCEEDED(hr));
        if (pSample == NULL) {
            return E_OUTOFMEMORY;
        }

        // This CANNOT fail
        m_lFree.Add(pSample);
    }

    m_bChanged = FALSE;
    return NOERROR;
}


// override this to free up any resources we have allocated.
// called from the base class on Decommit when all buffers have been
// returned to the free list.
//
// caller has already locked the object.

// in our case, we keep the memory until we are deleted, so
// we do nothing here. The memory is deleted in the destructor by
// calling ReallyFree()
void
CMemAllocator::Free(void)
{
    return;
}


// called from the destructor (and from Alloc if changing size/count) to
// actually free up the memory
void
CMemAllocator::ReallyFree(void)
{
    /* Should never be deleting this unless all buffers are freed */

    ASSERT(m_lAllocated == m_lFree.GetCount());

    /* Free up all the CMediaSamples */

    CMediaSample *pSample;
    for (;;) {
        pSample = m_lFree.RemoveHead();
        if (pSample != NULL) {
            delete pSample;
        } else {
            break;
        }
    }

    m_lAllocated = 0;

    // free the block of buffer memory
    if (m_pBuffer) {
        EXECUTE_ASSERT(VirtualFree(m_pBuffer, 0, MEM_RELEASE));
        m_pBuffer = NULL;
    }
}


/* Destructor frees our memory resources */

CMemAllocator::~CMemAllocator()
{
    Decommit();
    ReallyFree();
}

// ------------------------------------------------------------------------
// filter registration through IFilterMapper. used if IFilterMapper is
// not found (Quartz 1.0 install)

STDAPI
AMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata
                         , IFilterMapper *                  pIFM
                         , BOOL                             bRegister  )
{
  DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter")));

  // check we've got data
  //
  if( NULL == psetupdata ) return S_FALSE;


  // unregister filter
  // (as pins are subkeys of filter's CLSID key
  // they do not need to be removed separately).
  //
  DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter")));
  HRESULT hr = pIFM->UnregisterFilter( *(psetupdata->clsID) );


  if( bRegister )
  {
    // register filter
    //
    DbgLog((LOG_TRACE, 3, TEXT("= = register filter")));
    hr = pIFM->RegisterFilter( *(psetupdata->clsID)
                             , psetupdata->strName
                             , psetupdata->dwMerit    );
    if( SUCCEEDED(hr) )
    {
      // all its pins
      //
      DbgLog((LOG_TRACE, 3, TEXT("= = register filter pins")));
      for( UINT m1=0; m1 < psetupdata->nPins; m1++ )
      {
        hr = pIFM->RegisterPin( *(psetupdata->clsID)
                              , psetupdata->lpPin[m1].strName
                              , psetupdata->lpPin[m1].bRendered
                              , psetupdata->lpPin[m1].bOutput
                              , psetupdata->lpPin[m1].bZero
                              , psetupdata->lpPin[m1].bMany
                              , *(psetupdata->lpPin[m1].clsConnectsToFilter)
                              , psetupdata->lpPin[m1].strConnectsToPin );

        if( SUCCEEDED(hr) )
        {
          // and each pin's media types
          //
          DbgLog((LOG_TRACE, 3, TEXT("= = register filter pin types")));
          for( UINT m2=0; m2 < psetupdata->lpPin[m1].nMediaTypes; m2++ )
          {
            hr = pIFM->RegisterPinType( *(psetupdata->clsID)
                                      , psetupdata->lpPin[m1].strName
                                      , *(psetupdata->lpPin[m1].lpMediaType[m2].clsMajorType)
                                      , *(psetupdata->lpPin[m1].lpMediaType[m2].clsMinorType) );
            if( FAILED(hr) ) break;
          }
          if( FAILED(hr) ) break;
        }
        if( FAILED(hr) ) break;
      }
    }
  }

  // handle one acceptable "error" - that
  // of filter not being registered!
  // (couldn't find a suitable #define'd
  // name for the error!)
  //
  if( 0x80070002 == hr)
    return NOERROR;
  else
    return hr;
}

//  Remove warnings about unreferenced inline functions
#pragma warning(disable:4514)

