amfilter.cpp.svn-base

来自「ffshow源码」· SVN-BASE 代码 · 共 2,432 行 · 第 1/5 页

SVN-BASE
2,432
字号
/* 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 */HRESULTCBasePin::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 */HRESULTCBasePin::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 */HRESULTCBasePin::BreakConnect(){    return NOERROR;}/* Called normally by an output pin on an input pin to try and establish a   connection.*/STDMETHODIMPCBasePin::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() ) );        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;        }        return hr;    }    /* Complete the connection */    m_Connected = pConnector;    m_Connected->AddRef();    hr = SetMediaType(pcmt);    if (SUCCEEDED(hr)) {        hr = CompleteConnect(pConnector);        if (SUCCEEDED(hr)) {            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() ) );    return hr;}/* Called when we want to terminate a pin connection */STDMETHODIMPCBasePin::Disconnect(){    CAutoLock cObjectLock(m_pLock);    /* See if the filter is active */    if (!IsStopped()) {        return VFW_E_NOT_STOPPED;    }    return DisconnectInternal();}STDMETHODIMPCBasePin::DisconnectInternal(){    ASSERT(CritCheckIn(m_pLock));    if (m_Connected) {        HRESULT hr = BreakConnect();        if( FAILED( hr ) ) {            // 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;        return S_OK;    } else {        // no connection - not an error        return S_FALSE;    }}/* Return an AddRef()'d pointer to the connected pin if there is one */STDMETHODIMPCBasePin::ConnectedTo(    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 */STDMETHODIMPCBasePin::ConnectionMediaType(    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 */STDMETHODIMPCBasePin::QueryPinInfo(    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) {        lstrcpynW(pInfo->achName, m_pName, sizeof(pInfo->achName)/sizeof(WCHAR));    } else {        pInfo->achName[0] = L'\0';    }    pInfo->dir = m_dir;    return NOERROR;}STDMETHODIMPCBasePin::QueryDirection(    PIN_DIRECTION * pPinDir){    CheckPointer(pPinDir,E_POINTER);    ValidateReadWritePtr(pPinDir,sizeof(PIN_DIRECTION));    *pPinDir = m_dir;    return NOERROR;}// Default QueryId to return the pin's nameSTDMETHODIMPCBasePin::QueryId(    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 */STDMETHODIMPCBasePin::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 */STDMETHODIMPCBasePin::EnumMediaTypes(    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, 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) */HRESULTCBasePin::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) */HRESULTCBasePin::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) */HRESULTCBasePin::Inactive(void){    m_bRunTimeError = FALSE;    return NOERROR;}// Called when no more data will arriveSTDMETHODIMPCBasePin::EndOfStream(void){    return S_OK;}STDMETHODIMPCBasePin::SetSink(IQualityControl * piqc){    CAutoLock cObjectLock(m_pLock);    if (piqc) ValidateReadPtr(piqc,sizeof(IQualityControl));    m_pQSink = piqc;    return NOERROR;} // SetSinkSTDMETHODIMPCBasePin::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.STDMETHODIMPCBasePin::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(TCHAR *pObjectName,                   CBaseFilter *pFilter,                   CCritSec *pLock,                   HRESULT *phr,                   LPCWSTR pName) :    CBasePin(pObjectName, pFilter, pLock, phr, pName, PINDIR_OUTPUT),    m_pAllocator(NULL),    m_pInputPin(NULL){    ASSERT(pFilter);}#ifdef UNICODECBaseOutputPin::CBaseOutputPin(CHAR *pObjectName,                   CBaseFilter *pFilter,                   CCritSec *pLock,                   HRESULT *phr,                   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*/HRESULTCBaseOu

⌨️ 快捷键说明

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