CSourceSeeking 类
[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayer、 IMFMediaEngine 和 媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayer、 IMFMediaEngine 和 Media Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]
CSourceSeeking 类是一个抽象类,用于通过一个输出引脚实现在源筛选器中查找。
此类支持 IMediaSeeking 接口。 它为所有 IMediaSeeking 方法提供默认实现。 受保护的成员变量存储开始时间、停止时间和当前速率。 默认情况下,类支持的唯一时间格式是 TIME_FORMAT_MEDIA_TIME (100 纳秒单位) 。 有关更多信息,请参见备注。
受保护的成员变量 | 说明 |
---|---|
m_rtDuration | 流的持续时间。 |
m_rtStart | 开始时间。 |
m_rtStop | 停止时间。 |
m_dRateSeeking | 播放速率。 |
m_dwSeekingCaps | 寻求功能。 |
m_pLock | 指向用于锁定的关键节对象的指针。 |
受保护的方法 | 说明 |
CSourceSeeking | 构造函数方法。 |
纯虚拟方法 | 说明 |
ChangeRate | 在播放速率更改时调用。 |
ChangeStart | 在开始位置更改时调用。 |
ChangeStop | 在停止位置更改时调用。 |
IMediaSeeking 方法 | 说明 |
IsFormatSupported | 确定是否支持指定的时间格式。 |
QueryPreferredFormat | 检索对象的首选时间格式。 |
SetTimeFormat | 设置时间格式。 |
IsUsingTimeFormat | 确定指定的时间格式是否为当前使用的格式。 |
GetTimeFormat | 检索当前时间格式。 |
GetDuration | 检索流的持续时间。 |
GetStopPosition | 检索相对于流持续时间停止播放的时间。 |
GetCurrentPosition | 检索相对于流总持续时间的当前位置。 |
GetCapabilities | 检索流的所有查找功能。 |
CheckCapabilities | 查询流是否具有指定的查找功能。 |
ConvertTimeFormat | 将时间格式从一种时间格式转换为另一种时间格式。 |
SetPositions | 设置当前位置和停止位置。 |
GetPositions | 检索当前位置和停止位置。 |
GetAvailable | 检索查找效率的时间范围。 |
SetRate | 设置播放速率。 |
GetRate | 检索播放速率。 |
GetPreroll | 检索预滚动时间。 |
备注
每当开始位置、停止位置或播放速率发生更改时, CSourceSeeking 对象将调用相应的纯虚拟方法:
- 开始位置: CSourceSeeking::ChangeStart
- 停止位置: CSourceSeeking::ChangeStop
- 播放速率: CSourceSeeking::ChangeRate
派生类必须实现这些方法。 执行任何查找操作后,筛选器必须执行以下操作:
- 在下游输入引脚上调用 IPin::BeginFlush 方法。
- 停止传送数据的工作线程。
- 在输入引脚上调用 IPin::EndFlush 方法。
- 重启工作线程。
- 在输入引脚上调用 IPin::NewSegment 方法。
- 在第一个示例上设置不连续属性。 调用 IMediaSample::SetDiscontinuity 方法。
如果线程被阻止,则对 BeginFlush 的调用将释放工作线程,以等待提供示例。
在步骤 2 中,确保线程已停止发送数据。 根据实现,可能需要等待线程退出,或等待线程发出某种响应信号。 如果筛选器使用 CSourceStream 类,则 CSourceStream::Stop 方法将阻止,直到工作线程答复。
理想情况下,应从工作线程传送步骤 5) 步骤 5 的新 (段。 只要筛选器使用示例对其进行序列化, CSourceSeeking 对象也可以完成此操作。
以下示例演示了可能的实现。 它假定源筛选器的输出引脚派生自 CSourceSeeking 和 CSourceStream。 此示例定义执行步骤 1 4 的帮助程序方法 UpdateFromSeek。 将重写 CSourceStream::OnThreadStartPlay 方法以发送新段,并设置指示不连续的标志。 工作线程选取此标志并调用 IMediaSample::SetDiscontinuity 方法:
void CMyStream::UpdateFromSeek()
{
if (ThreadExists())
{
DeliverBeginFlush();
Stop();
DeliverEndFlush();
Run();
}
}
HRESULT CMyStream::OnThreadStartPlay()
{
m_bDiscontinuity = TRUE;
return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking);
}
支持其他时间格式
默认情况下,此类仅支持以引用时间 (TIME_FORMAT_MEDIA_TIME) 单位查找。 若要支持其他时间格式,请重写处理时间格式的 IMediaSeeking 方法:
- IMediaSeeking::GetTimeFormat
- IMediaSeeking::GetTimeFormat
- IMediaSeeking::IsUsingTimeFormat
- IMediaSeeking::IsUsingTimeFormat
- IMediaSeeking::SetTimeFormat
此外,重写剩余的 IMediaSeeking 方法,以在时间格式之间执行必要的转换。 调用 SetTimeFormat 方法后,所有 IMediaSeeking 方法都必须将传入和传出时间参数视为采用新的时间格式。 例如,如果 m_rtDuration 变量以引用时间单位表示持续时间,但当前时间格式为帧,则 GetDuration 方法必须返回 m_rtDuration 转换为帧的值。 例如:
STDMETHODIMP GetDuration(LONGLONG *pDuration)
{
HRESULT hr = CSourceSeeking::GetDuration(pDuration);
if (SUCCEEDED(hr))
{
if (m_TimeFormat == TIME_FORMAT_FRAME)
{
// Convert from reference time to frames.
*pDuration = TimeToFrame(*pDuration); // Private method.
}
}
return hr
}
此外,请确保在 IMediaSeeking::SetPositions 方法中为 AM_SEEKING_ReturnTime 标志检查。 如果存在此标志,请在将位置值返回到调用方时将其转换为引用时间。
要求
要求 | 值 |
---|---|
标头 |
|
库 |
|