Función MFTEnum2 (mfapi.h)

Obtiene una lista de transformaciones (MFT) de Microsoft Media Foundation que coinciden con los criterios de búsqueda especificados. Esta función amplía la función MFTEnumEx para permitir que las aplicaciones externas y los componentes internos detecten las MFT de hardware que corresponden a un adaptador de vídeo específico.

Sintaxis

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

GUID que especifica la categoría de MFP que se van a enumerar. Para obtener una lista de las categorías de MFT, consulte MFT_CATEGORY.

[in] Flags

Or bit a bit de cero o más marcas de la enumeración _MFT_ENUM_FLAG.

[in] pInputType

Puntero a una estructura MFT_REGISTER_TYPE_INFO que especifica un tipo de medio de entrada que debe coincidir.

Este parámetro puede ser NULL. Si es NULL, se buscarán coincidencias con todos los tipos de entrada.

[in] pOutputType

Puntero a una estructura de MFT_REGISTER_TYPE_INFO que especifica un tipo de medio de salida que debe coincidir.

Este parámetro puede ser NULL. Si es NULL, se buscarán coincidencias con todos los tipos de salida.

[in, optional] pAttributes

Puntero a una interfaz IMFAttributes que permite el acceso al almacén de atributos estándar. Para especificar un adaptador de hardware específico para el que se consultan las MFP, establezca el atributo MFT_ENUM_ADAPTER_LUID en el LUID del adaptador. Si lo hace, también debe especificar la marca MFT_ENUM_FLAG_HARDWARE o E_INVALIDARG se devuelve.

[out] pppMFTActivate

Recibe una matriz de punteros de interfaz IMFActivate . Cada puntero representa un objeto de activación para un MFT que coincide con los criterios de búsqueda. La función asigna la memoria de la matriz. El autor de la llamada debe liberar los punteros y llamar a la función CoTaskMemFree para liberar la memoria de la matriz.

[out] pnumMFTActivate

Recibe el número de elementos de la matriz pppMFTActivate . Si no hay MFP que coincidan con los criterios de búsqueda, este parámetro recibe el valor cero.

Valor devuelto

Si el método se realiza correctamente, devuelve S_OK. Si se produce un error, los códigos de retorno posibles incluyen, entre otros, los valores que se muestran en la tabla siguiente.

Código devuelto Descripción
E_INVALIDARG
Se proporcionó un atributo IMFAttributes que contiene el atributo MFT_ENUM_ADAPTER_LUID en el parámetro pAttributes y no se especificó la marca MFT_ENUM_FLAG_HARDWARE.

Comentarios

El parámetro Flags controla qué MFP se enumeran y el orden en que se devuelven. Las marcas de este parámetro se dividen en varios grupos.

El primer conjunto de marcas especifica cómo procesa un MFT los datos.

Marca Descripción
MFT_ENUM_FLAG_SYNCMFT MFT realiza el procesamiento de datos sincrónicos en el software. Este es el modelo de procesamiento MFT original y es compatible con Windows Vista.
MFT_ENUM_FLAG_ASYNCMFT MFT realiza el procesamiento asincrónico de datos en software. Este modelo de procesamiento requiere Windows 7. Para obtener más información, vea MFT asincrónicas.
MFT_ENUM_FLAG_HARDWARE MFT realiza el procesamiento de datos basado en hardware, mediante el controlador AVStream o un proxy basado en GPU MFT. Las MFT de esta categoría siempre procesan los datos de forma asincrónica. Para obtener más información, consulte MFP de hardware.
Nota Si se proporciona un atributo IMFAttributes que contiene el atributo MFT_ENUM_ADAPTER_LUID en el parámetro pAttributes , se debe establecer o E_INVALIDARG marca MFT_ENUM_FLAG_HARDWARE.
 
 

Cada MFT entra exactamente en una de estas categorías. Para enumerar una categoría, establezca la marca correspondiente en el parámetro Flags . Puede combinar estas marcas para enumerar más de una categoría. Si no se especifica ninguna de estas marcas, la categoría predeterminada es mfts sincrónicas (MFT_ENUM_FLAG_SYNCMFT).

A continuación, las marcas siguientes incluyen MFP que, de lo contrario, se excluyen de los resultados. De forma predeterminada, las marcas que coinciden con estos criterios se excluyen de los resultados. Use cualquiera de estas marcas para incluirlas.

Marca Descripción
MFT_ENUM_FLAG_FIELDOFUSE Incluya las MFP que la aplicación debe desbloquear.
MFT_ENUM_FLAG_LOCALMFT Incluya las MFP registradas en el proceso del autor de la llamada a través de la función MFTRegisterLocal o MFTRegisterLocalByCLSID .
MFT_ENUM_FLAG_TRANSCODE_ONLY Incluya MFP optimizados para la transcodificación en lugar de la reproducción.
 

La última marca se usa para ordenar y filtrar los resultados:

Marca Descripción
MFT_ENUM_FLAG_SORTANDFILTER Ordene y filtre los resultados.
 

