Setting and Retrieving the Position

[The feature associated with this page, DirectShow, is a legacy feature. It has been superseded by MediaPlayer, IMFMediaEngine, and Audio/Video Capture in Media Foundation. Those features have been optimized for Windows 10 and Windows 11. Microsoft strongly recommends that new code use MediaPlayer, IMFMediaEngine and Audio/Video Capture in Media Foundation instead of DirectShow, when possible. Microsoft suggests that existing code that uses the legacy APIs be rewritten to use the new APIs if possible.]

The filter graph maintains two position values, current position and stop position. These are defined as follows:

  • When the graph is running, the current position is the current playback position, relative to the beginning of the source. When the graph is stopped or paused, the current position is the point where streaming will begin on the next run command.
  • The stop position is the point where the stream will end. When the graph reaches the stop position, no more data is streamed, and the filter graph manager posts an EC_COMPLETE event. (The graph does not automatically switch to a stopped state, however. For more information, see Responding to Events.)

To retrieve these values, call the IMediaSeeking::GetPositions method. The returned values are always relative to the original media source. By default, the values are in reference time units. In some cases, you can change the time units; for more information, see Time Formats For Seek Commands.

To seek to a new position or set a new stop position, call the IMediaSeeking::SetPositions method, as shown in the following example:

#define ONE_SECOND 10000000
REFERENCE_TIME rtNow  = 2 * ONE_SECOND, 
               rtStop = 5 * ONE_SECOND;

hr = pSeek->SetPositions(
    &rtNow,  AM_SEEKING_AbsolutePositioning, 
    &rtStop, AM_SEEKING_AbsolutePositioning
    );

Note

One second is 10,000,000 units of reference time. For convenience, the example defines this value as ONE_SECOND. If you are using the DirectShow base-class library, the constant UNITS has the same value.

 

The rtNow parameter specifies the new current position. The second parameter is a flag that defines how to interpret rtNow. In this example, the AM_SEEKING_AbsolutePositioning flag indicates that rtNow specifies an absolute position in the source. Therefore, the filter graph will seek to a position two seconds from the start of the stream. The rtStop parameter gives the stop time. The last parameter specifies that rtStop is also an absolute position.

To specify a position relative to the previous position value, use the AM_SEEKING_RelativePositioning flag. To leave one of the position values unchanged, use the AM_SEEKING_NoPositioning flag. The corresponding time parameter can be NULL in that case. The following example seeks forward by 10 seconds but leaves the stop position unchanged:

REFERENCE_TIME rtNow = 10 * ONE_SECOND;
hr = pSeek->SetPositions(
    &rtNow, AM_SEEKING_RelativePositioning, 
    NULL, AM_SEEKING_NoPositioning
    );

If the filter graph is stopped, the video renderer does not update the image after a seek operation. To the user, it will appear as if the seek did not happen. To update the image, pause the graph after the seek operation. Pausing the graph cues a new video frame for the video renderer. You can use the IMediaControl::StopWhenReady method, which pauses the graph and then stops it.