MFTEnum2 함수(mfapi.h)

지정된 검색 조건과 일치하는 MFT(Microsoft Media Foundation 변환) 목록을 가져옵니다. 이 함수는 외부 애플리케이션 및 내부 구성 요소가 특정 비디오 어댑터에 해당하는 하드웨어 MFT를 검색할 수 있도록 MFTEnumEx 함수를 확장합니다.

구문

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

열거할 MFT의 범주를 지정하는 GUID입니다. MFT 범주 목록은 MFT_CATEGORY 참조하세요.

[in] Flags

_MFT_ENUM_FLAG 열거형에서 0개 이상의 플래그가 있는 비트 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가 없으면 이 매개 변수는 값 0을 받습니다.

반환 값

메서드가 성공하면 S_OK가 반환되고, 실패할 경우 가능한 반환 코드는 다음 표에 표시된 값을 포함하지만 이에 국한되지 않습니다.

반환 코드 설명
E_INVALIDARG
MFT_ENUM_ADAPTER_LUID 특성을 포함하는 IMFAttributespAttributes 매개 변수에 제공되었으며 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 기반 프록시 MFT를 사용하여 하드웨어 기반 데이터 처리를 수행합니다. 이 범주의 MFT는 항상 데이터를 비동기적으로 처리합니다. 자세한 내용은 하드웨어 MFT를 참조하세요.
참고 MFT_ENUM_ADAPTER_LUID 특성을 포함하는 IMFAttributespAttributes 매개 변수에 제공된 경우 MFT_ENUM_FLAG_HARDWARE 플래그를 설정하거나 E_INVALIDARG 반환됩니다.
 
 

모든 MFT는 정확히 이러한 범주 중 하나에 속합니다. 범주를 열거하려면 Flags 매개 변수에서 해당 플래그를 설정합니다. 이러한 플래그를 결합하여 둘 이상의 범주를 열거할 수 있습니다. 이러한 플래그를 지정하지 않으면 기본 범주는 동기 MFT(MFT_ENUM_FLAG_SYNCMFT)입니다.

다음으로, 다음 플래그에는 결과에서 제외되는 MFT가 포함됩니다. 기본적으로 이러한 조건과 일치하는 플래그는 결과에서 제외됩니다. 이러한 플래그를 사용하여 플래그를 포함합니다.

플래그 설명
MFT_ENUM_FLAG_FIELDOFUSE 애플리케이션에서 잠금 해제해야 하는 MFT를 포함합니다.
MFT_ENUM_FLAG_LOCALMFT MFTRegisterLocal 또는 MFTRegisterLocalByCLSID 함수를 통해 호출자의 프로세스에 등록된 MFT를 포함합니다.
MFT_ENUM_FLAG_TRANSCODE_ONLY 재생보다는 코드 변환에 최적화된 MFT를 포함합니다.
 

마지막 플래그는 결과를 정렬하고 필터링하는 데 사용됩니다.

플래그 설명
MFT_ENUM_FLAG_SORTANDFILTER 결과를 정렬하고 필터링합니다.
 

MFT_ENUM_FLAG_SORTANDFILTER 플래그가 설정된 경우 MFTEnum2 함수는 다음과 같이 결과를 정렬합니다.

  • 로컬: MFT_ENUM_FLAG_LOCALMFT 플래그가 설정된 경우 로컬 MFT가 목록에 먼저 표시됩니다. 로컬 MFT를 등록하려면 MFTRegisterLocal 또는 MFTRegisterLocalByCLSID 함수를 호출합니다.
  • 장점: 장점 값이 있는 MFT는 장점 값(가장 높음에서 가장 낮은 값)의 순서로 목록 옆에 표시됩니다. 장점에 대한 자세한 내용은 MFT_CODEC_MERIT_Attribute 참조하세요.
  • 기본 설정: MFT가 플러그 인 컨트롤의 기본 설정 목록에 나열되면 목록의 다음으로 표시됩니다. 플러그 인 제어에 대한 자세한 내용은 IMFPluginControl을 참조하세요.
  • MFT가 차단된 목록에 표시되면 결과에서 제외됩니다. 차단된 목록에 대한 자세한 내용은 IMFPluginControl::IsDisabled를 참조하세요.
  • 검색 조건과 일치하는 다른 모든 MFT는 목록의 끝에 정렬되지 않은 상태로 표시됩니다.
MFT_ENUM_FLAG_SORTANDFILTER 플래그를 설정하지 않으면 MFTEnum2 함수는 정렬되지 않은 목록을 반환합니다.

Flags 매개 변수를 0으로 설정하는 것은 값 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의 instance 만들려면 IMFActivate::ActivateObject를 호출합니다.

하드웨어 코덱

다음 레지스트리 키가 0으로 설정된 경우 하드웨어 코덱은 열거형 결과에서 제외됩니다.

디코더: 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의 instance 만들고 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의 instance 만들고 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의 instance 만들고 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 등록 및 열거