www.pudn.com > avi_file_source.rar > asyncrdr.h


//------------------------------------------------------------------------------ 
// File: AsyncRdr.h 
// 
// Desc: DirectShow sample code - base library for I/O functionality. 
// 
// Copyright (c) Microsoft Corporation.  All rights reserved. 
//------------------------------------------------------------------------------ 
 
 
#ifndef __ASYNCRDR_H__ 
#define __ASYNCRDR_H__ 
 
 
// 
// AsyncRdr 
// 
// Defines an IO source filter. 
// 
// This filter (CAsyncReader) supports IBaseFilter and IFileSourceFilter interfaces from the 
// filter object itself. It has a single output pin (CAsyncOutputPin) 
// which supports IPin and IAsyncReader. 
// 
// This filter is essentially a wrapper for the CAsyncFile class that does 
// all the work. 
// 
 
 
// the filter class (defined below) 
class CAsyncReader; 
 
 
// the output pin class 
class CAsyncOutputPin 
  : public IAsyncReader, 
    public CBasePin 
{ 
protected: 
    CAsyncReader* m_pReader; 
    CAsyncIo * m_pIo; 
 
    //  This is set every time we're asked to return an IAsyncReader 
    //  interface 
    //  This allows us to know if the downstream pin can use 
    //  this transport, otherwise we can hook up to thinks like the 
    //  dump filter and nothing happens 
    BOOL         m_bQueriedForAsyncReader; 
 
    HRESULT InitAllocator(IMemAllocator **ppAlloc); 
 
public: 
    // constructor and destructor 
    CAsyncOutputPin( 
        HRESULT * phr, 
        CAsyncReader *pReader, 
        CAsyncIo *pIo, 
        CCritSec * pLock); 
 
    ~CAsyncOutputPin(); 
 
    // --- CUnknown --- 
 
    // need to expose IAsyncReader 
    DECLARE_IUNKNOWN 
    STDMETHODIMP NonDelegatingQueryInterface(REFIID, void**); 
 
    // --- IPin methods --- 
    STDMETHODIMP Connect( 
        IPin * pReceivePin, 
        const AM_MEDIA_TYPE *pmt   // optional media type 
    ); 
 
    // --- CBasePin methods --- 
 
    // return the types we prefer - this will return the known 
    // file type 
    HRESULT GetMediaType(int iPosition, CMediaType *pMediaType); 
 
    // can we support this type? 
    HRESULT CheckMediaType(const CMediaType* pType); 
 
    // Clear the flag so we see if IAsyncReader is queried for 
    HRESULT CheckConnect(IPin *pPin) 
    { 
        m_bQueriedForAsyncReader = FALSE; 
        return CBasePin::CheckConnect(pPin); 
    } 
 
    // See if it was asked for 
    HRESULT CompleteConnect(IPin *pReceivePin) 
    { 
        if (m_bQueriedForAsyncReader) { 
            return CBasePin::CompleteConnect(pReceivePin); 
        } else { 
 
#ifdef VFW_E_NO_TRANSPORT 
            return VFW_E_NO_TRANSPORT; 
#else 
            return E_FAIL; 
#endif 
        } 
    } 
 
    //  Remove our connection status 
    HRESULT BreakConnect() 
    { 
        m_bQueriedForAsyncReader = FALSE; 
        return CBasePin::BreakConnect(); 
    } 
 
    // --- IAsyncReader methods --- 
    // pass in your preferred allocator and your preferred properties. 
    // method returns the actual allocator to be used. Call GetProperties 
    // on returned allocator to learn alignment and prefix etc chosen. 
    // this allocator will be not be committed and decommitted by 
    // the async reader, only by the consumer. 
    STDMETHODIMP RequestAllocator( 
                      IMemAllocator* pPreferred, 
                      ALLOCATOR_PROPERTIES* pProps, 
                      IMemAllocator ** ppActual); 
 
    // queue a request for data. 
    // media sample start and stop times contain the requested absolute 
    // byte position (start inclusive, stop exclusive). 
    // may fail if sample not obtained from agreed allocator. 
    // may fail if start/stop position does not match agreed alignment. 
    // samples allocated from source pin's allocator may fail 
    // GetPointer until after returning from WaitForNext. 
    STDMETHODIMP Request( 
                     IMediaSample* pSample, 
                     DWORD dwUser);         // user context 
 
    // block until the next sample is completed or the timeout occurs. 
    // timeout (millisecs) may be 0 or INFINITE. Samples may not 
    // be delivered in order. If there is a read error of any sort, a 
    // notification will already have been sent by the source filter, 
    // and STDMETHODIMP will be an error. 
    STDMETHODIMP WaitForNext( 
                      DWORD dwTimeout, 
                      IMediaSample** ppSample,  // completed sample 
                      DWORD * pdwUser);         // user context 
 
    // sync read of data. Sample passed in must have been acquired from 
    // the agreed allocator. Start and stop position must be aligned. 
    // equivalent to a Request/WaitForNext pair, but may avoid the 
    // need for a thread on the source filter. 
    STDMETHODIMP SyncReadAligned( 
                      IMediaSample* pSample); 
 
 
    // sync read. works in stopped state as well as run state. 
    // need not be aligned. Will fail if read is beyond actual total 
    // length. 
    STDMETHODIMP SyncRead( 
                      LONGLONG llPosition,  // absolute file position 
                      LONG lLength,         // nr bytes required 
                      BYTE* pBuffer);       // write data here 
 
    // return total length of stream, and currently available length. 
    // reads for beyond the available length but within the total length will 
    // normally succeed but may block for a long period. 
    STDMETHODIMP Length( 
                      LONGLONG* pTotal, 
                      LONGLONG* pAvailable); 
 
    // cause all outstanding reads to return, possibly with a failure code 
    // (VFW_E_TIMEOUT) indicating they were cancelled. 
    // these are defined on IAsyncReader and IPin 
    STDMETHODIMP BeginFlush(void); 
    STDMETHODIMP EndFlush(void); 
 
}; 
 
 
// 
// The filter object itself. Supports IBaseFilter through 
// CBaseFilter and also IFileSourceFilter directly in this object 
 
class CAsyncReader : public CBaseFilter 
{ 
 
protected: 
    // filter-wide lock 
    CCritSec m_csFilter; 
 
    // all i/o done here 
    CAsyncIo m_Io; 
 
    // our output pin 
    CAsyncOutputPin m_OutputPin; 
 
    // Type we think our data is 
    CMediaType m_mt; 
 
public: 
         
    // construction / destruction 
 
    CAsyncReader( 
        TCHAR *pName, 
        LPUNKNOWN pUnk, 
        CAsyncStream *pStream, 
        HRESULT *phr); 
 
    ~CAsyncReader(); 
 
 
    // --- CBaseFilter methods --- 
    int GetPinCount(); 
    CBasePin *GetPin(int n); 
 
    // --- Access our media type 
    const CMediaType *LoadType() const 
    { 
        return &m_mt; 
    } 
 
    virtual HRESULT Connect( 
        IPin * pReceivePin, 
        const AM_MEDIA_TYPE *pmt   // optional media type 
    ) 
    { 
        return m_OutputPin.CBasePin::Connect(pReceivePin, pmt); 
    } 
}; 
 
 
 
#endif //__ASYNCRDR_H__