//------------------------------------------------------------------------------
// 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
