协商分配器

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

当两个引脚连接时,他们需要一个机制来交换媒体数据。 此机制称为 传输。 通常,DirectShow 体系结构与传输无关。 两个筛选器可以同意使用两者都支持的任何传输进行连接。

最常见的传输是 本地内存 传输,其中媒体数据驻留在主内存中。 存在本地内存传输的两种风格,推送模型拉取模型。 在推送模型中,源筛选器使用下游筛选器的输入引脚上的 IMemInputPin 接口将数据推送到下游筛选器。 在拉取模型中,下游筛选器使用源筛选器的输出引脚上的 IAsyncReader 接口从源筛选器请求数据。 有关这两个数据流模型的详细信息,请参阅 Filter Graph 中的数据流。

在本地内存传输中,负责分配内存缓冲区的对象称为 分配器。 分配器支持 IMemAllocator 接口。 两个引脚共享单个分配器。 任一引脚都可以提供分配器,但输出引脚选择要使用的分配器。

输出引脚还设置分配器属性,用于确定分配器创建的缓冲区数、每个缓冲区的大小以及内存对齐方式。 输出引脚可能会延迟输入引脚以满足缓冲区要求。

IMemInputPin 连接中,分配器协商的工作原理如下:

  1. (可选)输出引脚调用 IMemInputPin::GetAllocatorRequirements。 此方法检索输入引脚的缓冲区要求,例如内存对齐方式。 通常,输出引脚应遵循输入引脚的请求,除非有充分的理由不这样做。
  2. (可选)输出引脚调用 IMemInputPin::GetAllocator。 此方法从输入引脚请求分配器。 输入引脚提供一个或返回错误代码。
  3. 输出引脚选择分配器。 它可以使用输入引脚提供的一个,也可以创建自己的。
  4. 输出引脚调用 IMemAllocator::SetProperties 来设置分配器属性。 但是,分配器可能不遵循请求的属性。 (例如,如果输入引脚提供分配器,则可能会发生这种情况。分配器将实际属性作为 SetProperties 方法中的输出参数返回。
  5. 输出调用 IMemInputPin::NotifyAllocator,以通知所选内容的输入引脚。
  6. 输入引脚应调用 IMemAllocator::GetProperties 来验证分配器属性是否可接受。
  7. 输出引脚负责提交和解除分配器。 当流式处理启动和停止时,将发生这种情况。

IAsyncReader 连接中,分配器协商的工作原理如下:

  1. 输入引脚在输出引脚上调用 IAsyncReader::RequestAllocator。 输入引脚指定其缓冲区要求,(可选)提供分配器。
  2. 输出引脚选择分配器。 它可以使用输入引脚提供的内容(如果有)或创建自己的输入引脚。
  3. 输出引脚在 RequestAllocator 方法中将分配器作为传出参数返回。 输入引脚应检查分配器属性。
  4. 输入引脚负责提交和取消分配器。
  5. 在分配器协商过程中,任一引脚都可能会失败连接。
  6. 如果输出引脚使用输入引脚的分配器,则它只能使用该分配器将样本传送到该输入引脚。 拥有筛选器不得使用分配器将样本传送到其他引脚。

提供自定义分配器