forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			158 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//------------------------------------------------------------------------------
 | 
						|
// File: StrmCtl.h
 | 
						|
//
 | 
						|
// Desc: DirectShow base classes.
 | 
						|
//
 | 
						|
// Copyright (c) 1996-2001 Microsoft Corporation.  All rights reserved.
 | 
						|
//------------------------------------------------------------------------------
 | 
						|
 | 
						|
 | 
						|
#ifndef __strmctl_h__
 | 
						|
#define __strmctl_h__
 | 
						|
 | 
						|
class CBaseStreamControl : public IAMStreamControl
 | 
						|
{
 | 
						|
public:
 | 
						|
    // Used by the implementation
 | 
						|
    enum StreamControlState
 | 
						|
    { STREAM_FLOWING = 0x1000,
 | 
						|
      STREAM_DISCARDING
 | 
						|
    };
 | 
						|
 | 
						|
private:
 | 
						|
    enum StreamControlState	m_StreamState;		// Current stream state
 | 
						|
    enum StreamControlState	m_StreamStateOnStop;	// State after next stop
 | 
						|
						// (i.e.Blocking or Discarding)
 | 
						|
 | 
						|
    REFERENCE_TIME	m_tStartTime;	    // MAX_TIME implies none
 | 
						|
    REFERENCE_TIME	m_tStopTime;	    // MAX_TIME implies none
 | 
						|
    DWORD		m_dwStartCookie;    // Cookie for notification to app
 | 
						|
    DWORD		m_dwStopCookie;	    // Cookie for notification to app
 | 
						|
    volatile BOOL       m_bIsFlushing;        // No optimization pls!
 | 
						|
    volatile BOOL	m_bStopSendExtra;   // bSendExtra was set
 | 
						|
    volatile BOOL	m_bStopExtraSent;   // the extra one was sent
 | 
						|
 | 
						|
    CCritSec		m_CritSec;	    // CritSec to guard above attributes
 | 
						|
 | 
						|
    // Event to fire when we can come
 | 
						|
    // out of blocking, or to come out of waiting
 | 
						|
    // to discard if we change our minds.
 | 
						|
    //
 | 
						|
    CAMEvent			m_StreamEvent;
 | 
						|
 | 
						|
    // All of these methods execute immediately.  Helpers for others.
 | 
						|
    //
 | 
						|
    void ExecuteStop();
 | 
						|
    void ExecuteStart();
 | 
						|
    void CancelStop();
 | 
						|
    void CancelStart();
 | 
						|
 | 
						|
    // Some things we need to be told by our owning filter
 | 
						|
    // Your pin must also expose IAMStreamControl when QI'd for it!
 | 
						|
    //
 | 
						|
    IReferenceClock *	m_pRefClock;	    // Need it to set advises
 | 
						|
					    // Filter must tell us via
 | 
						|
					    // SetSyncSource
 | 
						|
    IMediaEventSink *   m_pSink;            // Event sink
 | 
						|
					    // Filter must tell us after it
 | 
						|
					    // creates it in JoinFilterGraph()
 | 
						|
    FILTER_STATE	m_FilterState;	    // Just need it!
 | 
						|
					    // Filter must tell us via
 | 
						|
					    // NotifyFilterState
 | 
						|
    REFERENCE_TIME	m_tRunStart;	    // Per the Run call to the filter
 | 
						|
 | 
						|
    // This guy will return one of the three StreamControlState's.  Here's what
 | 
						|
    // the caller should do for each one:
 | 
						|
    //
 | 
						|
    // STREAM_FLOWING:		Proceed as usual (render or pass the sample on)
 | 
						|
    // STREAM_DISCARDING:	Calculate the time 'til *pSampleStop and wait
 | 
						|
    //				that long for the event handle
 | 
						|
    //				(GetStreamEventHandle()).  If the wait
 | 
						|
    //				expires, throw the sample away.  If the event
 | 
						|
    //				fires, call me back - I've changed my mind.
 | 
						|
    //
 | 
						|
    enum StreamControlState CheckSampleTimes( __in const REFERENCE_TIME * pSampleStart,
 | 
						|
					      __in const REFERENCE_TIME * pSampleStop );
 | 
						|
 | 
						|
public:
 | 
						|
    // You don't have to tell us much when we're created, but there are other
 | 
						|
    // obligations that must be met.  See SetSyncSource & NotifyFilterState
 | 
						|
    // below.
 | 
						|
    //
 | 
						|
    CBaseStreamControl(__inout_opt HRESULT *phr = NULL);
 | 
						|
    ~CBaseStreamControl();
 | 
						|
 | 
						|
    // If you want this class to work properly, there are thing you need to
 | 
						|
    // (keep) telling it.  Filters with pins that use this class
 | 
						|
    // should ensure that they pass through to this method any calls they
 | 
						|
    // receive on their SetSyncSource.
 | 
						|
 | 
						|
    // We need a clock to see what time it is.  This is for the
 | 
						|
    // "discard in a timely fashion" logic.  If we discard everything as
 | 
						|
    // quick as possible, a whole 60 minute file could get discarded in the
 | 
						|
    // first 10 seconds, and if somebody wants to turn streaming on at 30 
 | 
						|
    // minutes into the file, and they make the call more than a few seconds
 | 
						|
    // after the graph is run, it may be too late!
 | 
						|
    // So we hold every sample until it's time has gone, then we discard it.
 | 
						|
    // The filter should call this when it gets a SetSyncSource
 | 
						|
    //
 | 
						|
    void SetSyncSource( IReferenceClock * pRefClock )
 | 
						|
    {
 | 
						|
	CAutoLock lck(&m_CritSec);
 | 
						|
	if (m_pRefClock) m_pRefClock->Release();
 | 
						|
	m_pRefClock = pRefClock;
 | 
						|
	if (m_pRefClock) m_pRefClock->AddRef();
 | 
						|
    }
 | 
						|
 | 
						|
    // Set event sink for notifications
 | 
						|
    // The filter should call this in its JoinFilterGraph after it creates the
 | 
						|
    // IMediaEventSink
 | 
						|
    //
 | 
						|
    void SetFilterGraph( IMediaEventSink *pSink ) {
 | 
						|
        m_pSink = pSink;
 | 
						|
    }
 | 
						|
 | 
						|
    // Since we schedule in stream time, we need the tStart and must track the
 | 
						|
    // state of our owning filter.
 | 
						|
    // The app should call this ever state change
 | 
						|
    //
 | 
						|
    void NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart = 0 );
 | 
						|
 | 
						|
    // Filter should call Flushing(TRUE) in BeginFlush,
 | 
						|
    // and Flushing(FALSE) in EndFlush.
 | 
						|
    //
 | 
						|
    void Flushing( BOOL bInProgress );
 | 
						|
 | 
						|
 | 
						|
    // The two main methods of IAMStreamControl
 | 
						|
 | 
						|
    // Class adds default values suitable for immediate
 | 
						|
    // muting and unmuting of the stream.
 | 
						|
 | 
						|
    STDMETHODIMP StopAt( const REFERENCE_TIME * ptStop = NULL,
 | 
						|
			 BOOL bSendExtra = FALSE,
 | 
						|
			 DWORD dwCookie = 0 );
 | 
						|
    STDMETHODIMP StartAt( const REFERENCE_TIME * ptStart = NULL,
 | 
						|
		    	  DWORD dwCookie = 0 );
 | 
						|
    STDMETHODIMP GetInfo( __out AM_STREAM_INFO *pInfo);
 | 
						|
 | 
						|
    // Helper function for pin's receive method.  Call this with
 | 
						|
    // the sample and we'll tell you what to do with it.  We'll do a
 | 
						|
    // WaitForSingleObject within this call if one is required.  This is
 | 
						|
    // a "What should I do with this sample?" kind of call. We'll tell the
 | 
						|
    // caller to either flow it or discard it.
 | 
						|
    // If pSample is NULL we evaluate based on the current state
 | 
						|
    // settings
 | 
						|
    enum StreamControlState CheckStreamState( IMediaSample * pSample );
 | 
						|
 | 
						|
private:
 | 
						|
    // These don't require locking, but we are relying on the fact that
 | 
						|
    // m_StreamState can be retrieved with integrity, and is a snap shot that
 | 
						|
    // may have just been, or may be just about to be, changed.
 | 
						|
    HANDLE GetStreamEventHandle() const { return m_StreamEvent; }
 | 
						|
    enum StreamControlState GetStreamState() const { return m_StreamState; }
 | 
						|
    BOOL IsStreaming() const { return m_StreamState == STREAM_FLOWING; }
 | 
						|
};
 | 
						|
 | 
						|
#endif
 |