CSourceSeeking 类

[与此页面关联的功能 DirectShow 是一项旧功能。 它已被 MediaPlayerIMFMediaEngine媒体基金会中的音频/视频捕获取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能使用 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

csourceseeking 类层次结构

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 对象将调用相应的纯虚拟方法:

派生类必须实现这些方法。 执行任何查找操作后,筛选器必须执行以下操作:

  1. 在下游输入引脚上调用 IPin::BeginFlush 方法。
  2. 停止传送数据的工作线程。
  3. 在输入引脚上调用 IPin::EndFlush 方法。
  4. 重启工作线程。
  5. 在输入引脚上调用 IPin::NewSegment 方法。
  6. 在第一个示例上设置不连续属性。 调用 IMediaSample::SetDiscontinuity 方法。

如果线程被阻止,则对 BeginFlush 的调用将释放工作线程,以等待提供示例。

在步骤 2 中,确保线程已停止发送数据。 根据实现,可能需要等待线程退出,或等待线程发出某种响应信号。 如果筛选器使用 CSourceStream 类,则 CSourceStream::Stop 方法将阻止,直到工作线程答复。

理想情况下,应从工作线程传送步骤 5) 步骤 5 的新 (段。 只要筛选器使用示例对其进行序列化, CSourceSeeking 对象也可以完成此操作。

以下示例演示了可能的实现。 它假定源筛选器的输出引脚派生自 CSourceSeekingCSourceStream。 此示例定义执行步骤 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 方法,以在时间格式之间执行必要的转换。 调用 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 标志检查。 如果存在此标志,请在将位置值返回到调用方时将其转换为引用时间。

要求

要求
标头
Ctlutil.h (包括 Streams.h)

Strmbase.lib (零售版本) ;
Strmbasd.lib (调试生成)

另请参阅

支持在源筛选器中查找