Si se establece la marca MFT_ENUM_FLAG_SORTANDFILTER , la función MFTEnum2 ordena los resultados de la siguiente manera:

  • Local: si se establece la marca MFT_ENUM_FLAG_LOCALMFT , las MFP locales aparecen primero en la lista. Para registrar un MFT local, llame a la función MFTRegisterLocal o MFTRegisterLocalByCLSID .
  • Mérito: Las MFT con un valor de mérito aparecen a continuación en la lista, en orden de valor de mérito (más alto a más bajo). Para obtener más información sobre el mérito, consulte MFT_CODEC_MERIT_Attribute.
  • Preferido: si se muestra un MFT en la lista preferida del control de complemento, aparece a continuación en la lista. Para obtener más información sobre el control del complemento, vea IMFPluginControl.
  • Si aparece un MFT en la lista de bloqueados, se excluye de los resultados. Para obtener más información sobre la lista bloqueada, vea IMFPluginControl::IsDisabled.
  • Cualquier otra MFT que coincida con los criterios de búsqueda aparece al final de la lista, sin clasificar.
Si no establece la marca MFT_ENUM_FLAG_SORTANDFILTER , la función MFTEnum2 devuelve una lista no ordenada.

Establecer el parámetro Flags en cero equivale a usar el valor MFT_ENUM_FLAG_SYNCMFT MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SORTANDFILTER | .

Establecer marcasen MFT_ENUM_FLAG_SYNCMFT equivale a llamar a la función MFTEnum .

Si no hay MFP que coincidan con los criterios de búsqueda, la función devuelve S_OK, a menos que se produzca algún otro error. Por lo tanto, compruebe siempre el recuento recibido en el parámetro pcMFTActivate antes de desreferenciar el puntero pppMFTActivate .

Nota No hay ninguna manera de enumerar solo las MFP locales y nada más. Establecer marcas iguales a MFT_ENUM_FLAG_LOCALMFT equivale a incluir la marca MFT_ENUM_FLAG_SYNCMFT . Sin embargo, si también ordena los resultados especificando la marca MFT_ENUM_FLAG_SORTANDFILTER , las MFP locales aparecen primero en la lista.
 

Creación del MFT

Si al menos un MFT coincide con los criterios de búsqueda, el parámetro pppMFTActivate recibe una matriz de punteros IMFActivate . Se devuelve un puntero para cada MFT coincidente. Cada puntero representa un objeto de activación para el MFT. Para obtener más información, vea Objetos de activación.

La información adicional sobre cada MFT se almacena como atributos en los objetos de activación. Para obtener una lista de los posibles atributos, vea Transformar atributos.

Para crear una instancia de MFT, llame a IMFActivate::ActivateObject.

Códecs de hardware

Los códecs de hardware se excluyen de los resultados de la enumeración si las siguientes claves del Registro se establecen en cero:

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

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

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

Estas claves están pensadas para oem y no deben usarse en las aplicaciones.

En el caso de los códecs de hardware, el parámetro guidCategory de MFTEnum2 también puede especificar una de las siguientes categorías de dispositivos de streaming de kernel (KS):

  • KSCATEGORY_DATACOMPRESSOR
  • KSCATEGORY_DATADECOMPRESSOR
Los códecs de hardware también deben registrarse en un GUID de MFT_CATEGORY , por lo que las aplicaciones normalmente deben usar esas categorías en lugar de las categorías de dispositivos KS.

Ejemplos

En el ejemplo siguiente se recupera el primer IDXGIAdapter1 disponible y se obtiene el LUID de adaptadores, que es necesario para identificar el adaptador para los ejemplos posteriores.

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;

En el ejemplo siguiente se busca un descodificador de audio o vídeo de hardware. Se excluyen los descodificadores asincrónicos, de hardware, transcodificación y campo de uso. Si se encuentra una coincidencia, el código crea el primer MFT en la lista. A diferencia del ejemplo paralelo del artículo MFTEnumEx , en este ejemplo se crea una instancia de IMFAttributes y se establece el atributo MFT_ENUM_ADAPTER_LUID en el LUID de la interfaz desde la que se solicita el descodificador. En la llamada a MFTEnum2, se establece la marca MFT_ENUM_FLAG_HARDWARE necesaria y se proporciona el argumento 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;
}

En el ejemplo siguiente se busca un codificador de audio o vídeo de hardware. Se excluyen los codificadores asincrónicos, hardware, transcodificación y campo de uso. A diferencia del ejemplo paralelo del artículo MFTEnumEx , en este ejemplo se crea una instancia de IMFAttributes y se establece el atributo MFT_ENUM_ADAPTER_LUID en el LUID de la interfaz desde la que se solicita el codificador. En la llamada a MFTEnum2, se establece la marca MFT_ENUM_FLAG_HARDWARE necesaria y se proporciona el argumento 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;
}

En el ejemplo siguiente se busca un descodificador de vídeo de hardware, con opciones para incluir descodificadores asincrónicos, de hardware o transcodificadores. A diferencia del ejemplo paralelo del artículo MFTEnumEx , en este ejemplo se crea una instancia de IMFAttributes y se establece el atributo MFT_ENUM_ADAPTER_LUID en el LUID de la interfaz desde la que se solicita el descodificador de vídeo. En la llamada a MFTEnum2, se establece la marca MFT_ENUM_FLAG_HARDWARE necesaria y se proporciona el argumento 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;
}

Requisitos

Requisito Value
Cliente mínimo compatible Windows 10 [solo aplicaciones de escritorio]
Servidor mínimo compatible Windows Server 2016 [solo aplicaciones de escritorio]
Plataforma de destino Windows
Encabezado mfapi.h
Library Mfplat.lib
Archivo DLL Mfplat.dll

Consulte también

Restricciones de campo de uso

MFTRegister

Funciones de Media Foundation

Registro y enumeración de MFP