diff options
Diffstat (limited to 'thirdparties/win32/include/directshow/strmctl.h')
-rw-r--r-- | thirdparties/win32/include/directshow/strmctl.h | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/thirdparties/win32/include/directshow/strmctl.h b/thirdparties/win32/include/directshow/strmctl.h new file mode 100644 index 0000000..4077e6c --- /dev/null +++ b/thirdparties/win32/include/directshow/strmctl.h @@ -0,0 +1,157 @@ +//------------------------------------------------------------------------------ +// 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 |