DirectShow 筛选器开发简介

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

本部分简要概述了开发自定义 DirectShow 筛选器所涉及的任务。 它还提供了指向更详细地讨论这些任务的主题的链接。 在阅读本部分之前,请阅读 关于 DirectShow 中的主题,其中介绍了整个 DirectShow 体系结构。

DirectShow 基类库

DirectShow SDK 包含一组用于编写筛选器的 C++ 类。 尽管它们不是必需的,但这些类是编写新筛选器的建议方法。 若要使用基类,请将它们编译为静态库,并将 .lib 文件链接到项目,如 生成 DirectShow 筛选器中所述。

基类库定义筛选器的根类,即 CBaseFilter 类。 其他几个类派生自 CBaseFilter,专用于特定类型的筛选器。 例如, CTransformFilter 类专为转换筛选器而设计。 若要创建新筛选器,请实现继承自其中一个筛选器类的类。 例如,类声明可能如下所示:

class CMyFilter : public CTransformFilter
{
private:
    /* Declare variables and methods that are specific to your filter.
public:
    /* Override various methods in CTransformFilter */
};

有关 DirectShow 基类的详细信息,请参阅以下主题:

创建图钉

筛选器必须创建一个或多个引脚。 可以在设计时固定引脚数,或者筛选器可以根据需要创建新引脚。 引脚通常派生自 CBasePin 类,或从继承 CBasePin 的类(如 CBaseInputPin) 派生。 筛选器的引脚应在筛选器类中声明为成员变量。 某些筛选器类已定义引脚,但如果筛选器直接继承自 CBaseFilter,则必须在派生类中声明引脚。

协商引脚连接

当筛选器关系图管理器尝试连接两个筛选器时,引脚必须在各种方面达成一致。 如果不能,则连接尝试将失败。 通常,引脚协商以下内容:

  • 传输。 传输是筛选器用于将媒体样本从输出引脚移动到输入引脚的机制。 例如,他们可以使用 IMemInputPin 接口 (“push model”) 或 IAsyncReader 接口 (“pull model”) 。
  • 媒体类型。 几乎所有引脚都使用媒体类型来描述它们将传递的数据的格式。
  • 分配器。 分配器是创建保存数据的缓冲区的对象。 引脚必须同意哪个引脚将提供分配器。 他们还必须就缓冲区的大小、要创建的缓冲区数以及其他缓冲区属性达成一致。

基类为这些协商实现框架。 必须通过重写基类中的各种方法来完成详细信息。 必须重写的方法集取决于 类和筛选器的功能。 有关详细信息,请参阅 筛选器连接方式

处理和传送数据

大多数筛选器的主要功能是处理和传送媒体数据。 其发生方式取决于筛选器的类型:

  • 推送源具有一个工作线程,该线程持续填充数据并将样本传送到下游。
  • 拉取源等待其下游邻居请求样本。 它通过将数据写入样本并将样本传送到下游筛选器来做出响应。 下游筛选器创建驱动数据流的线程。
  • 转换筛选器具有由其上游邻居传递给它的样本。 当它收到样本时,它会处理数据并将其传送到下游。
  • 呈现器筛选器从上游接收样本,并根据时间戳计划这些样本的呈现。

与流式处理相关的其他任务包括刷新图形中的数据、处理流的末尾以及响应查找请求。 有关这些问题的详细信息,请参阅以下主题:

支持 COM

DirectShow 筛选器是 COM 对象,通常打包在 DLL 中。 基类库实现用于支持 COM 的框架。 DirectShow 和 COM 部分中介绍了这一点。

编写 DirectShow 筛选器