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
							 |