The IAMStreamControl interface is exposed on input and output pins on any filter in a filter graph. This interface exposes methods that allow applications to control individual stream components in a filter graph. You can turn various streams on or off without affecting the rest of the graph. For example, you can turn off an audio stream while a video stream continues, for muting. Or a capture stream can be turned off while preview continues to flow. This interface also assists in frame accuracy when exact capture start or stop times are important.
Currently, the CBaseStreamControl base class implements IAMStreamControl. CBaseStreamControl enables the user to specify start and stop times in the CBaseStreamControl::StartAt and CBaseStreamControl::StopAt member functions and provides stream information in the CBaseStreamControl::GetInfo member function. CBaseStreamControl uses the StreamControlState enumerated data type to describe the various states a stream is in. A flowing stream is indicated by the STREAM_FLOWING setting; otherwise it is in a discarding state indicated by the STREAM_DISCARDING setting. See StreamControlState for more details on stream states.
If you want to implement this interface on your own your class should typically inherit from CBaseStreamControl to obtain an implementation of the CBaseStreamControl::StartAt, CBaseStreamControl::StopAt, and CBaseStreamControl::GetInfo methods. The CBaseStreamControl class also maintains state information and makes decisions about what to do with the sample. Developers implementing their own filters with pins that support IAMStreamControl through the CBaseStreamControl base class must follow certain guidelines outlined in the CBaseStreamControl documentation.
Note There must be a clock in the filter graph or the stream control methods might not function as expected.
This interface is not available on the preview pin of capture cards with hardware overlay. Calling QueryInterface for this interface will return the error E_NOINTERFACE (0x80004002).
Implement this interface on input or output pins of filters when you want precise control of the data stream. This interface enables you to turn off portions of the filter graph's streams at specific times without affecting the rest of the graph. Although this interface can be used throughout the graph, the output pins of audio and video capture filters and input pins of multiplexer filters primarily use it.
If you are writing a filter that will implement IAMStreamControl on one of its pins, you should set the STREAM_DISCARDING state so that the pin discards media samples in a timely fashion, rather than as soon as they are received. This means that if your pin is discarding samples as soon as it determines they are outside the time that the pin is supposed to be on, it will discard samples as fast as possible and the whole file could potentially be pushed into your filter and discarded in mere moments. This causes problems if the pin tries to call IAMStreamControl::StartAt at a later point in time because the entire file will have already been discarded. To avoid pins from dumping media samples as fast possible, your code should check the media sample's timestamp and wait until the reference clock verifies that the end of the sample's time has actually occurred before discarding. This is known as discarding in a timely fashion (see CBaseStreamControl for an implementation that does this).
Use this interface to turn on or off certain portions of the filter graph's streams while other portions continue to process data. For example, your application can tell a video capture filter's output pin precisely when to start or stop capturing, independent of what is happening in the rest of the graph. This assists in frame accuracy when exact capture start or stop times are important.
Note If you are using this interface to control capture in a graph that is capturing audio and video to an AVI file through an AVI multiplexer filter (or other similar scenario), stream control will only work if the AVI multiplexer is not interleaving. If you use the IConfigInterleaving::put_Mode method to interleave the streams (either INTERLEAVE_CAPTURE or INTERLEAVE_FULL) then the multiplexer needs both streams to be on at the same time to interleave the data. Using the stream control interface to start and stop streams individually will interfere with the capture and it will not work.
Methods in Vtable Order
IUnknown methods Description QueryInterface Retrieves pointers to supported interfaces. AddRef Increments the reference count. Release Decrements the reference count. IAMStreamControl methods Description StartAt Informs the pin when to start sending streaming data. StopAt Informs the pin when to suspend processing and supplying data. GetInfo Retrieves information about the current streaming settings.
Retrieves information about the current streaming settings.
Syntax
HRESULT GetInfo( AM_STREAM_INFO *pInfo );
Parameters
- pInfo
- [out] Pointer to an AM_STREAM_INFO structure that contains current stream settings.
Return Value
Returns an HRESULT value that depends on the implementation of the interface.
Remarks
Call this method to discover the state of the StreamControlState enumerated data type, which indicates the stream's state. Other values in the AM_STREAM_INFO structure include start time, stop time, start cookie, and stop cookie.
Informs the pin when to start sending streaming data.
Syntax
HRESULT StartAt( const REFERENCE_TIME *ptStart, DWORD dwCookie );
Parameters
- ptStart
- [in] Pointer to the time at which to start streaming as specified in the REFERENCE_TIME structure. If NULL, start immediately (no notification); if MAX_TIME, start canceled and will have no effect.
- dwCookie
- [in] Value to send with the notification when the start occurs. (Only used if ptStart is non-NULL or MAX_TIME).
Return Value
Returns an HRESULT value that depends on the implementation of the interface.
Remarks
Streams are enabled by default, so this method will have no effect unless a previous StopAt member function has been called.
If the pointer to the REFERENCE_TIME is not NULL or MAX_TIME, then pins should signal EC_STREAM_CONTROL_STARTED with an IPin pointer and the cookie specified in the dwCookie parameter. This enables applications to tie the events back to their requests. If the ptStart pointer is NULL or MAX_TIME, then the filter graph sends no event.
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 to capture a single frame.
Informs the pin when to suspend processing and supplying data.
Syntax
HRESULT StopAt( const REFERENCE_TIME *ptStop, BOOL bSendExtra, DWORD dwCookie );
Parameters
- ptStop
- [in] Pointer to the time at which to stop streaming as specified in the REFERENCE_TIME structure. If you specify NULL for ptStop, it will stop immediately (no notification); if MAX_TIME, cancels stop.
- bSendExtra
- [in] Flag indicating whether to send an extra sample after scheduled ptStop time; TRUE means to send an extra sample.
- dwCookie
- [in] Value to send with the notification when the stop occurs (used only if ptStart if not NULL or MAX_TIME).
Return Value
Returns an HRESULT value that depends on the implementation of the interface.
Remarks
This method is exposed by pins that support the stopping of streams. It sets the StreamControlState enumeration type to STREAM_DISCARDING.
In video capture, you would typically call StopAt on both the output pin of a capture filter and the input pin of a multiplexer, and pay attention only to the notification from the multiplexer. This ensures that the capture filter doesn't needlessly capture extra frames, while guaranteeing that the multiplexer has, in fact, saved the last frame to a file.
In addition, you should specify TRUE for the bSendExtra parameter on the capture pin, and specify FALSE to the multiplexer pin. If an extra frame is not sent, the multiplexer will wait for the stop time indefinitely and not realize it already has received all the capture information. The multiplexer will discard the extra sample sent by the capture pin, so it will not get written to the file. Do not set bSendExtra to TRUE unless you also use IAMStreamControl on another downstream pin too, like in the preceding case.
If you call StopAt with a time that is 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 (see CBaseStreamControl for an implementation example).
Top of Page
© 2000 Microsoft and/or its suppliers. All rights reserved. Terms of Use.