?? amfilter.h
字號:
REFERENCE_TIME tStop,
double dRate);
//================================================================================
// IQualityControl methods
//================================================================================
// All inherited from CBasePin and not overridden here.
// STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
// STDMETHODIMP SetSink(IQualityControl * piqc);
};
//=====================================================================
//=====================================================================
// Defines CBaseInputPin
//
// derive your standard input pin from this.
// you need to supply GetMediaType and CheckConnect etc (see CBasePin),
// and you need to supply Receive to do something more useful.
//
//=====================================================================
//=====================================================================
class AM_NOVTABLE CBaseInputPin : public CBasePin,
public IMemInputPin
{
protected:
IMemAllocator *m_pAllocator; // Default memory allocator
// allocator is read-only, so received samples
// cannot be modified (probably only relevant to in-place
// transforms
BYTE m_bReadOnly;
// in flushing state (between BeginFlush and EndFlush)
// if TRUE, all Receives are returned with S_FALSE
BYTE m_bFlushing;
// Sample properties - initalized in Receive
AM_SAMPLE2_PROPERTIES m_SampleProps;
public:
CBaseInputPin(
TCHAR *pObjectName,
CBaseFilter *pFilter,
CCritSec *pLock,
HRESULT *phr,
LPCWSTR pName);
#ifdef UNICODE
CBaseInputPin(
CHAR *pObjectName,
CBaseFilter *pFilter,
CCritSec *pLock,
HRESULT *phr,
LPCWSTR pName);
#endif
virtual ~CBaseInputPin();
DECLARE_IUNKNOWN
// override this to publicise our interfaces
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
// return the allocator interface that this input pin
// would like the output pin to use
STDMETHODIMP GetAllocator(IMemAllocator ** ppAllocator);
// tell the input pin which allocator the output pin is actually
// going to use.
STDMETHODIMP NotifyAllocator(
IMemAllocator * pAllocator,
BOOL bReadOnly);
// do something with this media sample
STDMETHODIMP Receive(IMediaSample *pSample);
// do something with these media samples
STDMETHODIMP ReceiveMultiple (
IMediaSample **pSamples,
long nSamples,
long *nSamplesProcessed);
// See if Receive() blocks
STDMETHODIMP ReceiveCanBlock();
// 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 BeginFlush(void);
// 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 EndFlush(void);
// this method is optional (can return E_NOTIMPL).
// default implementation returns E_NOTIMPL. Override if you have
// specific alignment or prefix needs, but could use an upstream
// allocator
STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES*pProps);
// Release the pin's allocator.
HRESULT BreakConnect();
// helper method to check the read-only flag
BOOL IsReadOnly() {
return m_bReadOnly;
};
// helper method to see if we are flushing
BOOL IsFlushing() {
return m_bFlushing;
};
// Override this for checking whether it's OK to process samples
// Also call this from EndOfStream.
virtual HRESULT CheckStreaming();
// Pass a Quality notification on to the appropriate sink
HRESULT PassNotify(Quality& q);
//================================================================================
// IQualityControl methods (from CBasePin)
//================================================================================
STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
// no need to override:
// STDMETHODIMP SetSink(IQualityControl * piqc);
// switch the pin to inactive state - may already be inactive
virtual HRESULT Inactive(void);
// Return sample properties pointer
AM_SAMPLE2_PROPERTIES * SampleProps() {
ASSERT(m_SampleProps.cbData != 0);
return &m_SampleProps;
}
};
///////////////////////////////////////////////////////////////////////////
// CDynamicOutputPin
//
class CDynamicOutputPin : public CBaseOutputPin,
public IPinFlowControl
{
public:
#ifdef UNICODE
CDynamicOutputPin(
CHAR *pObjectName,
CBaseFilter *pFilter,
CCritSec *pLock,
HRESULT *phr,
LPCWSTR pName);
#endif
CDynamicOutputPin(
TCHAR *pObjectName,
CBaseFilter *pFilter,
CCritSec *pLock,
HRESULT *phr,
LPCWSTR pName);
~CDynamicOutputPin();
// IUnknown Methods
DECLARE_IUNKNOWN
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
// IPin Methods
STDMETHODIMP Disconnect(void);
// IPinFlowControl Methods
STDMETHODIMP Block(DWORD dwBlockFlags, HANDLE hEvent);
// Set graph config info
void SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent);
#ifdef DEBUG
virtual HRESULT Deliver(IMediaSample *pSample);
virtual HRESULT DeliverEndOfStream(void);
virtual HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
#endif // DEBUG
HRESULT DeliverBeginFlush(void);
HRESULT DeliverEndFlush(void);
HRESULT Inactive(void);
HRESULT Active(void);
virtual HRESULT CompleteConnect(IPin *pReceivePin);
virtual HRESULT StartUsingOutputPin(void);
virtual void StopUsingOutputPin(void);
virtual bool StreamingThreadUsingOutputPin(void);
HRESULT ChangeOutputFormat
(
const AM_MEDIA_TYPE *pmt,
REFERENCE_TIME tSegmentStart,
REFERENCE_TIME tSegmentStop,
double dSegmentRate
);
HRESULT ChangeMediaType(const CMediaType *pmt);
HRESULT DynamicReconnect(const CMediaType *pmt);
protected:
HRESULT SynchronousBlockOutputPin(void);
HRESULT AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent);
HRESULT UnblockOutputPin(void);
void BlockOutputPin(void);
void ResetBlockState(void);
static HRESULT WaitEvent(HANDLE hEvent);
enum BLOCK_STATE
{
NOT_BLOCKED,
PENDING,
BLOCKED
};
// This lock should be held when the following class members are
// being used: m_hNotifyCallerPinBlockedEvent, m_BlockState,
// m_dwBlockCallerThreadID and m_dwNumOutstandingOutputPinUsers.
CCritSec m_BlockStateLock;
// This event should be signaled when the output pin is
// not blocked. This is a manual reset event. For more
// information on events, see the documentation for
// CreateEvent() in the Windows SDK.
HANDLE m_hUnblockOutputPinEvent;
// This event will be signaled when block operation succeedes or
// when the user cancels the block operation. The block operation
// can be canceled by calling IPinFlowControl2::Block( 0, NULL )
// while the block operation is pending.
HANDLE m_hNotifyCallerPinBlockedEvent;
// The state of the current block operation.
BLOCK_STATE m_BlockState;
// The ID of the thread which last called IPinFlowControl::Block().
// For more information on thread IDs, see the documentation for
// GetCurrentThreadID() in the Windows SDK.
DWORD m_dwBlockCallerThreadID;
// The number of times StartUsingOutputPin() has been sucessfully
// called and a corresponding call to StopUsingOutputPin() has not
// been made. When this variable is greater than 0, the streaming
// thread is calling IPin::NewSegment(), IPin::EndOfStream(),
// IMemInputPin::Receive() or IMemInputPin::ReceiveMultiple(). The
// streaming thread could also be calling: DynamicReconnect(),
// ChangeMediaType() or ChangeOutputFormat(). The output pin cannot
// be blocked while the output pin is being used.
DWORD m_dwNumOutstandingOutputPinUsers;
// This event should be set when the IMediaFilter::Stop() is called.
// This is a manual reset event. It is also set when the output pin
// delivers a flush to the connected input pin.
HANDLE m_hStopEvent;
IGraphConfig* m_pGraphConfig;
// TRUE if the output pin's allocator's samples are read only.
// Otherwise FALSE. For more information, see the documentation
// for IMemInputPin::NotifyAllocator().
BOOL m_bPinUsesReadOnlyAllocator;
private:
HRESULT Initialize(void);
HRESULT ChangeMediaTypeHelper(const CMediaType *pmt);
#ifdef DEBUG
void AssertValid(void);
#endif // DEBUG
};
class CAutoUsingOutputPin
{
public:
CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr );
~CAutoUsingOutputPin();
private:
CDynamicOutputPin* m_pOutputPin;
};
inline CAutoUsingOutputPin::CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr ) :
m_pOutputPin(NULL)
{
// The caller should always pass in valid pointers.
ASSERT( NULL != pOutputPin );
ASSERT( NULL != phr );
// Make sure the user initialized phr.
ASSERT( S_OK == *phr );
HRESULT hr = pOutputPin->StartUsingOutputPin();
if( FAILED( hr ) )
{
*phr = hr;
return;
}
m_pOutputPin = pOutputPin;
}
inline CAutoUsingOutputPin::~CAutoUsingOutputPin()
{
if( NULL != m_pOutputPin )
{
m_pOutputPin->StopUsingOutputPin();
}
}
#ifdef DEBUG
inline HRESULT CDynamicOutputPin::Deliver(IMediaSample *pSample)
{
// The caller should call StartUsingOutputPin() before calling this
// method.
ASSERT(StreamingThreadUsingOutputPin());
return CBaseOutputPin::Deliver(pSample);
}
inline HRESULT CDynamicOutputPin::DeliverEndOfStream(void)
{
// The caller should call StartUsingOutputPin() before calling this
// method.
ASSERT( StreamingThreadUsingOutputPin() );
return CBaseOutputPin::DeliverEndOfStream();
}
inline HRESULT CDynamicOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
// The caller should call StartUsingOutputPin() before calling this
// method.
ASSERT(StreamingThreadUsingOutputPin());
return CBaseOutputPin::DeliverNewSegment(tStart, tStop, dRate);
}
#endif // DEBUG
//=====================================================================
//=====================================================================
// Memory allocators
//
// the shared memory transport between pins requires the input pin
// to provide a memory allocator that can provide sample objects. A
// sample object supports the IMediaSample interface.
//
// CBaseAllocator handles the management of free and busy samples. It
// allocates CMediaSample objects. CBaseAllocator is an abstract class:
// in particular it has no method of initializing the list of free
// samples. CMemAllocator is derived from CBaseAllocator and initializes
// the list of samples using memory from the standard IMalloc interface.
//
// If you want your buffers to live in some special area of memory,
// derive your allocator object from CBaseAllocator. If you derive your
// IMemInputPin interface object from CBaseMemInputPin, you will get
// CMemAllocator-based allocation etc for free and will just need to
// supply the Receive handling, and media type / format negotiation.
//=====================================================================
//=====================================================================
//=====================================================================
//=====================================================================
// Defines CMediaSample
//
// an object of this class supports IMediaSample and represents a buffer
// for media data with some associated properties. Releasing it returns
// it to a freelist managed by a CBaseAllocator derived object.
//=====================================================================
//=====================================================================
class CMediaSample : public IMediaSample2 // The interface we support
{
protected:
friend class CBaseAllocator;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -