谈判分配器

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

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

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

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

输出引脚还设置分配器属性,这些属性确定分配器创建的缓冲区数、每个缓冲区的大小以及内存对齐方式。 根据缓冲区要求,输出引脚可能遵循输入引脚。

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

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

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

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

提供自定义分配器