/*
 * Copyright 2019 Jactry Zeng for CodeWeavers
 *
 * This library 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.
 *
 * This library 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 this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

import "mfidl.idl";

cpp_quote("EXTERN_GUID(CLSID_MFMediaEngineClassFactory, 0xb44392da, 0x499b, 0x446b, 0xa4, 0xcb, 0x00, 0x5f, 0xea, 0xd0, 0xe6, 0xd5);")

cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_AUDIO_CATEGORY,                     0xc8d4c51d, 0x350e, 0x41f2, 0xba, 0x46, 0xfa, 0xeb, 0xbb, 0x08, 0x57, 0xf6);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE,                0xd2cb93d1, 0x116a, 0x44f2, 0x93, 0x85, 0xf7, 0xd0, 0xfd, 0xa2, 0xfb, 0x46);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE,         0x4e0212e2, 0xe18f, 0x41e1, 0x95, 0xe5, 0xc0, 0xe7, 0xe9, 0x23, 0x5b, 0xc3);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE9,     0x052c2d39, 0x40c0, 0x4188, 0xab, 0x86, 0xf8, 0x28, 0x27, 0x3b, 0x75, 0x22);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE10,    0x11a47afd, 0x6589, 0x4124, 0xb3, 0x12, 0x61, 0x58, 0xec, 0x51, 0x7f, 0xc3);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11,    0x1cf1315f, 0xce3f, 0x4035, 0x93, 0x91, 0x16, 0x14, 0x2f, 0x77, 0x51, 0x89);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE, 0xa6f3e465, 0x3aca, 0x442c, 0xa3, 0xf0, 0xad, 0x6d, 0xda, 0xd8, 0x39, 0xae);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_CALLBACK,                           0xc60381b8, 0x83a4, 0x41f8, 0xa3, 0xd0, 0xde, 0x05, 0x07, 0x68, 0x49, 0xa9);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_COMPATIBILITY_MODE,                 0x3ef26ad4, 0xdc54, 0x45de, 0xb9, 0xaf, 0x76, 0xc8, 0xc6, 0x6b, 0xfa, 0x8e);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WIN10,           0x5b25e089, 0x6ca7, 0x4139, 0xa2, 0xcb, 0xfc, 0xaa, 0xb3, 0x95, 0x52, 0xa3);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WWA_EDGE,        0x15b29098, 0x9f01, 0x4e4d, 0xb6, 0x5a, 0xc0, 0x6c, 0x6c, 0x89, 0xda, 0x2a);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_CONTENT_PROTECTION_FLAGS,           0xe0350223, 0x5aaf, 0x4d76, 0xa7, 0xc3, 0x06, 0xde, 0x70, 0x89, 0x4d, 0xb4);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_CONTENT_PROTECTION_MANAGER,         0xfdd6dfaa, 0xbd85, 0x4af3, 0x9e, 0x0f, 0xa0, 0x1d, 0x53, 0x9d, 0x87, 0x6a);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_CONTINUE_ON_CODEC_ERROR,            0xdbcdb7f9, 0x48e4, 0x4295, 0xb7, 0x0d, 0xd5, 0x18, 0x23, 0x4e, 0xeb, 0x38);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_COREWINDOW,                         0xfccae4dc, 0x0b7f, 0x41c2, 0x9f, 0x96, 0x46, 0x59, 0x94, 0x8a, 0xcd, 0xdc);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_DXGI_MANAGER,                       0x065702da, 0x1094, 0x486d, 0x86, 0x17, 0xee, 0x7c, 0xc4, 0xee, 0x46, 0x48);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_EME_CALLBACK,                       0x494553a7, 0xa481, 0x4cb7, 0xbe, 0xc5, 0x38, 0x09, 0x03, 0x51, 0x37, 0x31);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_EXTENSION,                          0x3109fd46, 0x060d, 0x4b62, 0x8d, 0xcf, 0xfa, 0xff, 0x81, 0x13, 0x18, 0xd2);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_MEDIA_PLAYER_MODE,                  0x3ddd8d45, 0x5aa1, 0x4112, 0x82, 0xe5, 0x36, 0xf6, 0xa2, 0x19, 0x7e, 0x6e);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_NEEDKEY_CALLBACK,                   0x7ea80843, 0xb6e4, 0x432c, 0x8e, 0xa4, 0x78, 0x48, 0xff, 0xe4, 0x22, 0x0e);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_OPM_HWND,                           0xa0be8ee7, 0x0572, 0x4f2c, 0xa8, 0x01, 0x2a, 0x15, 0x1b, 0xd3, 0xe7, 0x26);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_PLAYBACK_HWND,                      0xd988879b, 0x67c9, 0x4d92, 0xba, 0xa7, 0x6e, 0xad, 0xd4, 0x46, 0x03, 0x9d);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_PLAYBACK_VISUAL,                    0x6debd26f, 0x6ab9, 0x4d7e, 0xb0, 0xee, 0xc6, 0x1a, 0x73, 0xff, 0xad, 0x15);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE,       0x0ac0c497, 0xb3c4, 0x48c9, 0x9c, 0xde, 0xbb, 0x8c, 0xa2, 0x44, 0x2c, 0xa3);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_STREAM_CONTAINS_ALPHA_CHANNEL,      0x5cbfaf44, 0xd2b2, 0x4cfb, 0x80, 0xa7, 0xd4, 0x29, 0xc7, 0x4c, 0x78, 0x9d);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_SYNCHRONOUS_CLOSE,                  0xc3c2e12f, 0x7e0e, 0x4e43, 0xb9, 0x1c, 0xdc, 0x99, 0x2c, 0xcd, 0xfa, 0x5e);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_TELEMETRY_APPLICATION_ID,           0x1e7b273b, 0xa7e4, 0x402a, 0x8f, 0x51, 0xc4, 0x8e, 0x88, 0xa2, 0xca, 0xbc);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_TRACK_ID,                           0x65bea312, 0x4043, 0x4815, 0x8e, 0xab, 0x44, 0xdc, 0xe2, 0xef, 0x8f, 0x2a);")
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT,                0x5066893c, 0x8cf9, 0x42bc, 0x8b, 0x8a, 0x47, 0x22, 0x12, 0xe5, 0x27, 0x26);")

typedef enum MF_MEDIA_ENGINE_ERR
{
    MF_MEDIA_ENGINE_ERR_NOERROR,
    MF_MEDIA_ENGINE_ERR_ABORTED,
    MF_MEDIA_ENGINE_ERR_NETWORK,
    MF_MEDIA_ENGINE_ERR_DECODE,
    MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED,
    MF_MEDIA_ENGINE_ERR_ENCRYPTED
} MF_MEDIA_ENGINE_ERR;

typedef enum MF_MEDIA_ENGINE_PRELOAD
{
    MF_MEDIA_ENGINE_PRELOAD_MISSING,
    MF_MEDIA_ENGINE_PRELOAD_EMPTY,
    MF_MEDIA_ENGINE_PRELOAD_NONE,
    MF_MEDIA_ENGINE_PRELOAD_METADATA,
    MF_MEDIA_ENGINE_PRELOAD_AUTOMATIC
} MF_MEDIA_ENGINE_PRELOAD;

typedef enum MF_MEDIA_ENGINE_CANPLAY
{
    MF_MEDIA_ENGINE_CANPLAY_NOT_SUPPORTED,
    MF_MEDIA_ENGINE_CANPLAY_MAYBE,
    MF_MEDIA_ENGINE_CANPLAY_PROBABLY,
} MF_MEDIA_ENGINE_CANPLAY;

typedef struct MFVideoNormalizedRect
{
    float left;
    float top;
    float right;
    float bottom;
} MFVideoNormalizedRect;

typedef enum MF_MEDIA_ENGINE_CREATEFLAGS
{
    MF_MEDIA_ENGINE_AUDIOONLY = 0x1,
    MF_MEDIA_ENGINE_WAITFORSTABLE_STATE = 0x2,
    MF_MEDIA_ENGINE_FORCEMUTE = 0x4,
    MF_MEDIA_ENGINE_REAL_TIME_MODE = 0x8,
    MF_MEDIA_ENGINE_DISABLE_LOCAL_PLUGINS = 0x10,
    MF_MEDIA_ENGINE_CREATEFLAGS_MASK = 0x1f
} MF_MEDIA_ENGINE_CREATEFLAGS;

[
    object,
    uuid(fc0e10d2-ab2a-4501-a951-06bb1075184c),
    local,
    pointer_default(unique)
]
interface IMFMediaError : IUnknown
{
    USHORT GetErrorCode();
    HRESULT GetExtendedErrorCode();
    HRESULT SetErrorCode([in] MF_MEDIA_ENGINE_ERR error);
    HRESULT SetExtendedErrorCode([in] HRESULT error);
}

[
    object,
    uuid(7a5e5354-b114-4c72-b991-3131d75032ea),
    local,
    pointer_default(unique)
]
interface IMFMediaEngineSrcElements : IUnknown
{
    DWORD GetLength();
    HRESULT GetURL([in] DWORD index, [out] BSTR *url);
    HRESULT GetType([in] DWORD index, [out] BSTR *type);
    HRESULT GetMedia([in] DWORD index, [out] BSTR *media);
    HRESULT AddElement([in] BSTR url, [in] BSTR type, [in] BSTR media);
    HRESULT RemoveAllElements();
}

[
    object,
    uuid(db71a2fc-078a-414e-9df9-8c2531b0aa6c),
    local,
    pointer_default(unique)
]
interface IMFMediaTimeRange : IUnknown
{
    DWORD GetLength();
    HRESULT GetStart([in] DWORD index, [out] double *start);
    HRESULT GetEnd([in] DWORD index, [out] double *end);
    BOOL ContainsTime([in] double time);
    HRESULT AddRange([in] double start, [in] double end);
    HRESULT Clear();
}

[
    object,
    uuid(98a1b0bb-03eb-4935-ae7c-93c1fa0e1c93),
    local,
    pointer_default(unique)
]
interface IMFMediaEngine : IUnknown
{
    HRESULT GetError([out] IMFMediaError **error);
    HRESULT SetErrorCode([in] MF_MEDIA_ENGINE_ERR error);
    HRESULT SetSourceElements([in] IMFMediaEngineSrcElements *elements);
    HRESULT SetSource([in] BSTR url);
    HRESULT GetCurrentSource([out] BSTR *url);
    USHORT GetNetworkState();
    MF_MEDIA_ENGINE_PRELOAD GetPreload();
    HRESULT SetPreload([in] MF_MEDIA_ENGINE_PRELOAD preload);
    HRESULT GetBuffered([out] IMFMediaTimeRange **buffered);
    HRESULT Load();
    HRESULT CanPlayType([in] BSTR type, [out] MF_MEDIA_ENGINE_CANPLAY *answer);
    USHORT GetReadyState();
    BOOL IsSeeking();
    cpp_quote("#undef GetCurrentTime")
    double GetCurrentTime();
    HRESULT SetCurrentTime([in] double time);
    double GetStartTime();
    double GetDuration();
    BOOL IsPaused();
    double GetDefaultPlaybackRate();
    HRESULT SetDefaultPlaybackRate([in] double rate);
    double GetPlaybackRate();
    HRESULT SetPlaybackRate([in] double rate);
    HRESULT GetPlayed([out] IMFMediaTimeRange **played);
    HRESULT GetSeekable([out] IMFMediaTimeRange **seekable);
    BOOL IsEnded();
    BOOL GetAutoPlay();
    HRESULT SetAutoPlay([in] BOOL autoplay);
    BOOL GetLoop();
    HRESULT SetLoop([in] BOOL loop);
    HRESULT Play();
    HRESULT Pause();
    BOOL GetMuted();
    HRESULT SetMuted([in] BOOL muted);
    double GetVolume();
    HRESULT SetVolume([in] double volume);
    BOOL HasVideo();
    BOOL HasAudio();
    HRESULT GetNativeVideoSize([out] DWORD *cx, [out] DWORD *cy);
    HRESULT GetVideoAspectRatio([out] DWORD *cx, [out] DWORD *cy);
    HRESULT Shutdown();
    HRESULT TransferVideoFrame([in] IUnknown *surface, [in] const MFVideoNormalizedRect *src,
                               [in] const RECT *dst, [in] const MFARGB *color);
    HRESULT OnVideoStreamTick([out] LONGLONG *time);
}

[
    object,
    uuid(4d645ace-26aa-4688-9be1-df3516990b93),
    local,
    pointer_default(unique)
]
interface IMFMediaEngineClassFactory : IUnknown
{
    HRESULT CreateInstance([in] DWORD flags, [in] IMFAttributes *attributes, [out] IMFMediaEngine **engine);
    HRESULT CreateTimeRange([out] IMFMediaTimeRange **range);
    HRESULT CreateError([out] IMFMediaError **error);
}

[
    object,
    uuid(fee7c112-e776-42b5-9bbf-0048524e2bd5),
    local,
    pointer_default(unique)
]
interface IMFMediaEngineNotify : IUnknown
{
    HRESULT EventNotify([in] DWORD event, [in] DWORD_PTR param1, [in] DWORD param2);
}
