自定义混音器

[此页中所述的组件增强的视频呈现器是一项旧功能。 它已由通过 MediaPlayerIMFMediaEngine 组件公开的简单视频呈现器 (SVR) 取代。 若要播放视频内容,应将数据发送到其中一个组件,并允许它们实例化新的视频呈现器。 这些组件已针对 Windows 10 和 Windows 11 进行了优化。 Microsoft 强烈建议新代码在 Windows 中尽可能使用 MediaPlayer 或较低级别的 IMFMediaEngine API 而不是 EVR 播放视频媒体。 如果可能,Microsoft 建议应重写使用旧 API 的现有代码,以尽可能地使用新的 API。]

本主题介绍如何为增强的视频呈现器 (EVR) 编写自定义混合器。 可以将自定义混合器与媒体基础 EVR 媒体接收器或 DirectShow EVR 筛选器配合使用。 有关混合器和演示器的详细信息,请参阅“增强的视频呈现器”。

混合器是一个媒体基础转换 (MFT),其中包含一个或多个输入(引用流加子流)和一个输出。 输入流会从上游接收样本。 输出流会将示例传送到演示器。 EVR 负责在混合器上调用 IMFTransform::ProcessInput,演示器负责调用 IMFTransform::ProcessOutput

EVR 混合器必须至少实现以下接口:

接口 说明
IMFTransform 提供基本 MFT 功能。
IMFTopologyServiceLookupClient 使混合器能够从 EVR 获取接口。
IMFVideoDeviceID 使混合器能够从 EVR 获取接口。
IMFAttributes 用于向 EVR 公开 MF_SA_D3D_AWARE 属性。

 

(可选)MFT 可以实现以下任何接口:

接口 说明
IEVRTrustedVideoPlugin 需要播放受保护的内容。
IMFGetService 向应用程序公开 IMFVideoMixerBitmapIMFVideoProcessor 等接口。
IMFQualityAdvise 使质量管理器能够调整视频质量。
IMFVideoMixerBitmap 使应用程序能够将静态位图混合到视频中。
IMFVideoPositionMapper 将输出视频帧上的坐标映射到输入视频帧上的坐标。
IMFVideoProcessor 向应用程序公开一些 DXVA 视频处理功能。

 

与混合器进行格式协商的工作原理如下:

  1. EVR 会在引用流上设置媒体类型。

  2. EVR 使用 MFVP_MESSAGE_INVALIDATEMEDIATYPE 消息在演示器上调用 IMFVideoPresenter::ProcessMessage

  3. 演示器对混合器的输出流设置媒体类型。

  4. EVR 会在子流上设置媒体类型。

如果引用流上的媒体类型发生更改,混合器的其他媒体类型将不再有效。 然后,混合器的 IMFTransform::ProcessOutput 方法将失败并返回 MF_E_TRANSFORM_STREAM_CHANGE。 演示器此时不应执行任何操作。 EVR 将再次启动格式协商过程。

当任何输入流到达流的末尾时,EVR 会在混合器上调用 IMFTransform::ProcessMessage 并使用 MFT_MESSAGE_NOTIFY_END_OF_STREAM

混合器使用 EVR 的 IMediaEventSink 接口将以下事件发送到 EVR。 此接口记录在 DirectShow SDK 文档中。

事件 说明
EC_SAMPLE_NEEDED 混合器需要新的输入样本。

 

在流式处理开始之前,EVR 可能会在混合器上调用 ProcessOutput。 混合器不应使这些调用失败。 相反,它应使用黑色像素填充输出图面。 混合器应继续着色填充输出样本,直到收到 MFT_MESSAGE_NOTIFY_BEGIN_STREAMING 消息或调用了 ProcessInput 方法。 如果混合器收到 MFT_MESSAGE_NOTIFY_END_STREAMING 消息,则应切换回颜色填充模式。

实现 IMFVideoDeviceID

IMFVideoDeviceID 接口包含一个方法 GetDeviceID,该方法返回设备 GUID。 设备 GUID 确保演示器和混合器使用兼容的技术。 如果设备 GUID 不匹配,EVR 将无法初始化。

标准混合器和演示器都使用 Direct3D 9,设备 GUID 等于 IID_IDirect3DDevice9。 如果打算将自定义演示器与标准混合器一起使用,则演示器的设备 GUID 必须为 IID_IDirect3DDevice9。 如果替换这两个组件,则可以定义新的设备 GUID。

实现 IMFTopologyServiceLookupClient

混合器必须实现 IMFTopologyServiceLookupClient 接口。 在流式处理开始之前,EVR 会调用 IMFTopologyServiceLookupClient::InitServicePointers,并传入指向 EVR IMFTopologyServiceLookup 接口的指针。 混合器使用此指针从 EVR 获取接口指针。

混合器必须至少查询以下接口:

当 EVR 调用 IMFTopologyServiceLookupClient::ReleaseServicePointers 时,混合器必须释放从 InitServicePointers 调用中获得的指针。

混合器属性

混合器应支持以下属性。

Attribute 说明
MF_SA_D3D_AWARE 指定混合器是否支持 DirectX 视频加速 (DXVA)。
MF_SA_REQUIRED_SAMPLE_COUNT EVR 应为每个混合器流分配的视频样本数。 此属性适用于单个流;使用 IMFTransform::GetInputStreamAttributes 返回的属性存储。

 

在 EVR 上设置混合器

若要在 EVR 上设置自定义混合器,请调用 IMFVideoRenderer::InitializeRenderer。 DirectShow EVR 筛选器和 EVR 媒体接收器都会实现此方法。

EVR 激活对象。 如果使用 EVR 激活对象,则可以通过在 EVR 激活对象上设置以下属性之一来提供自定义混合器:

Attribute 说明
MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE 指向混合器的激活对象的指针。 激活对象必须实现 IMFActivate 接口。
MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID 混合器的 CLSID。

 

增强的视频呈现器