注册和枚举 MFT

本部分介绍如何枚举 Media Foundation 转换,以及如何注册自定义 MFT,以便应用程序能够发现它。

枚举 MFT

若要发现系统上注册的 MFT,应用程序可以调用 MFTEnumEx 函数。

注意

此函数需要Windows 7。 在Windows 7 之前,应用程序应改用 MFTEnum 函数。

 

此函数采用以下信息作为输入:

  • 要枚举的 MFT 类别,例如视频解码器或音频解码器。
  • 要匹配的输入或输出格式。
  • 指定其他搜索条件的标志。

该函数返回 一个 IMFActivate 指针数组,每个指针表示与枚举条件匹配的 MFT。

例如,以下代码枚举Windows媒体视频解码器:

HRESULT hr = S_OK;
UINT32 count = 0;

IMFActivate **ppActivate = NULL;    // Array of activation objects.
IMFTransform *pDecoder = NULL;      // Pointer to the decoder.

// Match WMV3 video.
MFT_REGISTER_TYPE_INFO info = { MFMediaType_Video, MFVideoFormat_WMV3 };

UINT32 unFlags = MFT_ENUM_FLAG_SYNCMFT  | 
                 MFT_ENUM_FLAG_LOCALMFT | 
                 MFT_ENUM_FLAG_SORTANDFILTER;

hr = MFTEnumEx(
    MFT_CATEGORY_VIDEO_DECODER,
    unFlags,
    &info,      // Input type
    NULL,       // Output type
    &ppActivate,
    &count
    );


if (SUCCEEDED(hr) && count == 0)
{
    hr = MF_E_TOPO_CODEC_NOT_FOUND;
}

// Create the first decoder in the list.

if (SUCCEEDED(hr))
{
    hr = ppActivate[0]->ActivateObject(IID_PPV_ARGS(&pDecoder));
}

for (UINT32 i = 0; i < count; i++)
{
    ppActivate[i]->Release();
}
CoTaskMemFree(ppActivate);

默认情况下,某些类型的 MFT 从枚举中排除,包括异步 MFT、硬件 MFT 和具有字段使用 restruction 的 MFT。 它们被排除在外,因为它们都需要某种类型的特殊处理。 使用 MFTEnumExFlags 参数更改默认值。 例如,若要在枚举结果中包含硬件 MFT,请设置 MFT_ENUM_FLAG_HARDWARE 标志:

UINT32 unFlags = MFT_ENUM_FLAG_HARDWARE |
                 MFT_ENUM_FLAG_SYNCMFT  | 
                 MFT_ENUM_FLAG_LOCALMFT | 
                 MFT_ENUM_FLAG_SORTANDFILTER;
hr = MFTEnumEx(
    MFT_CATEGORY_VIDEO_DECODER,
    unFlags,
    &info,      // Input type
    NULL,       // Output type
    &ppActivate,
    &count
    );

注册 MFT

注册媒体基础转换 (MFT) 时,会将两种类型的信息写入注册表:

  • MFT 的 CLSID,以便客户端可以调用 CoCreateInstanceCoGetClassObject 来创建 MFT 实例。 此注册表项遵循 COM 类工厂的标准格式。 有关详细信息,请参阅组件对象模型 (COM) 的 Windows SDK 文档。
  • 使应用程序能够按功能类别枚举 MFT 的信息。

若要在注册表中创建 MFT 枚举项,请调用 MFTRegister 函数。 可以包括有关 MFT 的以下信息:

  • MFT 的类别,例如视频解码器或视频编码器。 有关类别列表,请参阅 MFT_CATEGORY
  • MFT 支持的输入和输出格式的列表。 每个格式都由主要类型和子类型定义。 (若要获取更详细的格式信息,客户端必须创建 MFT 并调用 IMFTransform 方法。) 拓扑加载程序在解析部分拓扑时使用此信息。

若要从注册表中删除条目,请调用 MFTUnregister

以下代码演示如何注册 MFT。 此示例假定 MFT 是支持输入和输出相同格式的视频效果。

// CLSID of the MFT.
extern const GUID CLSID_MyVideoEffectMFT;

// DllRegisterServer: Creates the registry entries.
STDAPI DllRegisterServer()
{
    HRESULT hr = S_OK;

    // Array of media types.
    MFT_REGISTER_TYPE_INFO aMediaTypes[] =
    {
        {   MFMediaType_Video, MFVideoFormat_NV12 },
        {   MFMediaType_Video, MFVideoFormat_YUY2 },
        {   MFMediaType_Video, MFVideoFormat_UYVY },
    };

    // Size of the array.
    const DWORD cNumMediaTypes = ARRAY_SIZE(aMediaTypes);

    hr = MFTRegister(
        CLSID_MyVideoEffectMFT,     // CLSID.
        MFT_CATEGORY_VIDEO_EFFECT,  // Category.
        L"My Video Effect",         // Friendly name.
        0,                          // Reserved, must be zero.
        cNumMediaTypes,             // Number of input types.
        aMediaTypes,                // Input types.
        cNumMediaTypes,             // Number of output types.
        aMediaTypes,                // Output types.
        NULL                        // Attributes (optional).
        );

    if (SUCCEEDED(hr))
    {
        // Register the CLSID for CoCreateInstance (not shown).
    }
    return hr;
}

// DllUnregisterServer: Removes the registry entries.
STDAPI DllUnregisterServer()
{
    HRESULT hr = MFTUnregister(CLSID_MyVideoEffectMFT);

    // Unregister the CLSID for CoCreateInstance (not shown).

    return hr;
}

使用限制字段

媒体基础转换