共用方式為


MFTEnum2 函式 (mfapi.h)

取得符合指定搜尋準則的 Microsoft Media Foundation 轉換清單 (MFT) 。 此函式會擴充 MFTEnumEx 函式,以允許外部應用程式和內部元件探索對應至特定視訊適配卡的硬體 MFT。

語法

HRESULT MFTEnum2(
  [in]           GUID                         guidCategory,
  [in]           UINT32                       Flags,
  [in]           const MFT_REGISTER_TYPE_INFO *pInputType,
  [in]           const MFT_REGISTER_TYPE_INFO *pOutputType,
  [in, optional] IMFAttributes                *pAttributes,
  [out]          IMFActivate                  ***pppMFTActivate,
  [out]          UINT32                       *pnumMFTActivate
);

參數

[in] guidCategory

GUID,指定要列舉的 MFT 類別。 如需 MFT 類別清單,請參閱 MFT_CATEGORY

[in] Flags

_MFT_ENUM_FLAG列舉中零個或多個旗標的位 OR

[in] pInputType

MFT_REGISTER_TYPE_INFO 結構的指標,指定要比對的輸入媒體類型。

此參數可以是 Null。 如果 為 NULL,則會比對所有輸入類型。

[in] pOutputType

MFT_REGISTER_TYPE_INFO 結構的指標,指定要比對的輸出媒體類型。

此參數可以是 Null。 如果 為 NULL,則會比對所有輸出類型。

[in, optional] pAttributes

可存取標準屬性存放區之 IMFAttributes 介面的指標。 若要指定查詢 MFT 的特定硬體適配卡,請將 MFT_ENUM_ADAPTER_LUID 屬性設定為適配卡的 LUID。 如果您這樣做,也必須指定傳回MFT_ENUM_FLAG_HARDWARE旗標或E_INVALIDARG。

[out] pppMFTActivate

接收 IMFActivate 介面指標的陣列。 每個指標都代表符合搜尋準則之 MFT 的啟用物件。 函式會配置陣列的記憶體。 呼叫端必須釋放指標,並呼叫 CoTaskMemFree 函式以釋放數位的記憶體。

[out] pnumMFTActivate

接收 pppMFTActivate 陣列中的項目數目。 如果沒有 MFT 符合搜尋準則,此參數就會收到零值。

傳回值

如果方法成功,它會傳回 S_OK。 如果失敗,可能的傳回碼包括,但不限於下表所示的值。

傳回碼 Description
E_INVALIDARG
pAttributes 參數中提供了包含MFT_ENUM_ADAPTER_LUID屬性的IMFAttributes,而且未指定MFT_ENUM_FLAG_HARDWARE旗標。

備註

Flags 參數會控制要列舉的 MFT,以及傳回它們的順序。 此參數的旗標分為數個群組。

第一組旗標會指定 MFT 如何處理數據。

旗標 描述
MFT_ENUM_FLAG_SYNCMFT MFT 會在軟體中執行同步數據處理。 這是原始的 MFT 處理模型,且與 Windows Vista 相容。
MFT_ENUM_FLAG_ASYNCMFT MFT 會在軟體中執行異步數據處理。 此處理模型需要 Windows 7。 如需詳細資訊,請參閱 異步 MFT
MFT_ENUM_FLAG_HARDWARE MFT 會使用 AVStream 驅動程式或 GPU 型 Proxy MFT 來執行硬體型數據處理。 此類別中的 MFT 一律以異步方式處理數據。 如需詳細資訊,請參閱 硬體 MFT
注意如果在 pAttributes 參數中提供包含MFT_ENUM_ADAPTER_LUID屬性的 IMFAttributes,則必須設定MFT_ENUM_FLAG_HARDWARE旗標,否則會傳回E_INVALIDARG。
 
 

每個 MFT 都只屬於這些類別的其中一個。 若要列舉類別,請在 Flags 參數中設定對應的旗標。 您可以結合這些旗標來列舉多個類別。 如果未指定這些旗標,則預設類別為同步 MFT (MFT_ENUM_FLAG_SYNCMFT) 。

接下來,下列旗標包含從結果中排除的 MFT。 根據預設,符合這些準則的旗標會從結果中排除。 使用這些旗標來包含這些旗標。

旗標 描述
MFT_ENUM_FLAG_FIELDOFUSE 包含應用程式必須解除鎖定的 MFT。
MFT_ENUM_FLAG_LOCALMFT 包含透過 MFTRegisterLocalMFTRegisterLocalByCLSID 函式在呼叫端程式中註冊的 MFT。
MFT_ENUM_FLAG_TRANSCODE_ONLY 包含針對轉碼優化的 MFT,而不是播放。
 

最後一個旗標是用來排序和篩選結果:

旗標 描述
MFT_ENUM_FLAG_SORTANDFILTER 排序和篩選結果。
 

