Funzione MFTEnum2 (mfapi.h)

Ottiene un elenco di trasformazioni di Microsoft Media Foundation che corrispondono ai criteri di ricerca specificati. Questa funzione estende la funzione MFTEnumEx per consentire alle applicazioni esterne e ai componenti interni di individuare i MFT hardware che corrispondono a una scheda video specifica.

Sintassi

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
);

Parametri

[in] guidCategory

GUID che specifica la categoria di MFP da enumerare. Per un elenco delle categorie MFT, vedere MFT_CATEGORY.

[in] Flags

OR bit per bit di zero o più flag dall'enumerazione _MFT_ENUM_FLAG .

[in] pInputType

Puntatore a una struttura MFT_REGISTER_TYPE_INFO che specifica un tipo di supporto di input da associare.

Questo parametro può essere NULL. Se NULL, vengono confrontati tutti i tipi di input.

[in] pOutputType

Puntatore a una struttura MFT_REGISTER_TYPE_INFO che specifica un tipo di supporto di output da associare.

Questo parametro può essere NULL. Se NULL, vengono confrontati tutti i tipi di output.

[in, optional] pAttributes

Puntatore a un'interfaccia IMFAttributes che consente l'accesso all'archivio attributi standard. Per specificare un adattatore hardware specifico per cui vengono eseguite query sulle MFP, impostare l'attributo MFT_ENUM_ADAPTER_LUID sul LUID dell'adattatore. In questo caso, è necessario specificare anche il flag MFT_ENUM_FLAG_HARDWARE o E_INVALIDARG restituito.

[out] pppMFTActivate

Riceve una matrice di puntatori di interfaccia IMFActivate . Ogni puntatore rappresenta un oggetto attivazione per un MFT che corrisponde ai criteri di ricerca. La funzione alloca la memoria per la matrice. Il chiamante deve rilasciare i puntatori e chiamare la funzione CoTaskMemFree per liberare la memoria per la matrice.

[out] pnumMFTActivate

Riceve il numero di elementi nella matrice pppMFTActivate . Se nessun MFP corrisponde ai criteri di ricerca, questo parametro riceve il valore zero.

Valore restituito

Se il metodo ha esito positivo, viene restituito S_OK. Se ha esito negativo, i possibili codici restituiti includono, ma non sono limitati, i valori illustrati nella tabella seguente.

Codice restituito Descrizione
E_INVALIDARG
Un IMFAttributes contenente l'attributo MFT_ENUM_ADAPTER_LUID è stato fornito nel parametro pAttributes e il flag MFT_ENUM_FLAG_HARDWARE non è stato specificato.

Commenti

Il parametro Flags controlla quali MFP vengono enumerati e l'ordine in cui vengono restituiti. I flag per questo parametro rientrano in diversi gruppi.

Il primo set di flag specifica il modo in cui un MFT elabora i dati.

Flag Descrizione
MFT_ENUM_FLAG_SYNCMFT MFT esegue l'elaborazione dei dati sincrona nel software. Si tratta del modello di elaborazione MFT originale ed è compatibile con Windows Vista.
MFT_ENUM_FLAG_ASYNCMFT MFT esegue l'elaborazione asincrona dei dati nel software. Questo modello di elaborazione richiede Windows 7. Per altre informazioni, vedere Mft asincroni.
MFT_ENUM_FLAG_HARDWARE MFT esegue l'elaborazione dati basata su hardware, usando il driver AVStream o un proxy basato su GPU MFT. Le MFP in questa categoria elaborano sempre i dati in modo asincrono. Per altre informazioni, vedere Hardware MFT.
Nota Se un IMFAttributes contenente l'attributo MFT_ENUM_ADAPTER_LUID viene fornito nel parametro pAttributes , il flag MFT_ENUM_FLAG_HARDWARE deve essere impostato o E_INVALIDARG verrà restituito.
 
 

Ogni MFT rientra esattamente in una di queste categorie. Per enumerare una categoria, impostare il flag corrispondente nel parametro Flags . È possibile combinare questi flag per enumerare più di una categoria. Se nessuno di questi flag viene specificato, la categoria predefinita è mft sincrona (MFT_ENUM_FLAG_SYNCMFT).

I flag seguenti includono quindi I MFC che altrimenti vengono esclusi dai risultati. Per impostazione predefinita, i flag che corrispondono a questi criteri vengono esclusi dai risultati. Usare questi flag per includerli.

Flag Descrizione
MFT_ENUM_FLAG_FIELDOFUSE Includere le MFP che devono essere sbloccate dall'applicazione.
MFT_ENUM_FLAG_LOCALMFT Includere I MFT registrati nel processo del chiamante tramite la funzione MFTRegisterLocal o MFTRegisterLocalByCLSID .
MFT_ENUM_FLAG_TRANSCODE_ONLY Includere le MFP ottimizzate per la transcodifica anziché per la riproduzione.
 

L'ultimo flag viene usato per ordinare e filtrare i risultati:

Flag Descrizione
MFT_ENUM_FLAG_SORTANDFILTER Ordinare e filtrare i risultati.
 

Se il flag MFT_ENUM_FLAG_SORTANDFILTER è impostato, la funzione MFTEnum2 ordina i risultati nel modo seguente:

  • Locale: se il flag MFT_ENUM_FLAG_LOCALMFT è impostato, le MFP locali vengono visualizzate per prime nell'elenco. Per registrare un MFT locale, chiamare la funzione MFTRegisterLocal o MFTRegisterLocalByCLSID .
  • Merito: le MFP con un valore di merito vengono visualizzate accanto nell'elenco, in ordine di valore di merito (più alto al più basso). Per altre informazioni sul merito, vedere MFT_CODEC_MERIT_Attribute.
  • Preferito: se un MFT è elencato nell'elenco preferito del controllo plug-in, viene visualizzato accanto nell'elenco. Per altre informazioni sul controllo plug-in, vedere IMFPluginControl.
  • Se un MFT viene visualizzato nell'elenco bloccato, viene escluso dai risultati. Per altre informazioni sull'elenco bloccato, vedere IMFPluginControl::IsDisabled.
  • Tutti gli altri MFP che corrispondono ai criteri di ricerca vengono visualizzati alla fine dell'elenco, non ordinato.
Se non si imposta il flag MFT_ENUM_FLAG_SORTANDFILTER , la funzione MFTEnum2 restituisce un elenco non ordinato.

L'impostazione del parametro Flags su zero equivale all'uso del valore MFT_ENUM_FLAG_SYNCMFT MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SORTANDFILTER | .

L'impostazione di Flag suMFT_ENUM_FLAG_SYNCMFT equivale a chiamare la funzione MFTEnum .

Se nessun MFP corrisponde ai criteri di ricerca, la funzione restituisce S_OK, a meno che non si verifichi un altro errore. Controllare quindi sempre il conteggio ricevuto nel parametro pcMFTActivate prima di dereferenziare il puntatore ppMFTActivate .

Nota Non c'è modo di enumerare solo le MFP locali e nient'altro. L'impostazione di Flag uguali a MFT_ENUM_FLAG_LOCALMFT equivale all'inclusione del flag MFT_ENUM_FLAG_SYNCMFT . Tuttavia, se si ordinano anche i risultati specificando il flag MFT_ENUM_FLAG_SORTANDFILTER , le MFP locali vengono visualizzate per prime nell'elenco.
 

Creazione del MFT

Se almeno un MFT corrisponde ai criteri di ricerca, il parametro pppMFTActivate riceve una matrice di puntatori IMFActivate . Viene restituito un puntatore per ogni MFT corrispondente. Ogni puntatore rappresenta un oggetto di attivazione per MFT. Per altre informazioni, vedere Oggetti attivazione.

Informazioni aggiuntive su ogni MFT vengono archiviate come attributi negli oggetti di attivazione. Per un elenco degli attributi possibili, vedere Attributi di trasformazione.

Per creare un'istanza di MFT, chiamare IMFActivate::ActivateObject.

Codec hardware

I codec hardware vengono esclusi dai risultati dell'enumerazione se le chiavi del Registro di sistema seguenti sono impostate su zero:

Decodificatori: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Media Foundation\HardwareMFT\EnableDecoders

Codificatori: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Media Foundation\HardwareMFT\EnableEncoders

Processori video: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Media Foundation\HardwareMFT\EnableVideoProcessors

Queste chiavi sono destinate agli OEM e non devono essere usate dalle applicazioni.

Per i codec hardware, il parametro guidCategory di MFTEnum2 può anche specificare una delle categorie di dispositivi KS (Kernel Streaming) seguenti:

  • KSCATEGORY_DATACOMPRESSOR
  • KSCATEGORY_DATADECOMPRESSOR
I codec hardware devono essere registrati anche in un GUID MFT_CATEGORY , quindi le applicazioni devono in genere usare tali categorie anziché le categorie di dispositivi KS.

Esempio

L'esempio seguente recupera il primo IDXGIAdapter1 disponibile e ottiene gli adattatori LUID, necessari per identificare l'adattatore per gli esempi successivi.

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;

Nell'esempio seguente viene eseguita la ricerca di un decodificatore audio o video hardware. I decodificatori asincroni, hardware, transcodificali e field-of-use vengono esclusi. Se viene trovata una corrispondenza, il codice crea il primo MFT nell'elenco. A differenza dell'esempio parallelo nell'articolo MFTEnumEx , questo esempio crea un'istanza di IMFAttributes e imposta l'attributo MFT_ENUM_ADAPTER_LUID sul LUID dell'interfaccia da cui viene richiesto il decodificatore. Nella chiamata a MFTEnum2 viene impostato il flag di MFT_ENUM_FLAG_HARDWARE richiesto e viene fornito l'argomento 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;
}

Nell'esempio seguente viene eseguita la ricerca di un codificatore video o audio hardware. I codificatori asincroni, hardware, transcodificali e field-of-use vengono esclusi. A differenza dell'esempio parallelo nell'articolo MFTEnumEx , questo esempio crea un'istanza di IMFAttributes e imposta l'attributo MFT_ENUM_ADAPTER_LUID sul LUID dell'interfaccia da cui viene richiesto il codificatore. Nella chiamata a MFTEnum2 viene impostato il flag di MFT_ENUM_FLAG_HARDWARE richiesto e viene fornito l'argomento 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;
}

L'esempio seguente cerca un decodificatore video hardware, con opzioni per includere decodificatori asincroni, hardware o transcodificati. A differenza dell'esempio parallelo nell'articolo MFTEnumEx , questo esempio crea un'istanza di IMFAttributes e imposta l'attributo MFT_ENUM_ADAPTER_LUID sul LUID dell'interfaccia da cui viene richiesto il decodificatore video. Nella chiamata a MFTEnum2 viene impostato il flag di MFT_ENUM_FLAG_HARDWARE richiesto e viene fornito l'argomento 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;
}

Requisiti

Requisito Valore
Client minimo supportato Windows 10 [solo app desktop]
Server minimo supportato Windows Server 2016 [solo app desktop]
Piattaforma di destinazione Windows
Intestazione mfapi.h
Libreria Mfplat.lib
DLL Mfplat.dll

Vedi anche

Campo delle restrizioni per l'utilizzo

MFTRegister

Funzioni di Media Foundation

Registrazione ed enumerazione di mft