Microsoft DirectX 8.0 |
This class implements the IAMStreamControl interface for both input and output pins. It provides control over starting and stopping an individual stream in the filter graph. (For more information, see IAMStreamControl.)
If you are implementing a pin that supports IAMStreamControl, you should inherit from this base class. The following is a typical declaration for an input pin:
class CMyInputPin : public CBaseInputPin, public CBaseStreamControl
Be sure to override NonDelegatingQueryInteface to expose IAMStreamControl. For more information, see How to Implement IUnknown.
This class uses the StreamControlState enumeration to describe the current state of a stream:
The class also provides a helper function, CheckStreamState, that retrieves the current state. A pin derived from this class should call this function in order to determine how to process a given sample.
It is also important that the pin be synchronized to a reference clock. Otherwise, it will discard every sample immediately, which could cause an entire file to get pushed through the filter as fast as possible, making it impossible to restart the stream at a later time. When the pin is synchronized correctly, it holds a sample until the scheduled time before discarding it. To specify the reference clock, call the SetSyncSource member function.
In order to use this base class correctly, you must call certain member functions at particular times. The following describes what to do, and gives brief code examples. (In your own code, you will probably need to handle various other details that the examples omit.)
STDMETHODIMP CMyFilter::SetSyncSource(IReferenceClock *pClock) { m_pMyPin->SetSyncSource(pClock); return CBaseFilter::SetSyncSource(pClock); }
STDMETHODIMP CMyFilter::JoinFilterGraph(IFilterGraph * pGraph, LPCWSTR pName) { HRESULT hr = CBaseFilter::JoinFilterGraph(pGraph, pName); if (hr == S_OK) m_pMyPin->SetFilterGraph(m_pSink); return hr; }
STDMETHODIMP CMyFilter::Run(REFERENCE_TIME tStart) { m_pMyPin->NotifyFilterState(State_Running, tStart); return CBaseFilter::Run(tStart); }
HRESULT CMyPin::BeginFlush() { Flushing(TRUE); return CBaseOutputPin::BeginFlush(); // Or CBaseInputPin, for input pins } HRESULT CMyPin::EndFlush() { Flushing(FALSE); return CBaseOutputPin::EndFlush(); // Or CBaseInputPin, for input pins }
CMyPin::Receive(IMediaSample *pSample) { int iStreamState = CheckStreamState(pSample); if (iStreamState == STREAM_FLOWING) { if (m_fLastSampleDiscarded) pSample->SetDiscontinuity(TRUE); m_fLastSampleDiscarded = FALSE; // Deliver sample, or otherwise handle. } else { m_fLastSampleDiscarded = TRUE; // Next one is discontinuity // Do NOT deliver this sample. Just throw it away. } }
Member Functions
CBaseStreamControl Constructs a CBaseStreamControl object. CheckStreamState Retrieves a stream's current state. Flushing Notifies the pin when the filter is flushing. GetInfo Retrieves information about the current streaming settings. NotifyFilterState Notifies the pin of what state your filter is in. SetFilterGraph Sets the event sink notification that your filter graph is using. SetSyncSource Identifies the reference clock being used by the graph your filter is in. StartAt Informs the pin when to start sending streaming data. StopAt Informs the pin when to stop processing data and discard any new samples.
Constructs a CBaseStreamControl object.
Syntax
CBaseStreamControl(void);
Return Value
No return value.
Remarks
This function initializes both the start time and stop time to MAX_TIME, which indicates starting from the beginning of the stream and not stopping until the end of the stream.
Retrieves a stream's current state.
Syntax
enum StreamControlState CheckStreamState( IMediaSample *pSample );
Parameters
- pSample
- Pointer to an IMediaSample interface.
Return Value
Returns a StreamControlState enumeration type.
Remarks
Your filter calls this member function when your pin receives a sample that it is about to forward. The first sample you forward after throwing one or more away should be marked as a discontinuity.
If your filter implements the IAMDroppedFrames interface and is counting how many frames are dropped, do not count a discarded frame as a dropped frame.
Notifies the pin that the filter is flushing.
Syntax
void Flushing( BOOL bInProgress );
Parameters
- bInProgress
- Value indicating whether the filter is flushing. TRUE indicates flushing in progress; FALSE indicates not flushing.
Return Value
No return value.
Remarks
If you are implementing your own filter, your pin must call this member function on BeginFlush and EndFlush to say when it is flushing.
Note that capture filters that do not support seeking do not call this method.
Retrieves information about the current streaming settings.
Syntax
HRESULT GetInfo( AM_STREAM_INFO *pInfo );
Parameters
- pInfo
- Pointer to an AM_STREAM_INFO structure.
Return Value
Returns S_OK.
Remarks
This member function implements the IAMStreamControl interface and is called by the user to find out if a pin is streaming and to obtain the stream's attributes.
Notifies the pin of your filter's state.
Syntax
void NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart = 0 );
Parameters
- new_state
- Filter's new state.
- tStart
- Time at which streaming starts (only valid when new_state is in State_Running).
Return Value
No return value.
Remarks
This member function notifies the pin of a filter's new state by setting a FILTER_STATE enumeration type variable.
If you are implementing your own filter, inform your pin's CBaseStreamControl::NotifyFilterState member function what state your filter is in every time your filter changes state, as shown in the following example.
STDMETHODIMP CMyFilter::Run(REFERENCE_TIME tStart) { // Once error check is successful m_pMyPin->NotifyFilterState(State_Running, tStart); // Now continue with whatever should occur next, for example... return CBaseFilter::Run(tStart); } STDMETHODIMP CMyFilter::Pause() { // Once error check is successful m_pMyPin->NotifyFilterState(State_Paused, 0); // Now continue with whatever should occur next, for example... return CBaseFilter::Pause(); } STDMETHODIMP CMyFilter::Stop() { // Once error check is successful m_pMyPin->NotifyFilterState(State_Stopped, 0); // Now continue with whatever should occur next, for example... return CBaseFilter::Stop(tStart); }
Sets the event sink your filter graph is using for event notification.
Syntax
void SetFilterGraph( IMediaEventSink *pSink );
Parameters
- pSink
- Pointer to an IMediaEventSink interface.
Return Value
No return value.
Remarks
A filter calls this member function in its JoinFilterGraph member function after it creates the IMediaEventSink.
Identifies the reference clock being used by the graph your filter is in.
Syntax
void SetSyncSource( IReferenceClock *pRefClock );
Parameters
- pRefClock
- Pointer to the IReferenceClock interface.
Return Value
No return value.
Remarks
Filters with pins that use this class should ensure that they pass sync source information to this member function
Tells the pin when to start sending streaming data.
Syntax
HRESULT StartAt( const REFERENCE_TIME *ptStart = NULL, DWORD dwCookie = 0 );
Parameters
- ptStart
- Pointer to the reference time at which to start streaming. If NULL, start immediately (no notification). If MAX_TIME, start canceled or will have no effect.
- dwCookie
- Value, other than 0, to be sent with the notification when the start occurs. (Only used if ptStart is non-NULL or MAX_TIME).
Return Value
Returns NOERROR.
Remarks
Streams are enabled by default, so this member function will have no effect unless you have previously called StopAt.
After the stream is in a STREAM_FLOWING state, the filter will send an EC_STREAM_CONTROL_STARTED event notification to the filter graph manager.
Note If start and stop are scheduled for a single point in time, the effect is as if the start occurred an infinitesimal time before the stop. You can use this effect to capture a single frame.
Informs the pin when to stop processing data and to discard any new samples.
Syntax
HRESULT StopAt( const REFERENCE_TIME *ptStop = NULL, BOOL bSendExtra = FALSE, DWORD dwCookie = 0 );
Parameters
- ptStop
- Pointer to the reference time at which to stop streaming. If NULL, stop immediately (no notification). If MAX_TIME, cancels stop.
- bSendExtra
- Flag that specifies whether the pin will send an extra sample after the scheduled ptStop time; TRUE means that it will. For more information, see Remarks.
- dwCookie
- Value to be sent with the notification when the stop occurs. (Only used if ptStart is not NULL or MAX_TIME).
Return Value
Returns NOERROR.
Remarks
This member function implements the IAMStreamControl::StopAt method and is used by pins and filters that must support the stopping of streams. It sets the StreamControlState enumeration type to STREAM_DISCARDING.
In a video capture scenario, specify StopAt on both the output pin of a capture filter and an input pin of a multiplexer and have the multiplexer send notification of completion. This ensures that the capture filter doesn't needlessly capture extra frames, while also guaranteeing that the multiplexer has written the last frame to disk.
In addition, the capture output pin should specify TRUE for the bSendExtra variable while all other pins specify FALSE. If an extra frame is not sent the multiplexer will end up waiting for the stop time indefinitely and not realize it already has received all the capture information.
If you are using ICaptureGraphBuilder, the ICaptureGraphBuilder::ControlStream method will accomplish all this for you automatically.
Note If a stop time is given in the middle of a packet, the filter will deliver the whole packet before going into a discarding state. Also, if start and stop are scheduled for a single point in time, the effect is as if the start occurred an infinitesimal time before the stop. You can use this effect to capture a single frame.