如果 已設定MFT_ENUM_FLAG_SORTANDFILTER 旗標, MFTEnum2 函式會依照下列方式排序結果:

  • 本機:如果 已設定MFT_ENUM_FLAG_LOCALMFT 旗標,本機 MFT 就會先出現在清單中。 若要註冊本機 MFT,請呼叫 MFTRegisterLocalMFTRegisterLocalByCLSID 函式。
  • 優點:具有優點值的 MFT 會出現在清單中,以最高至最低) (價值的順序。 如需優點的詳細資訊,請參閱 MFT_CODEC_MERIT_Attribute
  • 慣用:如果 MFT 列在外掛程式控制件的慣用清單中,它會出現在清單中的旁邊。 如需外掛程式控件的詳細資訊,請參閱 IMFPluginControl
  • 如果 MFT 出現在封鎖清單中,則會從結果中排除它。 如需封鎖清單的詳細資訊,請參閱 IMFPluginControl::IsDisabled
  • 符合搜尋準則的任何其他 MFT 都會出現在清單結尾,未排序。
如果您未設定 MFT_ENUM_FLAG_SORTANDFILTER 旗標, MFTEnum2 函式會傳回未排序的清單。

Flags 參數設定為零相當於使用值 MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SORTANDFILTER

旗標 設定為 MFT_ENUM_FLAG_SYNCMFT 相當於呼叫 MFTEnum 函式。

如果沒有 MFT 符合搜尋準則,則除非發生其他錯誤,否則函式會傳回 S_OK。 因此,在您取消參考 pppMFTActivate 指標之前,請一律檢查 pcMFTActivate 參數中收到的計數。

注意 沒有任何方法可以只列舉本機 MFT,而沒有其他方法。 將 旗標 設定為等於 MFT_ENUM_FLAG_LOCALMFT 相當於包含 MFT_ENUM_FLAG_SYNCMFT 旗標。 不過,如果您也會藉由指定 MFT_ENUM_FLAG_SORTANDFILTER 旗標來排序結果,本機 MFT 會先出現在清單中。
 

建立 MFT

如果至少有一個 MFT 符合搜尋準則, pppMFTActivate 參數會接收 IMFActivate 指標的陣列。 每個相符的 MFT 都會傳回一個指標。 每個指標都代表 MFT 的 啟用物件 。 如需詳細資訊,請參閱 啟用物件

每個 MFT 的其他資訊會儲存為啟用物件上的屬性。 如需可能屬性的清單,請參閱 轉換屬性

若要建立 MFT 的實例,請呼叫 IMFActivate::ActivateObject

硬體編解碼器

如果下列登錄機碼設定為零,硬體編解碼器會從列舉結果中排除:

譯碼器: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Media Foundation\HardwareMFT\EnableDecoders

編碼器: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Media Foundation\HardwareMFT\EnableEncoders

視訊處理器: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Media Foundation\HardwareMFT\EnableVideoProcessors

這些金鑰適用於 OEM,不應供應用程式使用。

針對硬體編解碼器,MFTEnum2guidCategory 參數也可以指定下列其中一個核心串流 (KS) 裝置類別:

  • KSCATEGORY_DATACOMPRESSOR
  • KSCATEGORY_DATADECOMPRESSOR
硬體編解碼器也應該在 MFT_CATEGORY GUID 下註冊,因此應用程式通常應該使用這些類別,而不是 KS 裝置類別。

範例

下列範例會擷取第一個可用的 IDXGIAdapter1 ,並取得配接器 LUID,這是識別後續範例所需的配接器。

HRESULT hr = S_OK;
IDXGIFactory1 *pDxgiFactory = NULL;
IDXGIAdapter1 *pDxgiAdapter = NULL;
LUID adapterLuid;

if (FAILED(hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)&pDxgiFactory)))
{
    return hr;
}

if (FAILED(hr = pDxgiFactory->EnumAdapters1(0, &pDxgiAdapter)))
{
    return hr;
}

DXGI_ADAPTER_DESC1 AdapterDescr;
if (FAILED(hr = pDxgiAdapter->GetDesc1(&AdapterDescr)))
{
    if (pDxgiAdapter)
    {
        pDxgiAdapter->Release();
        pDxgiAdapter = NULL;
    }
    return hr;
}

adapterLuid = AdapterDescr.AdapterLuid;

下列範例會搜尋硬體視訊或音頻譯碼器。 排除異步、硬體、轉碼和使用字段譯碼器。 如果找到相符專案,程式代碼會在清單中建立第一個 MFT。 不同於 MFTEnumEx 文章中的平行範例,此範例會建立 IMFAttributes 的實例,並將 MFT_ENUM_ADAPTER_LUID 屬性設定為要求譯碼器之介面的 LUID。 在 MFTEnum2 的呼叫中,會設定必要的MFT_ENUM_FLAG_HARDWARE旗標,並提供 IMFAttributes 自變數。

