Microsoft DirectX 8.0 |
Abstract class for implementing seeking in source filters with one output pin.
Declaration: Ctlutil.h.
This class supports the IMediaSeeking interface. It provides default implementations for all of the IMediaSeeking methods. Protected member variables store the start time, stop time, and current rate. By default, the only time format supported by the class is TIME_FORMAT_MEDIA_TIME (100-nanosecond units).
Whenever the start position, stop position, or playback rate changes, the CSourceSeeking object calls a corresponding pure virtual method:
The derived class must implement these methods. After any seek operation, a filter must do the following:
The call to BeginFlush frees the worker thread, if the thread is blocked waiting to deliver a sample.
In step 2, make sure that the thread has stopped sending data. Depending on the implementation, you might need to wait for the thread to exit, or for the thread to signal a response of some kind. If your filter uses the CSourceStream class, the CSourceStream::Stop method blocks until the worker thread replies.
Ideally, the new segment (step 5) should be delivered from the worker thread. It can also be done by the CSourceSeeking object, as long as the filter serializes it with the samples.
The following example shows a possible implementation. It assumes that the source filter's output pin is derived from CSourceSeeking and CSourceStream. This example defines a helper method, UpdateFromSeek, that performs steps 14. The CSourceStream::OnThreadStartPlay method is overridden to send the new segment, and to set a flag indicating the discontinuity. The worker thread picks up this flag and calls the IMediaSample::SetDiscontinuity method:
void CMyStream::UpdateFromSeek() { if (ThreadExists()) { DeliverBeginFlush(); Stop(); DeliverEndFlush(); Run(); } } HRESULT CMyStream::OnThreadStartPlay() { m_bDiscontinuity = TRUE; return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking); }
Protected Member Variables | |
---|---|
m_rtDuration | Duration of the stream. |
m_rtStart | Start time. |
m_rtStop | Stop time. |
m_dRateSeeking | Playback rate. |
m_dwSeekingCaps | Seeking capabilities. |
m_pLock | Pointer to a critical section object for locking. |
Protected Methods | |
CSourceSeeking | Constructor method. |
Pure Virtual Methods | |
ChangeRate | Called when the playback rate changes. |
ChangeStart | Called when the start position changes. |
ChangeStop | Called when the stop position changes. |
IMediaSeeking Methods | |
IsFormatSupported | Determines whether a specified time format is supported. |
QueryPreferredFormat | Retrieves the object's preferred time format. |
SetTimeFormat | Sets the time format. |
IsUsingTimeFormat | Determines whether a specified time format is the format currently in use. |
GetTimeFormat | Retrieves the current time format. |
GetDuration | Retrieves the duration of the stream. |
GetStopPosition | Retrieves the time at which the playback will stop, relative to the duration of the stream. |
GetCurrentPosition | Retrieves the current position, relative to the total duration of the stream. |
GetCapabilities | Retrieves all the seeking capabilities of the stream. |
CheckCapabilities | Queries whether the stream has specified seeking capabilities. |
ConvertTimeFormat | Converts from one time format to another. |
SetPositions | Sets the current position and the stop position. |
GetPositions | Retrieves the current position and the stop position. |
GetAvailable | Retrieves the range of times in which seeking is efficient. |
SetRate | Sets the playback rate. |
GetRate | Retrieves the playback rate. |
GetPreroll | Retrieves the preroll time. |
Duration of the stream. By default, the value is set to the value of the m_rtStop member variable.
Syntax
CRefTime m_rtDuration;
Start time. By default, the value is set to zero.
Syntax
CRefTime m_rtStart;
Stop time. By default, the value is set to a very large number. The derived class can reset the value in its constructor, or when the filter is initialized.
Syntax
CRefTime m_rtStop;
Playback rate. By default, the value is set to 1.0.
Syntax
double m_dRateSeeking;
Seeking capabilities.
Syntax
DWORD m_dwSeekingCaps;
Remarks
By default, the value is set to the bitwise combination of the following flags:
- AM_SEEKING_CanSeekForwards
- AM_SEEKING_CanSeekBackwards
- AM_SEEKING_CanSeekAbsolute
- AM_SEEKING_CanGetStopPos
- AM_SEEKING_CanGetDuration
If the filter supports a different set of capabilities, it should override this value.
Pointer to a critical section object for locking.
Syntax
CCritSec *m_pLock;
Called when the playback rate changes.
Syntax
virtual HRESULT ChangeRate(void) PURE;
Return Value
Returns an HRESULT value.
Remarks
The SetRate method calls this method, which the derived class must implement. The SetRate method updates the m_dRateSeeking member variable, but does not validate the new value. A rate of zero should always be rejected. Rates less than zero indicate negative playback. Most filters do not support negative rates.
The following example shows a possible implementation:
HRESULT CMyStream::ChangeRate( ) { { CAutoLock cAutoLockSeeking(CSourceSeeking::m_pLock); if( m_dRateSeeking <= 0 ) { m_dRateSeeking = 1.0; // Reset to a reasonable value. return E_FAIL; } } UpdateFromSeek(); return S_OK; }
Called when the start position changes.
Syntax
virtual HRESULT ChangeStart(void) PURE;
Return Value
Returns an HRESULT value.
Remarks
The SetPositions method calls this method if the start position changes. This method is pure virtual; the derived class must implement it. After a seek operation, time stamps should restart from zero. Media times should reflect the new start time. The following example shows a possible implementation:
HRESULT CMyStream::ChangeStart( ) { m_rtSampleTime = 0; // Reset the time stamps. m_rtMediaTime = m_rtStart; // Reset the media times. UpdateFromSeek(); return S_OK; }
Called when the stop position changes.
Syntax
virtual HRESULT ChangeStop(void) PURE;
Return Value
Returns an HRESULT value.
Remarks
The SetPositions method calls this method if the stop position changes. This method is pure virtual; the derived class must implement it. The following example shows a possible implementation:
HRESULT CMyStream::ChangeStop( ) { UpdateFromSeek(); return S_OK; }
Queries whether the stream has specified seeking capabilities. Implements the IMediaSeeking::CheckCapabilities method.
Syntax
HRESULT CheckCapabilities( DWORD *pCapabilities );
Parameters
- pCapabilities
- Pointer to a bitwise combination of one or more AM_SEEKING_SEEKING_CAPABILITIES attributes.
Return Value
Returns one of the HRESULT values listed in the following table.
S_FALSE Not all of the capabilities in pCapabilities are present. S_OK All capabilities in pCapabilities are present. E_POINTER NULL pointer argument.
Remarks
As implemented, this method checks the value of *pCapabilities against the m_dwSeekingCaps member variable. However, it does not set *pCapabilities equal to m_dwSeekingCaps, as described for the IMediaSeeking::CheckCapabilities method. Also, in the case where none of the specified capabilities are available, the method does not return E_FAIL. A more complete implementation would be as follows:
DWORD dwCaps; HRESULT hr = GetCapabilities(&dwCaps); if (SUCCEEDED(hr)) { dwCaps &= *pCapabilities; hr = dwCaps ? ( dwCaps == *pCapabilities ? S_OK : S_FALSE ) : E_FAIL; *pCapabilities = dwCaps; } else *pCapabilities = 0; return hr;
Converts from one time format to another. Implements the IMediaSeeking::ConvertTimeFormat method.
Syntax
HRESULT ConvertTimeFormat( LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat );
Parameters
- pTarget
- Pointer to a variable that receives the converted time.
- pTargetFormat
- Pointer to the time format GUID of the target format. If NULL, the current format is used.
- Source
- Time value to be converted.
- pSourceFormat
- Pointer to the time format GUID of the format to convert. If NULL, the current format is used.
Return Value
Returns one of the HRESULT values listed in the following table.
S_OK Success E_INVALIDARG Invalid argument E_POINTER NULL pointer argument
Remarks
The only time format supported by the base class is TIME_FORMAT_MEDIA_TIME (100-nanosecond units). This method returns E_INVALIDARG, except in the trivial case where pTargetFormat and pSourceFormat both specify TIME_FORMAT_MEDIA_TIME.
Constructor method.
Syntax
CSourceSeeking( const TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr, CCritSec *pLock );
Parameters
- pName
- Pointer to a string containing the name of the object. For more information, see CBaseObject.
- pUnk
- Pointer to the owner of this object. If the object is aggregated, pass a pointer to the aggregating object's IUnknown interface. Otherwise, set this parameter to NULL.
- phr
- Pointer to an HRESULT value. Ignored.
- pLock
- Pointer to a CCritSec object that protects shared data used by this class.
Retrieves the range of times in which seeking is efficient. Implements the IMediaSeeking::GetAvailable method.
Syntax
HRESULT GetAvailable( LONGLONG *pEarliest, LONGLONG *pLatest );
Parameters
- pEarliest
- Pointer to a variable that receives the earliest time for efficient seeking. The variable is set to zero.
- pLatest
- Pointer to a variable that receives the latest time for efficient seeking. The variable is set to the value of the m_rtDuration member variable.
Return Value
Returns S_OK.
Retrieves all the seeking capabilities of the stream. Implements the IMediaSeeking::GetCapabilities method.
Syntax
HRESULT GetCapabilities( DWORD *pCapabilities );
Parameters
- pCapabilities
- Pointer to a variable that receives a bitwise combination of AM_SEEKING_SEEKING_CAPABILITIES flags.
Return Value
Returns one of the HRESULT values listed in the following table.
S_OK Success E_POINTER NULL pointer value
Remarks
The seeking capabilities are specified by the m_dwSeekingCaps member variable.
Retrieves the current position, relative to the total duration of the stream. Not implemented.
Syntax
HRESULT GetCurrentPosition( LONGLONG *pCurrent );
Parameters
- pCurrent
- Pointer to a variable that receives the current position, in units of the current time format.
Return Value
Returns E_NOTIMPL.
Remarks
Source filters typically do not support this method. Instead, renderer filters report the current position through the CRendererPosPassThru class.
Retrieves the duration of the stream. Implements the IMediaSeeking::GetDuration method.
Syntax
HRESULT GetDuration( LONGLONG *pDuration );
Parameters
- pDuration
- Pointer to a variable that receives the duration, in units of the current time format.
Return Value
Returns one of the HRESULT values listed in the following table.
S_OK Success E_POINTER NULL pointer value
Remarks
The duration is specified by the m_rtDuration member variable.
Retrieves the current position and the stop position. Implements the IMediaSeeking::GetPositions method.
Syntax
HRESULT GetPositions( LONGLONG *pCurrent, LONGLONG *pStop );
Parameters
- pCurrent
- Pointer to a variable that receives the start position.
- pStop
- Pointer to a variable that receives the stop position.
Return Value
Returns S_OK.
Remarks
For the pCurrent parameter, this method returns the value of the m_rtStart member variable, which represents the latest seek time, not the current streaming position. However, when an application calls IMediaSeeking::GetPositions through the filter graph manager, the values typically come from a renderer filter, not a source filter.
Retrieves the preroll time. Implements the IMediaSeeking::GetPreroll method.
Syntax
HRESULT GetPreroll( LONGLONG *pPreroll );
Parameters
- pPreroll
- Pointer to a variable that receives the preroll time. The value is set to zero.
Return Value
Returns one of the HRESULT values listed in the following table.
S_OK Success E_POINTER NULL pointer value
Retrieves the playback rate. Implements the IMediaSeeking::GetRate method.
Syntax
HRESULT GetRate( double *pdRate );
Parameters
- pdRate
- Pointer to a variable that receives the playback rate.
Return Value
Returns one of the HRESULT values listed in the following table.
S_OK Success E_POINTER NULL pointer value
Remarks
The playback rate is specified by the m_dRateSeeking member variable.
Retrieves the time at which the playback will stop, relative to the duration of the stream. Implements the IMediaSeeking::GetStopPosition method.
Syntax
HRESULT GetStopPosition( LONGLONG *pStop );
Parameters
- pStop
- Pointer to a variable that receives the stop time, in units of the current time format.
Return Value
Returns one of the HRESULT values listed in the following table.
S_OK Success E_POINTER NULL pointer value
Remarks
The stop time is specified by the m_rtStop member variable.
Retrieves the current time format. Implements the IMediaSeeking::GetTimeFormat method.
Syntax
HRESULT GetTimeFormat( const GUID *pFormat );
Parameters
- pFormat
- Pointer to a variable that receives a time format GUID.
Return Value
Returns one of the HRESULT values listed in the following table.
S_OK Success E_POINTER NULL pointer value
Remarks
The only time format supported by the base class is TIME_FORMAT_MEDIA_TIME (100-nanosecond units).
Determines whether a specified time format is supported. Implements the IMediaSeeking::IsFormatSupported method.
Syntax
HRESULT IsFormatSupported( const GUID *pFormat );
Parameters
- pFormat
- Pointer to a time format GUID.
Return Value
Returns one of the HRESULT values listed in the following table.
S_FALSE The format is not supported. S_OK The format is supported. E_POINTER NULL pointer argument.
Remarks
The only time format supported by the base class is TIME_FORMAT_MEDIA_TIME (100-nanosecond units).
Determines whether a specified time format is the format currently in use.
Syntax
HRESULT IsUsingTimeFormat( const GUID *pFormat );
Parameters
- pFormat
- Pointer to a time format GUID.
Return Value
Returns one of the HRESULT values listed in the following table.
S_FALSE The specified format is not the current format. S_OK The specified format is the current format. E_POINTER NULL pointer argument.
Remarks
The only time format supported by the base class is TIME_FORMAT_MEDIA_TIME (100-nanosecond units).
Retrieves the object's preferred time format. Implements the IMediaSeeking::QueryPreferredFormat method.
Syntax
HRESULT QueryPreferredFormat( GUID *pFormat );
Parameters
- pFormat
- Pointer to a variable that receives a time format GUID.
Return Value
Returns one of the HRESULT values listed in the following table.
S_OK Success E_POINTER NULL pointer value
Remarks
The only time format supported by the base class is TIME_FORMAT_MEDIA_TIME (100-nanosecond units).
Sets the current position and the stop position. Implements the IMediaSeeking::SetPositions method.
Syntax
HRESULT SetPositions( LONGLONG *pCurrent, DWORD CurrentFlags, LONGLONG *pStop, DWORD StopFlags );
Parameters
- pCurrent
- Pointer to a variable that specifies the current position.
- CurrentFlags
- Bitwise combination of flags. See Remarks.
- pStop
- Pointer to a variable that specifies the stop time, in units of the current time format.
- StopFlags
- Bitwise combination of flags. See Remarks.
Return Value
Returns an HRESULT value. Possible values include those listed in the following table.
S_OK Success E_INVALIDARG Invalid flags E_POINTER NULL pointer argument
Remarks
The following flags are supported:
- AM_SEEKING_NoPositioning
- AM_SEEKING_AbsolutePositioning
- AM_SEEKING_RelativePositioning
- AM_SEEKING_IncrementalPositioning (pStop only)
For more information, see IMediaSeeking::SetPositions.
This method updates the values of the m_rtStart and m_rtStop member variables, and then calls the pure virtual methods ChangeStart and ChangeStop.
Sets the playback rate. Implements the IMediaSeeking::SetRate method.
Syntax
HRESULT SetRate( double dRate );
Parameters
- dRate
- Playback rate.
Return Value
Returns an HRESULT value.
Remarks
This method updates the value of the m_dRateSeeking member variable, and then calls the pure virtual method ChangeRate. The method does not validate the dRate parameter.
Sets the time format. Implements the IMediaSeeking::SetTimeFormat method.
Syntax
HRESULT SetTimeFormat( const GUID *pFormat );
Parameters
- pFormat
- Pointer to a time format GUID.
Return Value
Returns one of the HRESULT values listed in the following table.
S_OK Success. E_INVALIDARG Specified format is not supported. E_POINTER NULL pointer argument.
Remarks
The only time format supported by the base class is TIME_FORMAT_MEDIA_TIME (100-nanosecond units).