/*
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#define COBJMACROS
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0602
#endif

#include "mf_utils.h"
#include "libavutil/pixdesc.h"

HRESULT ff_MFGetAttributeSize(IMFAttributes *pattr, REFGUID guid,
                              UINT32 *pw, UINT32 *ph)
{
    UINT64 t;
    HRESULT hr = IMFAttributes_GetUINT64(pattr, guid, &t);
    if (!FAILED(hr)) {
        *pw = t >> 32;
        *ph = (UINT32)t;
    }
    return hr;
}

HRESULT ff_MFSetAttributeSize(IMFAttributes *pattr, REFGUID guid,
                              UINT32 uw, UINT32 uh)
{
    UINT64 t = (((UINT64)uw) << 32) | uh;
    return IMFAttributes_SetUINT64(pattr, guid, t);
}

#define ff_MFSetAttributeRatio ff_MFSetAttributeSize
#define ff_MFGetAttributeRatio ff_MFGetAttributeSize

// MFTEnumEx was missing from mingw-w64's mfplat import library until
// mingw-w64 v6.0.0, thus wrap it and load it using GetProcAddress.
// It's also missing in Windows Vista's mfplat.dll.
HRESULT ff_MFTEnumEx(GUID guidCategory, UINT32 Flags,
                     const MFT_REGISTER_TYPE_INFO *pInputType,
                     const MFT_REGISTER_TYPE_INFO *pOutputType,
                     IMFActivate ***pppMFTActivate, UINT32 *pnumMFTActivate)
{
    HRESULT (WINAPI *MFTEnumEx_ptr)(GUID guidCategory, UINT32 Flags,
                                    const MFT_REGISTER_TYPE_INFO *pInputType,
                                    const MFT_REGISTER_TYPE_INFO *pOutputType,
                                    IMFActivate ***pppMFTActivate,
                                    UINT32 *pnumMFTActivate) = NULL;
#if !HAVE_UWP
    HANDLE lib = GetModuleHandleW(L"mfplat.dll");
    if (lib)
        MFTEnumEx_ptr = (void *)GetProcAddress(lib, "MFTEnumEx");
#else
    // In UWP (which lacks GetModuleHandle), just link directly against
    // the functions - this requires building with new/complete enough
    // import libraries.
    MFTEnumEx_ptr = MFTEnumEx;
#endif
    if (!MFTEnumEx_ptr)
        return E_FAIL;
    return MFTEnumEx_ptr(guidCategory,
                         Flags,
                         pInputType,
                         pOutputType,
                         pppMFTActivate,
                         pnumMFTActivate);
}

char *ff_hr_str_buf(char *buf, size_t size, HRESULT hr)
{
#define HR(x) case x: return (char *) # x;
    switch (hr) {
    HR(S_OK)
    HR(E_UNEXPECTED)
    HR(MF_E_INVALIDMEDIATYPE)
    HR(MF_E_INVALIDSTREAMNUMBER)
    HR(MF_E_INVALIDTYPE)
    HR(MF_E_TRANSFORM_CANNOT_CHANGE_MEDIATYPE_WHILE_PROCESSING)
    HR(MF_E_TRANSFORM_TYPE_NOT_SET)
    HR(MF_E_UNSUPPORTED_D3D_TYPE)
    HR(MF_E_TRANSFORM_NEED_MORE_INPUT)
    HR(MF_E_TRANSFORM_STREAM_CHANGE)
    HR(MF_E_NOTACCEPTING)
    HR(MF_E_NO_SAMPLE_TIMESTAMP)
    HR(MF_E_NO_SAMPLE_DURATION)
#undef HR
    }
    snprintf(buf, size, "%x", (unsigned)hr);
    return buf;
}

// If fill_data!=NULL, initialize the buffer and set the length. (This is a
// subtle but important difference: some decoders want CurrentLength==0 on
// provided output buffers.)
IMFSample *ff_create_memory_sample(void *fill_data, size_t size, size_t align)
{
    HRESULT hr;
    IMFSample *sample;
    IMFMediaBuffer *buffer;

    hr = MFCreateSample(&sample);
    if (FAILED(hr))
        return NULL;

    align = FFMAX(align, 16); // 16 is "recommended", even if not required

    hr = MFCreateAlignedMemoryBuffer(size, align - 1, &buffer);
    if (FAILED(hr))
        return NULL;

    if (fill_data) {
        BYTE *tmp;

        hr = IMFMediaBuffer_Lock(buffer, &tmp, NULL, NULL);
        if (FAILED(hr)) {
            IMFMediaBuffer_Release(buffer);
            IMFSample_Release(sample);
            return NULL;
        }
        memcpy(tmp, fill_data, size);

        IMFMediaBuffer_SetCurrentLength(buffer, size);
        IMFMediaBuffer_Unlock(buffer);
    }

    IMFSample_AddBuffer(sample, buffer);
    IMFMediaBuffer_Release(buffer);

    return sample;
}

enum AVSampleFormat ff_media_type_to_sample_fmt(IMFAttributes *type)
{
    HRESULT hr;
    UINT32 bits;
    GUID subtype;

    hr = IMFAttributes_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &bits);
    if (FAILED(hr))
        return AV_SAMPLE_FMT_NONE;

    hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &subtype);
    if (FAILED(hr))
        return AV_SAMPLE_FMT_NONE;

    if (IsEqualGUID(&subtype, &MFAudioFormat_PCM)) {
        switch (bits) {
        case 8:  return AV_SAMPLE_FMT_U8;
        case 16: return AV_SAMPLE_FMT_S16;
        case 32: return AV_SAMPLE_FMT_S32;
        }
    } else if (IsEqualGUID(&subtype, &MFAudioFormat_Float)) {
        switch (bits) {
        case 32: return AV_SAMPLE_FMT_FLT;
        case 64: return AV_SAMPLE_FMT_DBL;
        }
    }

    return AV_SAMPLE_FMT_NONE;
}

struct mf_pix_fmt_entry {
    const GUID *guid;
    enum AVPixelFormat pix_fmt;
};

static const struct mf_pix_fmt_entry mf_pix_fmts[] = {
    {&MFVideoFormat_IYUV, AV_PIX_FMT_YUV420P},
    {&MFVideoFormat_I420, AV_PIX_FMT_YUV420P},
    {&MFVideoFormat_NV12, AV_PIX_FMT_NV12},
    {&MFVideoFormat_P010, AV_PIX_FMT_P010},
    {&MFVideoFormat_P016, AV_PIX_FMT_P010}, // not equal, but compatible
    {&MFVideoFormat_YUY2, AV_PIX_FMT_YUYV422},
};

enum AVPixelFormat ff_media_type_to_pix_fmt(IMFAttributes *type)
{
    HRESULT hr;
    GUID subtype;
    int i;

    hr = IMFAttributes_GetGUID(type, &MF_MT_SUBTYPE, &subtype);
    if (FAILED(hr))
        return AV_PIX_FMT_NONE;

    for (i = 0; i < FF_ARRAY_ELEMS(mf_pix_fmts); i++) {
        if (IsEqualGUID(&subtype, mf_pix_fmts[i].guid))
            return mf_pix_fmts[i].pix_fmt;
    }

    return AV_PIX_FMT_NONE;
}

const GUID *ff_pix_fmt_to_guid(enum AVPixelFormat pix_fmt)
{
    int i;

    for (i = 0; i < FF_ARRAY_ELEMS(mf_pix_fmts); i++) {
        if (mf_pix_fmts[i].pix_fmt == pix_fmt)
            return mf_pix_fmts[i].guid;
    }

    return NULL;
}

// If this GUID is of the form XXXXXXXX-0000-0010-8000-00AA00389B71, then
// extract the XXXXXXXX prefix as FourCC (oh the pain).
int ff_fourcc_from_guid(const GUID *guid, uint32_t *out_fourcc)
{
    if (guid->Data2 == 0 && guid->Data3 == 0x0010 &&
        guid->Data4[0] == 0x80 &&
        guid->Data4[1] == 0x00 &&
        guid->Data4[2] == 0x00 &&
        guid->Data4[3] == 0xAA &&
        guid->Data4[4] == 0x00 &&
        guid->Data4[5] == 0x38 &&
        guid->Data4[6] == 0x9B &&
        guid->Data4[7] == 0x71) {
        *out_fourcc = guid->Data1;
        return 0;
    }

    *out_fourcc = 0;
    return AVERROR_UNKNOWN;
}

struct GUID_Entry {
    const GUID *guid;
    const char *name;
};

#define GUID_ENTRY(var) {&(var), # var}

static struct GUID_Entry guid_names[] = {
    GUID_ENTRY(MFT_FRIENDLY_NAME_Attribute),
    GUID_ENTRY(MFT_TRANSFORM_CLSID_Attribute),
    GUID_ENTRY(MFT_ENUM_HARDWARE_URL_Attribute),
    GUID_ENTRY(MFT_CONNECTED_STREAM_ATTRIBUTE),
    GUID_ENTRY(MFT_CONNECTED_TO_HW_STREAM),
    GUID_ENTRY(MF_SA_D3D_AWARE),
    GUID_ENTRY(ff_MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT),
    GUID_ENTRY(ff_MF_SA_MINIMUM_OUTPUT_SAMPLE_COUNT_PROGRESSIVE),
    GUID_ENTRY(ff_MF_SA_D3D11_BINDFLAGS),
    GUID_ENTRY(ff_MF_SA_D3D11_USAGE),
    GUID_ENTRY(ff_MF_SA_D3D11_AWARE),
    GUID_ENTRY(ff_MF_SA_D3D11_SHARED),
    GUID_ENTRY(ff_MF_SA_D3D11_SHARED_WITHOUT_MUTEX),
    GUID_ENTRY(MF_MT_SUBTYPE),
    GUID_ENTRY(MF_MT_MAJOR_TYPE),
    GUID_ENTRY(MF_MT_AUDIO_SAMPLES_PER_SECOND),
    GUID_ENTRY(MF_MT_AUDIO_NUM_CHANNELS),
    GUID_ENTRY(MF_MT_AUDIO_CHANNEL_MASK),
    GUID_ENTRY(MF_MT_FRAME_SIZE),
    GUID_ENTRY(MF_MT_INTERLACE_MODE),
    GUID_ENTRY(MF_MT_USER_DATA),
    GUID_ENTRY(MF_MT_PIXEL_ASPECT_RATIO),
    GUID_ENTRY(MFMediaType_Audio),
    GUID_ENTRY(MFMediaType_Video),
    GUID_ENTRY(MFAudioFormat_PCM),
    GUID_ENTRY(MFAudioFormat_Float),
    GUID_ENTRY(MFVideoFormat_H264),
    GUID_ENTRY(MFVideoFormat_H264_ES),
    GUID_ENTRY(ff_MFVideoFormat_HEVC),
    GUID_ENTRY(ff_MFVideoFormat_HEVC_ES),
    GUID_ENTRY(MFVideoFormat_MPEG2),
    GUID_ENTRY(MFVideoFormat_MP43),
    GUID_ENTRY(MFVideoFormat_MP4V),
    GUID_ENTRY(MFVideoFormat_WMV1),
    GUID_ENTRY(MFVideoFormat_WMV2),
    GUID_ENTRY(MFVideoFormat_WMV3),
    GUID_ENTRY(MFVideoFormat_WVC1),
    GUID_ENTRY(MFAudioFormat_Dolby_AC3),
    GUID_ENTRY(MFAudioFormat_Dolby_DDPlus),
    GUID_ENTRY(MFAudioFormat_AAC),
    GUID_ENTRY(MFAudioFormat_MP3),
    GUID_ENTRY(MFAudioFormat_MSP1),
    GUID_ENTRY(MFAudioFormat_WMAudioV8),
    GUID_ENTRY(MFAudioFormat_WMAudioV9),
    GUID_ENTRY(MFAudioFormat_WMAudio_Lossless),
    GUID_ENTRY(MF_MT_ALL_SAMPLES_INDEPENDENT),
    GUID_ENTRY(MF_MT_COMPRESSED),
    GUID_ENTRY(MF_MT_FIXED_SIZE_SAMPLES),
    GUID_ENTRY(MF_MT_SAMPLE_SIZE),
    GUID_ENTRY(MF_MT_WRAPPED_TYPE),
    GUID_ENTRY(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION),
    GUID_ENTRY(MF_MT_AAC_PAYLOAD_TYPE),
    GUID_ENTRY(MF_MT_AUDIO_AVG_BYTES_PER_SECOND),
    GUID_ENTRY(MF_MT_AUDIO_BITS_PER_SAMPLE),
    GUID_ENTRY(MF_MT_AUDIO_BLOCK_ALIGNMENT),
    GUID_ENTRY(MF_MT_AUDIO_CHANNEL_MASK),
    GUID_ENTRY(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND),
    GUID_ENTRY(MF_MT_AUDIO_FOLDDOWN_MATRIX),
    GUID_ENTRY(MF_MT_AUDIO_NUM_CHANNELS),
    GUID_ENTRY(MF_MT_AUDIO_PREFER_WAVEFORMATEX),
    GUID_ENTRY(MF_MT_AUDIO_SAMPLES_PER_BLOCK),
    GUID_ENTRY(MF_MT_AUDIO_SAMPLES_PER_SECOND),
    GUID_ENTRY(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE),
    GUID_ENTRY(MF_MT_AUDIO_WMADRC_AVGREF),
    GUID_ENTRY(MF_MT_AUDIO_WMADRC_AVGTARGET),
    GUID_ENTRY(MF_MT_AUDIO_WMADRC_PEAKREF),
    GUID_ENTRY(MF_MT_AUDIO_WMADRC_PEAKTARGET),
    GUID_ENTRY(MF_MT_AVG_BIT_ERROR_RATE),
    GUID_ENTRY(MF_MT_AVG_BITRATE),
    GUID_ENTRY(MF_MT_DEFAULT_STRIDE),
    GUID_ENTRY(MF_MT_DRM_FLAGS),
    GUID_ENTRY(MF_MT_FRAME_RATE),
    GUID_ENTRY(MF_MT_FRAME_RATE_RANGE_MAX),
    GUID_ENTRY(MF_MT_FRAME_RATE_RANGE_MIN),
    GUID_ENTRY(MF_MT_FRAME_SIZE),
    GUID_ENTRY(MF_MT_GEOMETRIC_APERTURE),
    GUID_ENTRY(MF_MT_INTERLACE_MODE),
    GUID_ENTRY(MF_MT_MAX_KEYFRAME_SPACING),
    GUID_ENTRY(MF_MT_MINIMUM_DISPLAY_APERTURE),
    GUID_ENTRY(MF_MT_MPEG_SEQUENCE_HEADER),
    GUID_ENTRY(MF_MT_MPEG_START_TIME_CODE),
    GUID_ENTRY(MF_MT_MPEG2_FLAGS),
    GUID_ENTRY(MF_MT_MPEG2_LEVEL),
    GUID_ENTRY(MF_MT_MPEG2_PROFILE),
    GUID_ENTRY(MF_MT_PAD_CONTROL_FLAGS),
    GUID_ENTRY(MF_MT_PALETTE),
    GUID_ENTRY(MF_MT_PAN_SCAN_APERTURE),
    GUID_ENTRY(MF_MT_PAN_SCAN_ENABLED),
    GUID_ENTRY(MF_MT_PIXEL_ASPECT_RATIO),
    GUID_ENTRY(MF_MT_SOURCE_CONTENT_HINT),
    GUID_ENTRY(MF_MT_TRANSFER_FUNCTION),
    GUID_ENTRY(MF_MT_VIDEO_CHROMA_SITING),
    GUID_ENTRY(MF_MT_VIDEO_LIGHTING),
    GUID_ENTRY(MF_MT_VIDEO_NOMINAL_RANGE),
    GUID_ENTRY(MF_MT_VIDEO_PRIMARIES),
    GUID_ENTRY(MF_MT_VIDEO_ROTATION),
    GUID_ENTRY(MF_MT_YUV_MATRIX),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoThumbnailGenerationMode),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoDropPicWithMissingRef),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoSoftwareDeinterlaceMode),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoFastDecodeMode),
    GUID_ENTRY(ff_CODECAPI_AVLowLatencyMode),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoH264ErrorConcealment),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoMPEG2ErrorConcealment),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoCodecType),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoDXVAMode),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoDXVABusEncryption),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoSWPowerLevel),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoMaxCodedWidth),
    GUID_ENTRY(ff_CODECAPI_AVDecVideoMaxCodedHeight),
    GUID_ENTRY(ff_CODECAPI_AVDecNumWorkerThreads),
    GUID_ENTRY(ff_CODECAPI_AVDecSoftwareDynamicFormatChange),
    GUID_ENTRY(ff_CODECAPI_AVDecDisableVideoPostProcessing),
};

char *ff_guid_str_buf(char *buf, size_t buf_size, const GUID *guid)
{
    uint32_t fourcc;
    int n;
    for (n = 0; n < FF_ARRAY_ELEMS(guid_names); n++) {
        if (IsEqualGUID(guid, guid_names[n].guid)) {
            snprintf(buf, buf_size, "%s", guid_names[n].name);
            return buf;
        }
    }

    if (ff_fourcc_from_guid(guid, &fourcc) >= 0) {
        snprintf(buf, buf_size, "<FourCC %s>", av_fourcc2str(fourcc));
        return buf;
    }

    snprintf(buf, buf_size,
             "{%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}",
             (unsigned) guid->Data1, guid->Data2, guid->Data3,
             guid->Data4[0], guid->Data4[1],
             guid->Data4[2], guid->Data4[3],
             guid->Data4[4], guid->Data4[5],
             guid->Data4[6], guid->Data4[7]);
    return buf;
}

void ff_attributes_dump(void *log, IMFAttributes *attrs)
{
    HRESULT hr;
    UINT32 count;
    int n;

    hr = IMFAttributes_GetCount(attrs, &count);
    if (FAILED(hr))
        return;

    for (n = 0; n < count; n++) {
        GUID key;
        MF_ATTRIBUTE_TYPE type;
        char extra[80] = {0};
        const char *name = NULL;

        hr = IMFAttributes_GetItemByIndex(attrs, n, &key, NULL);
        if (FAILED(hr))
            goto err;

        name = ff_guid_str(&key);

        if (IsEqualGUID(&key, &MF_MT_AUDIO_CHANNEL_MASK)) {
            UINT32 v;
            hr = IMFAttributes_GetUINT32(attrs, &key, &v);
            if (FAILED(hr))
                goto err;
            snprintf(extra, sizeof(extra), " (0x%x)", (unsigned)v);
        } else if (IsEqualGUID(&key, &MF_MT_FRAME_SIZE)) {
            UINT32 w, h;

            hr = ff_MFGetAttributeSize(attrs, &MF_MT_FRAME_SIZE, &w, &h);
            if (FAILED(hr))
                goto err;
            snprintf(extra, sizeof(extra), " (%dx%d)", (int)w, (int)h);
        } else if (IsEqualGUID(&key, &MF_MT_PIXEL_ASPECT_RATIO) ||
                   IsEqualGUID(&key, &MF_MT_FRAME_RATE)) {
            UINT32 num, den;

            hr = ff_MFGetAttributeRatio(attrs, &key, &num, &den);
            if (FAILED(hr))
                goto err;
            snprintf(extra, sizeof(extra), " (%d:%d)", (int)num, (int)den);
        }

        hr = IMFAttributes_GetItemType(attrs, &key, &type);
        if (FAILED(hr))
            goto err;

        switch (type) {
        case MF_ATTRIBUTE_UINT32: {
            UINT32 v;
            hr = IMFAttributes_GetUINT32(attrs, &key, &v);
            if (FAILED(hr))
                goto err;
            av_log(log, AV_LOG_VERBOSE, "   %s=%d%s\n", name, (int)v, extra);
            break;
        case MF_ATTRIBUTE_UINT64: {
            UINT64 v;
            hr = IMFAttributes_GetUINT64(attrs, &key, &v);
            if (FAILED(hr))
                goto err;
            av_log(log, AV_LOG_VERBOSE, "   %s=%lld%s\n", name, (long long)v, extra);
            break;
        }
        case MF_ATTRIBUTE_DOUBLE: {
            DOUBLE v;
            hr = IMFAttributes_GetDouble(attrs, &key, &v);
            if (FAILED(hr))
                goto err;
            av_log(log, AV_LOG_VERBOSE, "   %s=%f%s\n", name, (double)v, extra);
            break;
        }
        case MF_ATTRIBUTE_STRING: {
            wchar_t s[512]; // being lazy here
            hr = IMFAttributes_GetString(attrs, &key, s, sizeof(s), NULL);
            if (FAILED(hr))
                goto err;
            av_log(log, AV_LOG_VERBOSE, "   %s='%ls'%s\n", name, s, extra);
            break;
        }
        case MF_ATTRIBUTE_GUID: {
            GUID v;
            hr = IMFAttributes_GetGUID(attrs, &key, &v);
            if (FAILED(hr))
                goto err;
            av_log(log, AV_LOG_VERBOSE, "   %s=%s%s\n", name, ff_guid_str(&v), extra);
            break;
        }
        case MF_ATTRIBUTE_BLOB: {
            UINT32 sz;
            UINT8 buffer[100];
            hr = IMFAttributes_GetBlobSize(attrs, &key, &sz);
            if (FAILED(hr))
                goto err;
            if (sz <= sizeof(buffer)) {
                // hex-dump it
                char str[512] = {0};
                size_t pos = 0;
                hr = IMFAttributes_GetBlob(attrs, &key, buffer, sizeof(buffer), &sz);
                if (FAILED(hr))
                    goto err;
                for (pos = 0; pos < sz; pos++) {
                    const char *hex = "0123456789ABCDEF";
                    if (pos * 3 + 3 > sizeof(str))
                        break;
                    str[pos * 3 + 0] = hex[buffer[pos] >> 4];
                    str[pos * 3 + 1] = hex[buffer[pos] & 15];
                    str[pos * 3 + 2] = ' ';
                }
                str[pos * 3 + 0] = 0;
                av_log(log, AV_LOG_VERBOSE, "   %s=<blob size %d: %s>%s\n", name, (int)sz, str, extra);
            } else {
                av_log(log, AV_LOG_VERBOSE, "   %s=<blob size %d>%s\n", name, (int)sz, extra);
            }
            break;
        }
        case MF_ATTRIBUTE_IUNKNOWN: {
            av_log(log, AV_LOG_VERBOSE, "   %s=<IUnknown>%s\n", name, extra);
            break;
        }
        default:
            av_log(log, AV_LOG_VERBOSE, "   %s=<unknown type>%s\n", name, extra);
            break;
        }
        }

        if (IsEqualGUID(&key, &MF_MT_SUBTYPE)) {
            const char *fmt;
            fmt = av_get_sample_fmt_name(ff_media_type_to_sample_fmt(attrs));
            if (fmt)
                av_log(log, AV_LOG_VERBOSE, "   FF-sample-format=%s\n", fmt);

            fmt = av_get_pix_fmt_name(ff_media_type_to_pix_fmt(attrs));
            if (fmt)
                av_log(log, AV_LOG_VERBOSE, "   FF-pixel-format=%s\n", fmt);
        }

        continue;
    err:
        av_log(log, AV_LOG_VERBOSE, "   %s=<failed to get value>\n", name ? name : "?");
    }
}

void ff_media_type_dump(void *log, IMFMediaType *type)
{
    ff_attributes_dump(log, (IMFAttributes *)type);
}

const CLSID *ff_codec_to_mf_subtype(enum AVCodecID codec)
{
    switch (codec) {
    case AV_CODEC_ID_H264:              return &MFVideoFormat_H264;
    case AV_CODEC_ID_HEVC:              return &ff_MFVideoFormat_HEVC;
    case AV_CODEC_ID_AC3:               return &MFAudioFormat_Dolby_AC3;
    case AV_CODEC_ID_AAC:               return &MFAudioFormat_AAC;
    case AV_CODEC_ID_MP3:               return &MFAudioFormat_MP3;
    default:                            return NULL;
    }
}

static int init_com_mf(void *log)
{
    HRESULT hr;

    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (hr == RPC_E_CHANGED_MODE) {
        av_log(log, AV_LOG_ERROR, "COM must not be in STA mode\n");
        return AVERROR(EINVAL);
    } else if (FAILED(hr)) {
        av_log(log, AV_LOG_ERROR, "could not initialize COM\n");
        return AVERROR(ENOSYS);
    }

    hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
    if (FAILED(hr)) {
        av_log(log, AV_LOG_ERROR, "could not initialize MediaFoundation\n");
        CoUninitialize();
        return AVERROR(ENOSYS);
    }

    return 0;
}

static void uninit_com_mf(void)
{
    MFShutdown();
    CoUninitialize();
}

// Find and create a IMFTransform with the given input/output types. When done,
// you should use ff_free_mf() to destroy it, which will also uninit COM.
int ff_instantiate_mf(void *log,
                      GUID category,
                      MFT_REGISTER_TYPE_INFO *in_type,
                      MFT_REGISTER_TYPE_INFO *out_type,
                      int use_hw,
                      IMFTransform **res)
{
    HRESULT hr;
    int n;
    int ret;
    IMFActivate **activate;
    UINT32 num_activate;
    IMFActivate *winner = 0;
    UINT32 flags;

    ret = init_com_mf(log);
    if (ret < 0)
        return ret;

    flags = MFT_ENUM_FLAG_SORTANDFILTER;

    if (use_hw) {
        flags |= MFT_ENUM_FLAG_HARDWARE;
    } else {
        flags |= MFT_ENUM_FLAG_SYNCMFT;
    }

    hr = ff_MFTEnumEx(category, flags, in_type, out_type, &activate,
                      &num_activate);
    if (FAILED(hr))
        goto error_uninit_mf;

    if (log) {
        if (!num_activate)
            av_log(log, AV_LOG_ERROR, "could not find any MFT for the given media type\n");

        for (n = 0; n < num_activate; n++) {
            av_log(log, AV_LOG_VERBOSE, "MF %d attributes:\n", n);
            ff_attributes_dump(log, (IMFAttributes *)activate[n]);
        }
    }

    *res = NULL;
    for (n = 0; n < num_activate; n++) {
        if (log)
            av_log(log, AV_LOG_VERBOSE, "activate MFT %d\n", n);
        hr = IMFActivate_ActivateObject(activate[n], &IID_IMFTransform,
                                        (void **)res);
        if (*res) {
            winner = activate[n];
            IMFActivate_AddRef(winner);
            break;
        }
    }

    for (n = 0; n < num_activate; n++)
       IMFActivate_Release(activate[n]);
    CoTaskMemFree(activate);

    if (!*res) {
        if (log)
            av_log(log, AV_LOG_ERROR, "could not create MFT\n");
        goto error_uninit_mf;
    }

    if (log) {
        wchar_t s[512]; // being lazy here
        IMFAttributes *attrs;
        hr = IMFTransform_GetAttributes(*res, &attrs);
        if (!FAILED(hr) && attrs) {

            av_log(log, AV_LOG_VERBOSE, "MFT attributes\n");
            ff_attributes_dump(log, attrs);
            IMFAttributes_Release(attrs);
        }

        hr = IMFActivate_GetString(winner, &MFT_FRIENDLY_NAME_Attribute, s,
                                   sizeof(s), NULL);
        if (!FAILED(hr))
            av_log(log, AV_LOG_INFO, "MFT name: '%ls'\n", s);

    }

    IMFActivate_Release(winner);

    return 0;

error_uninit_mf:
    uninit_com_mf();
    return AVERROR(ENOSYS);
}

void ff_free_mf(IMFTransform **mft)
{
    if (*mft)
        IMFTransform_Release(*mft);
    *mft = NULL;
    uninit_com_mf();
}
