Compartilhar via


Função MFTEnum2 (mfapi.h)

Obtém uma lista de MFTs (transformações do Microsoft Media Foundation) que correspondem aos critérios de pesquisa especificados. Essa função estende a função MFTEnumEx para permitir que aplicativos externos e componentes internos descubram os MFTs de hardware que correspondem a um adaptador de vídeo específico.

Sintaxe

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

Parâmetros

[in] guidCategory

Um GUID que especifica a categoria de MFTs a enumerar. Para obter uma lista de categorias de MFT, consulte MFT_CATEGORY.

[in] Flags

O OR bit a bit de zero ou mais sinalizadores da enumeração _MFT_ENUM_FLAG .

[in] pInputType

Um ponteiro para uma estrutura MFT_REGISTER_TYPE_INFO que especifica um tipo de mídia de entrada a ser correspondido.

Este parâmetro pode ser NULL. Se FOR NULL, todos os tipos de entrada serão correspondidos.

[in] pOutputType

Um ponteiro para uma estrutura MFT_REGISTER_TYPE_INFO que especifica um tipo de mídia de saída a ser correspondido.

Este parâmetro pode ser NULL. Se FOR NULL, todos os tipos de saída serão correspondidos.

[in, optional] pAttributes

Um ponteiro para uma interface IMFAttributes que permite o acesso ao repositório de atributos padrão. Para especificar um adaptador de hardware específico para o qual os MFTs são consultados, defina o atributo MFT_ENUM_ADAPTER_LUID como o LUID do adaptador. Se você fizer isso, também deverá especificar o sinalizador de MFT_ENUM_FLAG_HARDWARE ou E_INVALIDARG será retornado.

[out] pppMFTActivate

Recebe uma matriz de ponteiros de interface IMFActivate . Cada ponteiro representa um objeto de ativação para um MFT que corresponde aos critérios de pesquisa. A função aloca a memória para a matriz. O chamador deve liberar os ponteiros e chamar a função CoTaskMemFree para liberar a memória da matriz.

[out] pnumMFTActivate

Recebe o número de elementos na matriz pppMFTActivate . Se nenhum MFTs corresponder aos critérios de pesquisa, esse parâmetro receberá o valor zero.

Retornar valor

Se o método for bem-sucedido, retornará S_OK. Se falhar, os códigos de retorno possíveis incluem, mas não se limitam a, os valores mostrados na tabela a seguir.

Código de retorno Descrição
E_INVALIDARG
Um IMFAttributes que contém o atributo MFT_ENUM_ADAPTER_LUID foi fornecido no parâmetro pAttributes e o sinalizador MFT_ENUM_FLAG_HARDWARE não foi especificado.

Comentários

O parâmetro Flags controla quais MFTs são enumerados e a ordem em que são retornados. Os sinalizadores para esse parâmetro se enquadram em vários grupos.

O primeiro conjunto de sinalizadores especifica como um MFT processa dados.

Sinalizador Descrição
MFT_ENUM_FLAG_SYNCMFT O MFT executa o processamento de dados síncronos no software. Esse é o modelo de processamento MFT original e é compatível com o Windows Vista.
MFT_ENUM_FLAG_ASYNCMFT O MFT executa o processamento de dados assíncrono no software. Esse modelo de processamento requer o Windows 7. Para obter mais informações, consulte MFTs assíncronos.
MFT_ENUM_FLAG_HARDWARE O MFT executa o processamento de dados baseado em hardware, usando o driver AVStream ou um MFT proxy baseado em GPU. Os MFTs nessa categoria sempre processam dados de forma assíncrona. Para obter mais informações, consulte MFTs de hardware.
Nota Se um IMFAttributes que contém o atributo MFT_ENUM_ADAPTER_LUID for fornecido no parâmetro pAttributes , o sinalizador MFT_ENUM_FLAG_HARDWARE deverá ser definido ou E_INVALIDARG será retornado.
 
 

Cada MFT se enquadra exatamente em uma dessas categorias. Para enumerar uma categoria, defina o sinalizador correspondente no parâmetro Flags . Você pode combinar esses sinalizadores para enumerar mais de uma categoria. Se nenhum desses sinalizadores for especificado, a categoria padrão será MFTs síncronos (MFT_ENUM_FLAG_SYNCMFT).

Em seguida, os sinalizadores a seguir incluem MFTs que, de outra forma, são excluídos dos resultados. Por padrão, os sinalizadores que correspondem a esses critérios são excluídos dos resultados. Use esses sinalizadores para incluí-los.

Sinalizador Descrição
MFT_ENUM_FLAG_FIELDOFUSE Inclua MFTs que devem ser desbloqueados pelo aplicativo.
MFT_ENUM_FLAG_LOCALMFT Inclua MFTs registrados no processo do chamador por meio da função MFTRegisterLocal ou MFTRegisterLocalByCLSID .
MFT_ENUM_FLAG_TRANSCODE_ONLY Inclua MFTs otimizados para transcodificação em vez de reprodução.
 

O último sinalizador é usado para classificar e filtrar os resultados:

Sinalizador Descrição
MFT_ENUM_FLAG_SORTANDFILTER Classifique e filtre os resultados.
 

