## CBaseStreamControl Class

The CBaseStreamControl class implements the IAMStreamControl interface on input and output pins in a filter graph. This class provides control of the starting and stopping of various components of the stream. Various streams can be turned on or off without affecting the rest of the graph. For example, an audio stream can be turned off while a video stream continues, for muting. Or perhaps a capture stream can be turned off while preview continues to flow. This could be used to assist in frame accuracy when exact capture start or stop times are important.

CBaseStreamControl enables you to specify start and stop times in the StartAt and StopAt member functions and provides stream information in the GetInfo member function. CBaseStreamControl uses the StreamControlState enumerated data type to describe the various states a stream is in. If a stream is flowing it is indicated by the STREAM_FLOWING setting, otherwise it is in a discarding state indicated by the STREAM_DISCARDING setting.

Filters that need to implement the interface on their own should typically inherit from CBaseStreamControl to obtain an implementation of the StartAt, StopAt, and GetInfo methods. The CBaseStreamControl class also maintains state information and decides what to do with the sample. To implement your own filter with pins that support CBaseStreamControl you must:

- Inform the filter object of all state changes through the NotifyFilterState member function.
- Inform the filter object of all SetSyncSource calls to the filter.
- Inform the filter object when in a flushing state. and when flushing has completed, in the CBaseStreamControl::Flushing member function.
- Use the CheckStreamState function to make decisions about discarding or passing along samples.
- Make sure output pins set discontinuity flags on the first sample flowed after samples have been discarded.
- Tell your pin what the sink is when your filter joins a filter graph, as shown in the following example.

      STDMETHODIMP CMyFilter::JoinFilterGraph(IFilterGraph * pGraph, LPCWSTR pName)
      {
         HRESULT hr = CBaseFilter::JoinFilterGraph(pGraph, pName);
         if (hr == S_OK)
            m_pMyPin->SetFilterGraph(m_pSink);
         return hr;
      }

If you are implementing the IAMStreamControl interface without using CBaseStreamControl, the last two preceding points do not apply.

For sample code see the video capture sample at DXmedia\Samples\DS\vidcap.

Member Functions

Name | Description
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.

###

CBaseStreamControl::CBaseStreamControl

CBaseStreamControl Class

Constructs a CBaseStreamControl object.

CBaseStreamControl( );

##### Return Values

No return value.

##### Remarks

This method initializes start time and stop time to MAX_TIME, which implies that times are unspecified.

###

CBaseStreamControl::CheckStreamState

CBaseStreamControl Class

Retrieves a stream's current state.

    enum StreamControlState CheckStreamState( IMediaSample * pSample );

##### Values

pSample
  Pointer to an IMediaSample interface.

##### Return Values

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, it should not count a frame that is discarded as dropped.

The following example shows what you should include if your filter inherits from CBaseStreamControl.

    //Pin has been given a sample to pass on, pSample
    //m_fLastSampleDiscarded is initialized to TRUE when streaming starts

    int iStreamState = CheckStreamState(pSample);
    if (iStreamState == STREAM_FLOWING) {
       if (m_fLastSampleDiscarded)
          pSample->SetDiscontinuity(TRUE);
       m_fLastSampleDiscarded = FALSE;
       //now deliver it or put it o a queue to be delivered, or whatever.
    } else {
       m_fLastSampleDiscarded = TRUE;     //next one is discontinuity
       //do NOT deliver this sample. Just throw it away
    }

###

CBaseStreamControl::Flushing

CBaseStreamControl Class

Notifies the pin that the filter is flushing.

void Flushing(
BOOL bInProgress );

##### Parameters

bInProgress
  TRUE indicates flushing in progress; FALSE indicates not flushing.

##### Return Values

No return value.

##### Remarks

If you are implementing your own filter, your pin must call this member function on BeginFlush and EndFlush (DeliverBeginFlush and DeliverEndFlush for output pins) to say when it is flushing, as shown in the following example.

    HRESULT CMyPin::BeginFlush()
    {
       Flushing(TRUE);
       //or CBaseInputPin for input pins
       return CBaseOutputPin::BeginFlush();
    }

    HRESULT CMyPin::EndFlush()
    {
       Flushing(FALSE);
       //or CBaseInputPin for input pins
       return CBaseOutputPin::EndFlush();
    }

Note that capture filters that do not support seeking do not call this method.

###

CBaseStreamControl::GetInfo

CBaseStreamControl Class

Retrieves information about the current streaming settings.

HRESULT GetInfo(
AM_STREAM_INFO *pInfo
);

##### Parameters

pInfo
  Pointer to an AM_STREAM_INFO structure.

##### Return Values

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.

###

CBaseStreamControl::NotifyFilterState

CBaseStreamControl Class

Notifies the pin of your filter's state.

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 Values

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);
    }

###

CBaseStreamControl::SetFilterGraph

CBaseStreamControl Class

Sets the event sink notification your filter graph is using.

void SetFilterGraph(
IMediaEventSink *pSink )

##### Parameters

pSink
  Pointer to an IMediaEventSink interface.

##### Return Values

No return value.

##### Remarks

A filter calls this member function in its JoinFilterGraph member function after it creates the IMediaEventSink.

###

CBaseStreamControl::SetSyncSource

CBaseStreamControl Class

Identifies the reference clock being used by the graph your filter is in.

void SetSyncSource(
IReferenceClock * pRefClock );

##### Parameters

pRefClock
  Pointer to the IReferenceClock interface.

##### Return Values

No return value.

##### Remarks

Filters with pins that use this class should ensure that they pass sync source information to this member function, as shown in the following example.

    STDMETHODIMP CMyFilter::SetSyncSource(IReferenceClock *pClock)
    {
       m_pMyPin->SetSyncSource(pClock);
       return CBaseFilter::SetSyncSource(pClock);
    }

###

CBaseStreamControl::StartAt

CBaseStreamControl Class

Tells the pin when to start sending streaming data.

HRESULT StartAt(
const REFERENCE_TIME * ptStart = NULL,
DWORD dwCookie = 0 );

##### Parameters

ptStart
  REFERENCE_TIME at which to start streaming. If NULL, start immediately (no notification). If MAX_TIME, start canceled or will have no effect.
dwCookie
  Specifies a particular 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 Values

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.

###

CBaseStreamControl::StopAt

CBaseStreamControl Class

Informs the pin when to stop processing data and to discard any new samples.

HRESULT StopAt(
const REFERENCE_TIME * ptStop = NULL,
BOOL bSendExtra = FALSE,
DWORD dwCookie = 0 );

##### Parameters

ptStop
  REFERENCE_TIME at which to stop streaming. If NULL, stop immediately (no notification). If MAX_TIME, cancels stop.
bSendExtra
  Indicates whether to send an extra sample after scheduled ptStop time.
dwCookie
  Specifies a particular value to be sent with the notification when the stop occurs. (Only used if ptStart if not NULL or MAX_TIME).

##### Return Values

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.

© 1997 Microsoft Corporation. All rights reserved. Terms of Use.