Search code examples
c++winapivideoh.264ms-media-foundation

Obtaining decoder MFT for H.264 video


i am trying to get a hardware decoder from media foundation. i know for sure my gpu supports nvdec hardware decoding. i found an example on github which gets the encoder, nvenc without any problem. but when i switch the params to decoder, i either get a bad hresult or a crash. i tried even getting a software decoder by changing the hardware flag, and still bad hresult. any one have an idea what is wrong? i cant think of anything else left for me to try or change

HRESULT get_decoder(CComPtr<IMFTransform>& out_transform, CComPtr<IMFActivate>& out_activate,
    CComPtr<IMFAttributes>& out_attributes)
{
    HRESULT hr = S_OK;

    // Find the decoder
    CComHeapPtr<IMFActivate*> activate_raw;
    uint32_t activateCount = 0;

    // Input & output types
    const MFT_REGISTER_TYPE_INFO in_info = { MFMediaType_Video, MFVideoFormat_H264 };
    const MFT_REGISTER_TYPE_INFO out_info = { MFMediaType_Video, MFVideoFormat_NV12 };

    // Get decoders matching the specified attributes
    if (FAILED(hr = MFTEnum2(MFT_CATEGORY_VIDEO_DECODER, MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_SORTANDFILTER, &in_info, &out_info,
        nullptr, &activate_raw, &activateCount)))
        return hr;

    // Choose the first returned decoder
    out_activate = activate_raw[0];

    // Memory management
    for (int i = 1; i < activateCount; i++)
        activate_raw[i]->Release();

    // Activate
    if (FAILED(hr = out_activate->ActivateObject(IID_PPV_ARGS(&out_transform))))
        return hr;

    // Get attributes
    if (FAILED(hr = out_transform->GetAttributes(&out_attributes)))
        return hr;

    std::cout << "- get_decoder() Found " << activateCount << " decoders" << std::endl;

    return hr;
}

Solution

  • There might be no dedicated decoder MFT for hardware decoding (even though some vendors supply those). Hardware video decoding, in contrast to encoding, is available via DXVA 2 API, and - in turn - is covered by Microsoft H264 Video Decoder MFT.

    This stock MFT is capable to decode using hardware and is also compatible with D3D9 and D3D11 enabled pipelines.

    Microsoft H264 Video Decoder MFT

    6 Attributes:

    • MFT_TRANSFORM_CLSID_Attribute: {62CE7E72-4C71-4D20-B15D-452831A87D9D} (Type VT_CLSID, CLSID_CMSH264DecoderMFT)
    • MF_TRANSFORM_FLAGS_Attribute: MFT_ENUM_FLAG_SYNCMFT
    • MFT_INPUT_TYPES_Attributes: MFVideoFormat_H264, MFVideoFormat_H264_ES
    • MFT_OUTPUT_TYPES_Attributes: MFVideoFormat_NV12, MFVideoFormat_YV12, MFVideoFormat_IYUV, MFVideoFormat_I420, MFVideoFormat_YUY2

    Attributes

    • MF_SA_D3D_AWARE: 1 (Type VT_UI4)
    • MF_SA_D3D11_AWARE: 1 (Type VT_UI4)
    • CODECAPI_AVDecVideoThumbnailGenerationMode: 0 (Type VT_UI4)
    • CODECAPI_AVDecVideoMaxCodedWidth: 7680 (Type VT_UI4)
    • CODECAPI_AVDecVideoMaxCodedHeight: 4320 (Type VT_UI4)
    • CODECAPI_AVDecNumWorkerThreads: 4294967295 (Type VT_UI4, -1)
    • CODECAPI_AVDecVideoAcceleration_H264: 1 (Type VT_UI4) ...

    From MSDN:

    CODECAPI_AVDecVideoAcceleration_H264 Enables or disables hardware acceleration.

    ...

    Maximum Resolution 4096 × 2304 pixels The maximum guaranteed resolution for DXVA acceleration is 1920 × 1088 pixels; at higher resolutions, decoding is done with DXVA, if it is supported by the underlying hardware, otherwise, decoding is done with software.

    ...

    DXVA The decoder supports DXVA version 2, but not DXVA version 1. DXVA decoding is supported only for Main-compatible Baseline, Main, and High profile bitstreams. (Main-compatible Baseline bitstreams are defined as profile_idc=66 and constrained_set1_flag=1.)

    To decode with hardware acceleration just use Microsoft H264 Video Decoder MFT.