Se o sinalizador MFT_ENUM_FLAG_SORTANDFILTER estiver definido, a função MFTEnum2 classificará os resultados da seguinte maneira:

  • Local: se o sinalizador MFT_ENUM_FLAG_LOCALMFT estiver definido, os MFTs locais aparecerão primeiro na lista. Para registrar um MFT local, chame a função MFTRegisterLocal ou MFTRegisterLocalByCLSID .
  • Mérito: MFTs com um valor de mérito aparecem em seguida na lista, em ordem de valor de mérito (mais alto para menor). Para obter mais informações sobre mérito, consulte MFT_CODEC_MERIT_Attribute.
  • Preferencial: se um MFT estiver listado na lista preferencial do controle de plug-in, ele aparecerá em seguida na lista. Para obter mais informações sobre o controle de plug-in, consulte IMFPluginControl.
  • Se um MFT aparecer na lista bloqueada, ele será excluído dos resultados. Para obter mais informações sobre a lista bloqueada, consulte IMFPluginControl::IsDisabled.
  • Quaisquer outros MFTs que correspondam aos critérios de pesquisa aparecem no final da lista, não classificados.
Se você não definir o sinalizador MFT_ENUM_FLAG_SORTANDFILTER , a função MFTEnum2 retornará uma lista não classificada.

Definir o parâmetro Flags como zero é equivalente a usar o valor MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SORTANDFILTER.

Definir Sinalizadorescomo MFT_ENUM_FLAG_SYNCMFT é equivalente a chamar a função MFTEnum .

Se nenhum MFTs corresponder aos critérios de pesquisa, a função retornará S_OK, a menos que ocorra algum outro erro. Portanto, sempre marcar a contagem recebida no parâmetro pcMFTActivate antes de desreferenciar o ponteiro pppMFTActivate.

Nota Não há como enumerar apenas MFTs locais e nada mais. Definir Sinalizadores iguais a MFT_ENUM_FLAG_LOCALMFT é equivalente a incluir o sinalizador MFT_ENUM_FLAG_SYNCMFT . No entanto, se você também classificar os resultados especificando o sinalizador MFT_ENUM_FLAG_SORTANDFILTER , os MFTs locais aparecerão primeiro na lista.
 

Criando o MFT

Se pelo menos um MFT corresponder aos critérios de pesquisa, o parâmetro pppMFTActivate receberá uma matriz de ponteiros IMFActivate . Um ponteiro é retornado para cada MFT correspondente. Cada ponteiro representa um objeto de ativação para o MFT. Para obter mais informações, consulte Objetos de ativação.

Informações adicionais sobre cada MFT são armazenadas como atributos nos objetos de ativação. Para obter uma lista dos atributos possíveis, consulte Transformar atributos.

Para criar uma instância do MFT, chame IMFActivate::ActivateObject.

Hardware Codecs

Os codecs de hardware serão excluídos dos resultados da enumeração se as seguintes chaves do Registro estiverem definidas como zero:

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

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

Processadores de vídeo: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Media Foundation\HardwareMFT\EnableVideoProcessors

Essas chaves são destinadas a OEMs e não devem ser usadas por aplicativos.

Para codecs de hardware, o parâmetro guidCategory de MFTEnum2 também pode especificar uma das seguintes categorias de dispositivo de streaming de kernel (KS):

  • KSCATEGORY_DATACOMPRESSOR
  • KSCATEGORY_DATADECOMPRESSOR
Codecs de hardware também devem ser registrados em um GUID MFT_CATEGORY , portanto, os aplicativos geralmente devem usar essas categorias em vez das categorias de dispositivo KS.

Exemplos

O exemplo a seguir recupera o primeiro IDXGIAdapter1 disponível e obtém o LUID dos adaptadores, que é necessário para identificar o adaptador para os exemplos subsequentes.

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;

O exemplo a seguir pesquisa um decodificador de áudio ou vídeo de hardware. Os decodificadores assíncronos, de hardware, transcodificados e de campo de uso são excluídos. Se uma correspondência for encontrada, o código criará o primeiro MFT na lista. Ao contrário do exemplo paralelo no artigo MFTEnumEx , este exemplo cria uma instância de IMFAttributes e define o atributo MFT_ENUM_ADAPTER_LUID como o LUID da interface da qual o decodificador é solicitado. Na chamada para MFTEnum2, o sinalizador de MFT_ENUM_FLAG_HARDWARE necessário é definido e o argumento IMFAttributes é fornecido.

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

O próximo exemplo pesquisa um codificador de áudio ou vídeo de hardware. Codificadores assíncronos, de hardware, de transcódigo e de campo de uso são excluídos. Ao contrário do exemplo paralelo no artigo MFTEnumEx , este exemplo cria uma instância de IMFAttributes e define o atributo MFT_ENUM_ADAPTER_LUID como o LUID da interface da qual o codificador é solicitado. Na chamada para MFTEnum2, o sinalizador de MFT_ENUM_FLAG_HARDWARE necessário é definido e o argumento IMFAttributes é fornecido.

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

O próximo exemplo pesquisa um decodificador de vídeo de hardware, com opções para incluir decodificadores assíncronos, de hardware ou transcodificadores. Ao contrário do exemplo paralelo no artigo MFTEnumEx , este exemplo cria uma instância de IMFAttributes e define o atributo MFT_ENUM_ADAPTER_LUID como o LUID da interface da qual o decodificador de vídeo é solicitado. Na chamada para MFTEnum2, o sinalizador de MFT_ENUM_FLAG_HARDWARE necessário é definido e o argumento IMFAttributes é fornecido.

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

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows 10 [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows Server 2016 [somente aplicativos da área de trabalho]
Plataforma de Destino Windows
Cabeçalho mfapi.h
Biblioteca Mfplat.lib
DLL Mfplat.dll

Confira também

Restrições de campo de uso

MFTRegister

Funções do Media Foundation

Registrando e enumerando MFTs