HRESULT FindHWDecoder(
    const GUID& subtype,        // Subtype
    BOOL bAudio,                // TRUE for audio, FALSE for video
    LUID& adapterLuid,          // LUID of the graphics adapter for which to find the decoder
    IMFTransform **ppDecoder    // Receives a pointer to the decoder.
)
{
    HRESULT hr = S_OK;

    
    UINT32 count = 0;

    IMFActivate **ppActivate = NULL;

    CComPtr<IMFAttributes> spAttributes;
    hr = MFCreateAttributes(&spAttributes, 1);
    if (FAILED(hr = spAttributes->SetBlob(MFT_ENUM_ADAPTER_LUID, (BYTE*)&adapterLuid, sizeof(LUID))))
    {
        return hr;
    }


    MFT_REGISTER_TYPE_INFO info = { 0 };

    info.guidMajorType = bAudio ? MFMediaType_Audio : MFMediaType_Video;
    info.guidSubtype = subtype;

    hr = MFTEnum2(
        bAudio ? MFT_CATEGORY_AUDIO_DECODER : MFT_CATEGORY_VIDEO_DECODER,
        MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SORTANDFILTER,
        &info,      // Input type
        NULL,       // Output type
        spAttributes,
        &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(ppDecoder));
    }

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

    return hr;
}

下一個範例會搜尋硬體視訊或音訊編碼器。 排除異步、硬體、轉碼和使用字段編碼器。 不同於 MFTEnumEx 文章中的平行範例,此範例會建立 IMFAttributes 的實例,並將 MFT_ENUM_ADAPTER_LUID 屬性設定為要求編碼器之介面的 LUID。 在 MFTEnum2 的呼叫中,會設定必要的MFT_ENUM_FLAG_HARDWARE旗標,並提供 IMFAttributes 自變數。

HRESULT FindHWEncoder(
    const GUID& subtype,        // Subtype
    BOOL bAudio,                // TRUE for audio, FALSE for video
    LUID& adapterLuid,          // LUID of the graphics adapter for which to find the encoder
    IMFTransform **ppEncoder    // Receives a pointer to the decoder.
)
{
    HRESULT hr = S_OK;
    UINT32 count = 0;

    IMFActivate **ppActivate = NULL;

    CComPtr<IMFAttributes> spAttributes;
    hr = MFCreateAttributes(&spAttributes, 1);
    if (FAILED(hr = spAttributes->SetBlob(MFT_ENUM_ADAPTER_LUID, (BYTE*)&adapterLuid, sizeof(LUID))))
    {
        return hr;
    }

    MFT_REGISTER_TYPE_INFO info = { 0 };

    info.guidMajorType = bAudio ? MFMediaType_Audio : MFMediaType_Video;
    info.guidSubtype = subtype;

    hr = MFTEnum2(
        bAudio ? MFT_CATEGORY_AUDIO_ENCODER : MFT_CATEGORY_VIDEO_ENCODER,
        MFT_ENUM_FLAG_HARDWARE | MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SORTANDFILTER,
        NULL,       // Input type
        &info,      // Output type
        spAttributes,
        &ppActivate,
        &count
    );

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

    // Create the first encoder in the list.

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

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

    return hr;
}

下一個範例會搜尋硬體視訊譯碼器,其中包含異步、硬體或轉碼譯碼器的選項。 不同於 MFTEnumEx 文章中的平行範例,此範例會建立 IMFAttributes 的實例,並將 MFT_ENUM_ADAPTER_LUID 屬性設定為要求視訊譯碼器之介面的 LUID。 在 MFTEnum2 的呼叫中,會設定必要的MFT_ENUM_FLAG_HARDWARE旗標,並提供 IMFAttributes 自變數。

HRESULT FindHWVideoDecoder(
    const GUID& subtype,
    BOOL bAllowAsync,
    BOOL bAllowHardware,
    BOOL bAllowTranscode,
    LUID& adapterLuid,          // LUID of the graphics adapter for which to find the encoder
    IMFTransform **ppDecoder
)
{
    HRESULT hr = S_OK;
    UINT32 count = 0;

    IMFActivate **ppActivate = NULL;

    MFT_REGISTER_TYPE_INFO info = { MFMediaType_Video, subtype };

    UINT32 unFlags = MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_LOCALMFT |
        MFT_ENUM_FLAG_SORTANDFILTER;

    if (bAllowAsync)
    {
        unFlags |= MFT_ENUM_FLAG_ASYNCMFT;
    }
    if (bAllowHardware)
    {
        unFlags |= MFT_ENUM_FLAG_HARDWARE;
    }
    if (bAllowTranscode)
    {
        unFlags |= MFT_ENUM_FLAG_TRANSCODE_ONLY;
    }

    unFlags |= MFT_ENUM_FLAG_HARDWARE;

    CComPtr<IMFAttributes> spAttributes;
    hr = MFCreateAttributes(&spAttributes, 1);
    if (FAILED(hr = spAttributes->SetBlob(MFT_ENUM_ADAPTER_LUID, (BYTE*)&adapterLuid, sizeof(LUID))))
    {
        return hr;
    }

    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(ppDecoder));
    }

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

    return hr;
}

規格需求

需求
最低支援的用戶端 Windows 10 [僅限傳統型應用程式]
最低支援的伺服器 Windows Server 2016 [僅限傳統型應用程式]
目標平台 Windows
標頭 mfapi.h
程式庫 Mfplat.lib
Dll Mfplat.dll

另請參閱

使用限制的欄位

MFTRegister

媒體基礎函式

註冊和列舉 MFT