Although IMediaPosition allows applications a simple seeking interface on a filter graph, it has a number of limitations. The IMediaPosition interface allows seeking only by using REFTIME time-based units; however, many filter graphs would prefer to seek on units of samples, video frames, or fields in a compressed stream. Also, the IMediaPosition interface uses separate methods to set and retrieve position properties, which can cause unnecessary filter flushing.
The IMediaSeeking interface improves on the IMediaPosition interface by allowing arbitrary formats for seekable units, such as frames, bytes, and 100-second units of time. It also offers the ability to start and stop times using a single method call, which is absent in IMediaPosition. When seeking to time units, IMediaSeeking expresses time as a 64-bit integer (LONGLONG), providing greater accuracy than IMediaPosition, which expresses time in decimal seconds stored as a double. However, because of this difference in time unit data types, only IMediaPosition supports Automation. IMediaPosition is maintained as an interface for this reason only. Applications not using Automation to seek the media stream should use the IMediaSeeking interface instead.
The IMediaSeeking interface is set by using a defined time format, such as TIME_FORMAT_MEDIA_TIME or TIME_FORMAT_SAMPLE, which then defines how parameters in other methods are interpreted. The format can be changed only when the filter graph is stopped (the default DirectShow plug-in distributor method for this method takes care of this automatically, effectively eliminating this restriction). Only one time format is available at any given time.
When a filter is seeked in media time, it must return a time at which the media seek positioned it. For example, if a source filter is seeked to frame 30, it might return 2 seconds if the video is 15 frames per second. With that position time (of 2 seconds), the filter graph manager can then seek all the other filters to that 2-second position so that the graph as a whole remains synchronized.
Time formats are globally unique identifiers (GUIDs), which are defined as follows:
GUID | Defined as |
0L-0-0-0-0-0-0-0-0-0-0 | TIME_FORMAT_NONE |
7b785570-8c82-11cf-bc0c-00aa00ac74f6 | TIME_FORMAT_FRAME |
7b785571-8c82-11cf-bc0c-00aa00ac74f6 | TIME_FORMAT_BYTE |
7b785572-8c82-11cf-bc0c-00aa00ac74f6 | TIME_FORMAT_SAMPLE |
7b785573-8c82-11cf-bc0c-00aa00ac74f6 | TIME_FORMAT_FIELD |
7b785574-8c82-11cf-bc0c-00aa00ac74f6 | TIME_FORMAT_MEDIA_TIME |
When to Implement
The filter graph manager exposes the IMediaSeeking interface from the plug-in distributor (PID) that handles this interface. If none of the filters within the graph support this interface, the PID will return E_NOINTERFACE; if at least one filter supports the interface, but all such filters return E_NOTIMPL, the PID will return E_NOTIMPL. Otherwise, the filter graph manager will return either a success or the first failure it encounters.
A success normally means that a seekable file source filter was found. Filters, such as a file source filter, will expose IMediaSeeking if they can seek their data or if their output pin represents a seekable stream. The renderer filter also should expose this interface. Output pins of transform filters expose this interface to pass the positioning information upstream, from the renderer through each intermediate filter to the seekable filter.
Use the CPosPassThru base class to implement this interface on output pins of transform filters used to pass media positioning information upstream. This is enabled by default in the pin base classes. Renderers can use the same class, although in most cases they should use CRendererPosPassThru, which is derived from CPosPassThru, to implement this interface.
When to Use
Applications can use this interface to set or retrieve properties such as the duration of the stream, the current position, the stop time, and the media time format being used. Most commonly, an application will use the methods on this interface to play a media stream for some duration starting at some set position in the stream (for example, 10 seconds from the start).
A transform filter will call the IMediaSeeking methods on the connected upstream pin when passing media times upstream from the renderer.
Methods in Vtable Order
IUnknown methods | Description |
QueryInterface | Returns pointers to supported interfaces. |
AddRef | Increments the reference count. |
Release | Decrements the reference count. |
IMediaSeeking methods | Description |
GetCapabilities | Returns the seeking capabilities of the media stream. |
CheckCapabilities | Determines which capabilities exist on a media stream by applying seeking capability flags and checking the returned value. |
IsFormatSupported | Determines if a specified time format is supported. |
QueryPreferredFormat | Retrieves the preferred time format to be used by the interface. |
GetTimeFormat | Retrieves the current time format. |
IsUsingTimeFormat | Determines if the time format being used in the call is the same as the one currently in use by the interface. |
SetTimeFormat | Sets the time format, which determines the format of units used during seeking. |
GetDuration | Retrieves the length of time that the media stream will play. |
GetStopPosition | Retrieves the position within the media stream at which playback should stop. |
GetCurrentPosition | Retrieves the current position within the media stream. |
ConvertTimeFormat | Converts a time from one time format to another. |
SetPositions | Sets current and stop positions and applies flags to both. |
GetPositions | Returns the current and stop position settings. |
GetAvailable | Returns the range of times in which seeking is efficient. |
SetRate | Sets a new playback rate. |
GetRate | Returns the current rate. |
GetPreroll | Retrieves the preroll settings. |
Determines which capabilities exist on a media stream by applying seeking capability flags and checking the returned value.
HRESULT CheckCapabilities(
DWORD * pCapabilities
);
AM_SEEKING_CanSeekAbsolute |
AM_SEEKING_CanSeekForwards |
AM_SEEKING_CanSeekBackwards |
AM_SEEKING_CanGetCurrentPos |
AM_SEEKING_CanGetStopPos |
AM_SEEKING_CanGetDuration |
AM_SEEKING_CanPlayBackwards |
Returns S_OK if all capabilities in pCapabilities are present, S_FALSE if some are present, or E_FAIL if none are present.
This method determines which seeking capabilities are present on a media stream. It applies the pCapabilities flags using a bitwise-AND operation, and returns a value to indicate whether they match the capabilities of the media stream. The value of pCapabilities is accumulated between successive calls to this method so that the value of pCapabilities can be checked when an S_FALSE value is returned to find the capability that does not match.
Converts a time from one format to another.
HRESULT ConvertTimeFormat(
LONGLONG * pTarget,
const GUID * pTargetFormat,
LONGLONG Source,
const GUID * pSourceFormat
);
Returns an HRESULT value.
Time formats can be converted between any two of the following:
TIME_FORMAT_FIELD |
TIME_FORMAT_FRAME |
TIME_FORMAT_MEDIA_TIME |
TIME_FORMAT_NONE |
TIME_FORMAT_SAMPLE |
Returns the range of times in which seeking is efficient.
HRESULT GetAvailable(
LONGLONG * pEarliest,
LONGLONG * pLatest
);
Returns an HRESULT value.
This method is intended primarily for seeking in media streams that might have excessive latency, such as when playing back media "live" from an Internet server. The returned values indicate cached data that has already arrived, which can be easily seeked. It is assumed that seeking to values beyond these returned parameters will cause a delay while waiting for the data to arrive.
Returns the seeking capabilities of the media stream.
HRESULT GetCapabilities(
DWORD * pCapabilities
);
AM_SEEKING_CanSeekAbsolute |
AM_SEEKING_CanSeekForwards |
AM_SEEKING_CanSeekBackwards |
AM_SEEKING_CanGetCurrentPos |
AM_SEEKING_CanGetStopPos |
AM_SEEKING_CanGetDuration |
AM_SEEKING_CanPlayBackwards |
Returns an HRESULT value.
Retrieves the current position in terms of the total length of the media stream.
HRESULT GetCurrentPosition(
LONGLONG* pCurrent
);
Returns an HRESULT value.
The current position is the position that playback has reached. It is a value between zero and the duration. If the filter graph is paused, this is the position at which it will restart.
Since IMediaSeeking uses media times for its time parameters, the current position value is independent of any rate or start position that might have been set.
When the filter graph is stopped or paused, this method returns the position at which playback will recommence. When the filter graph is running, the filter graph manager returns the position according to the data arriving at the renderer. If an individual filter implements this method, it should return the media time of the sample it is currently processing when paused or running.
After stopping or pausing, a run command causes playback to begin at the current position. This will be where playback stopped or paused, unless there has been an IMediaSeeking::SetPositions call in the meantime to reset the start position.
Retrieves the length of time that the media stream will play.
HRESULT GetDuration(
LONGLONG* pDuration
);
Returns an HRESULT value.
The duration assumes normal playback speed, and it is therefore unaffected by the rate. Although IMediaSeeking allows filters to be seeked in media time, it still requires that the media samples it sends downstream are time stamped appropriately.
Returns the current and stop position settings.
HRESULT GetPositions(
LONGLONG * pCurrent,
LONGLONG * pStop
);
Returns an HRESULT value.
This method is provided for efficiency so that just one call will retrieve both the current and stop position.
Retrieves the preroll settings.
HRESULT GetPreroll(
LONGLONG * pllPreroll
);
Returns an HRESULT value.
This method retrieves the time prior to the start position that the filter graph begins any nonrandom access device rolling.
Retrieves the current rate.
HRESULT GetRate(
double * dRate
);
Returns an HRESULT value.
Retrieves the time at which the media stream stops.
HRESULT GetStopPosition(
LONGLONG* pStop
);
Returns an HRESULT value.
The stop position is a time between zero and the duration of the media at which playback should stop.
The stop position is applied before the rate and therefore is the position at typical playback speed.
Retrieves the current time format, which determines the format of units used during seeking.
HRESULT GetTimeFormat(
GUID * pFormat
);
Returns an HRESULT value.
See the IsFormatSupported method for a list of time formats. Only one time format can be set on the filter graph at any one time.
Determines if a specified time format is supported.
HRESULT IsFormatSupported(
const GUID * pFormat
);
Returns S_OK if the time format is supported; otherwise returns S_FALSE.
Time formats are defined as follows:
GUID | Defined as |
TIME_FORMAT_NONE | Seeking is not supported. |
TIME_FORMAT_FRAME | Seeks to specific video frames. |
TIME_FORMAT_SAMPLE | Seeks to samples in the stream. |
TIME_FORMAT_FIELD | Seeks to interlaced video fields. |
TIME_FORMAT_BYTE | Seeks to a byte in the stream. |
TIME_FORMAT_MEDIA_TIME | Seeks to time stamps on the media samples. |
Third-party vendors are encouraged to add their own time formats to this list.
Determines if the time format being used in the call is the same as the one currently in use by the interface.
HRESULT IsUsingTimeFormat(
const GUID * pFormat
);
Returns S_OK if pFormat is the current time format; otherwise returns S_FALSE.
This can be used in place of IMediaSeeking::GetTimeFormat to compare time formats, since it is faster and does not require copying the GUID.
Retrieves the preferred time format to be used by the interface.
HRESULT QueryPreferredFormat(
GUID * pFormat
);
Returns an HRESULT value.
See the description for IsFormatSupported for a list of available time formats. If the time format returned is not satisfactory, use the IsFormatSupported method to query for supported time formats that you can use.
Sets current and stop positions and applies flags to both.
HRESULT SetPositions(
LONGLONG * pCurrent,
DWORD dwCurrentFlags,
LONGLONG * pStop,
DWORD dwStopFlags
);
Flag | Description |
AM_SEEKING_NoPositioning | No change in positioning. |
AM_SEEKING_AbsolutePositioning | Position supplied is absolute. |
AM_SEEKING_RelativePositioning | Position supplied is relative to the current position. |
AM_SEEKING_IncrementalPositioning | Stop position relative to current; useful for seeking when paused (only valid in conjunction with stop times). |
AM_SEEKING_PositioningBitsMask | Mask flag; determine if seeking is required by performing a bitwise AND of the four flags listed above and this mask. If the resulting value is nonzero, some form of seeking is required. Check the value of the last two bits to determine which of the above flags are set. |
AM_SEEKING_SeekToKeyFrame | Seek to the nearest key frame (not as accurate but quicker). |
AM_SEEKING_ReturnTime | Return the media time equivalents for pCurrent and pStop (overwriting these values with the returned values). |
Returns an HRESULT value.
The following code fragment checks for the type of seeking required.
switch ( dwFlags & AM_SEEKING_PositioningBitsMask ) { case AM_SEEKING_IncrementalPositioning: // Check this is on a stop time // Get Current, add this delta, apply result as new stop time break; case AM_SEEKING_RelativePositioning: // ... break; case AM_SEEKING_AbsolutePositioning: // ... break; case AM_SEEKING_NoPositioning: // Nothing to do. break; }
Sets a new playback rate.
HRESULT SetRate(
double dRate
);
Returns an HRESULT value.
Sets the time format, which determines the format of units used during seeking.
HRESULT SetTimeFormat(
const GUID * pFormat
);
Returns an HRESULT value.
See the IsFormatSupported method for a list of time formats. Note that the filter graph must be stopped before calling this method or a VFW_E_WRONG_STATE error will be returned.
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.