cpp_quote("#include <winapifamily.h>")

//*@@@+++@@@@******************************************************************
//
// Microsoft Windows Media Foundation
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//*@@@---@@@@******************************************************************
//

import "unknwn.idl";
import "mfidl.idl";

cpp_quote("#if (WINVER >= _WIN32_WINNT_WIN8) ")

cpp_quote("")
cpp_quote("// Prevent a name collision")
cpp_quote("#undef GetCurrentTime")
cpp_quote("")

#pragma region Application Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)")

cpp_quote("#define MF_INVALID_PRESENTATION_TIME 0x8000000000000000")

//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MEDIA_ENGINE_ERROR 
//
//  Synopsis:   Defines the error status of <video>/<audio> elements
//
//------------------------------------------------------------------------------
typedef enum MF_MEDIA_ENGINE_ERR
{
    MF_MEDIA_ENGINE_ERR_NOERROR = 0,
    MF_MEDIA_ENGINE_ERR_ABORTED = 1,
    MF_MEDIA_ENGINE_ERR_NETWORK = 2,
    MF_MEDIA_ENGINE_ERR_DECODE = 3,
    MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED = 4,
    MF_MEDIA_ENGINE_ERR_ENCRYPTED = 5
} MF_MEDIA_ENGINE_ERR;

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaError
//
//  Synopsis:   Media engine error information
//
//  See http://dev.w3.org/html5/spec/video.html#mediaerror for details
//------------------------------------------------------------------------------
[
    object,
    uuid(fc0e10d2-ab2a-4501-a951-06bb1075184c),
    pointer_default(unique),
    local
]
interface IMFMediaError : IUnknown
{
    USHORT GetErrorCode();
    HRESULT GetExtendedErrorCode();
    HRESULT SetErrorCode([in, annotation("_In_")] MF_MEDIA_ENGINE_ERR error);
    HRESULT SetExtendedErrorCode([in, annotation("_In_")] HRESULT error);
};

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaTimeRange
//
//  Synopsis:   IMFMediaTimeRange represents a list of ranges (periods) of time
//
//  See http://dev.w3.org/html5/spec/video.html#timeranges for details            
//------------------------------------------------------------------------------
[
    object,
    uuid(db71a2fc-078a-414e-9df9-8c2531b0aa6c),
    pointer_default(unique),
    local
]
interface IMFMediaTimeRange : IUnknown
{
    DWORD GetLength();

    HRESULT GetStart(
        [in, annotation("_In_")] DWORD index,
        [out, annotation("_Out_")] double* pStart
        );

    HRESULT GetEnd(
        [in, annotation("_In_")] DWORD index,
        [out, annotation("_Out_")] double* pEnd
        );

    // Extensions
    BOOL ContainsTime(
        [in, annotation("_In_")] double time
        );

    HRESULT AddRange(
        [in, annotation("_In_")] double startTime,
        [in, annotation("_In_")] double endTime
        );

    HRESULT Clear();
};

//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MEDIA_ENGINE_EVENT
//
//  Synopsis:   A list of events generated by the media engine
//
//  See http://dev.w3.org/html5/spec/video.html#mediaevents for details
//------------------------------------------------------------------------------
typedef enum MF_MEDIA_ENGINE_EVENT
{
    //
    // Standard events
    //
    MF_MEDIA_ENGINE_EVENT_LOADSTART = 1,
    MF_MEDIA_ENGINE_EVENT_PROGRESS = 2,
    MF_MEDIA_ENGINE_EVENT_SUSPEND = 3,
    MF_MEDIA_ENGINE_EVENT_ABORT = 4,
    MF_MEDIA_ENGINE_EVENT_ERROR = 5,
    MF_MEDIA_ENGINE_EVENT_EMPTIED = 6,
    MF_MEDIA_ENGINE_EVENT_STALLED = 7,
    MF_MEDIA_ENGINE_EVENT_PLAY = 8,
    MF_MEDIA_ENGINE_EVENT_PAUSE = 9,
    MF_MEDIA_ENGINE_EVENT_LOADEDMETADATA = 10,
    MF_MEDIA_ENGINE_EVENT_LOADEDDATA = 11,
    MF_MEDIA_ENGINE_EVENT_WAITING = 12,
    MF_MEDIA_ENGINE_EVENT_PLAYING = 13,
    MF_MEDIA_ENGINE_EVENT_CANPLAY = 14,
    MF_MEDIA_ENGINE_EVENT_CANPLAYTHROUGH = 15,
    MF_MEDIA_ENGINE_EVENT_SEEKING = 16,
    MF_MEDIA_ENGINE_EVENT_SEEKED = 17,
    MF_MEDIA_ENGINE_EVENT_TIMEUPDATE = 18,
    MF_MEDIA_ENGINE_EVENT_ENDED = 19,
    MF_MEDIA_ENGINE_EVENT_RATECHANGE = 20,
    MF_MEDIA_ENGINE_EVENT_DURATIONCHANGE = 21,
    MF_MEDIA_ENGINE_EVENT_VOLUMECHANGE = 22,
    
    //
    // Extensions
    //
    MF_MEDIA_ENGINE_EVENT_FORMATCHANGE = 1000,
    MF_MEDIA_ENGINE_EVENT_PURGEQUEUEDEVENTS  = 1001,
    MF_MEDIA_ENGINE_EVENT_TIMELINE_MARKER = 1002,
    MF_MEDIA_ENGINE_EVENT_BALANCECHANGE = 1003,
    MF_MEDIA_ENGINE_EVENT_DOWNLOADCOMPLETE = 1004,
    MF_MEDIA_ENGINE_EVENT_BUFFERINGSTARTED = 1005,
    MF_MEDIA_ENGINE_EVENT_BUFFERINGENDED = 1006,
    MF_MEDIA_ENGINE_EVENT_FRAMESTEPCOMPLETED = 1007,
    MF_MEDIA_ENGINE_EVENT_NOTIFYSTABLESTATE = 1008,
    MF_MEDIA_ENGINE_EVENT_FIRSTFRAMEREADY = 1009, 
    MF_MEDIA_ENGINE_EVENT_TRACKSCHANGE = 1010,
    MF_MEDIA_ENGINE_EVENT_OPMINFO = 1011,
    MF_MEDIA_ENGINE_EVENT_RESOURCELOST = 1012,
    MF_MEDIA_ENGINE_EVENT_DELAYLOADEVENT_CHANGED = 1013,
    MF_MEDIA_ENGINE_EVENT_STREAMRENDERINGERROR = 1014,
    MF_MEDIA_ENGINE_EVENT_SUPPORTEDRATES_CHANGED = 1015,
    MF_MEDIA_ENGINE_EVENT_AUDIOENDPOINTCHANGE = 1016,

} MF_MEDIA_ENGINE_EVENT;


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineNotify
//
//  Synopsis:   IMFMediaEngineNotify fires events
//
//  This interface is implemented by the component using IMFMediaEngine
//------------------------------------------------------------------------------
[
    object,
    uuid(fee7c112-e776-42b5-9bbf-0048524e2bd5),
    pointer_default(unique),
    local
]
interface IMFMediaEngineNotify : IUnknown
{
    HRESULT EventNotify(
        [in, annotation("_In_")] DWORD event,
        [in, annotation("_In_")] DWORD_PTR param1,
        [in, annotation("_In_")] DWORD param2
        );
};

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineSrcElements
//
//  Synopsis:   IMFMediaEngineSrcElements represents a list of <source> elements
//
//  See http://dev.w3.org/html5/spec/video.html#the-source-element for details
//------------------------------------------------------------------------------
[
    object,
    uuid(7a5e5354-b114-4c72-b991-3131d75032ea),
    pointer_default(unique),
    local
]
interface IMFMediaEngineSrcElements : IUnknown
{
    DWORD GetLength();
    
    HRESULT GetURL(
        [in, annotation("_In_")] DWORD index,
        [out, annotation("_Out_")] BSTR* pURL
        );

    HRESULT GetType(
        [in, annotation("_In_")] DWORD index,
        [out, annotation("_Out_")] BSTR* pType
        );

    HRESULT GetMedia(
        [in, annotation("_In_")] DWORD index,
        [out, annotation("_Out_")] BSTR* pMedia
        );
    
    HRESULT AddElement(
        [in, annotation("_In_opt_")] BSTR pURL, 
        [in, annotation("_In_opt_")] BSTR pType, 
        [in, annotation("_In_opt_")] BSTR pMedia
        );

    HRESULT RemoveAllElements();
};

//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MEDIA_ENGINE_NETWORK
//
//  Synopsis:   Defines different network states of the <audio>/<video> elements
//
//  See http://dev.w3.org/html5/spec/video.html#dom-media-networkstate for details
//------------------------------------------------------------------------------
typedef enum MF_MEDIA_ENGINE_NETWORK
{
    MF_MEDIA_ENGINE_NETWORK_EMPTY = 0,
    MF_MEDIA_ENGINE_NETWORK_IDLE = 1,
    MF_MEDIA_ENGINE_NETWORK_LOADING = 2,
    MF_MEDIA_ENGINE_NETWORK_NO_SOURCE = 3 
} MF_MEDIA_ENGINE_NETWORK;



//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MEDIA_ENGINE_READY
//
//  Synopsis:   Defines different ready states of the <audio>/<video> elements
//
//  See http://dev.w3.org/html5/spec/video.html#the-ready-states for details
//------------------------------------------------------------------------------
typedef enum MF_MEDIA_ENGINE_READY
{
    MF_MEDIA_ENGINE_READY_HAVE_NOTHING = 0,
    MF_MEDIA_ENGINE_READY_HAVE_METADATA = 1,
    MF_MEDIA_ENGINE_READY_HAVE_CURRENT_DATA = 2,
    MF_MEDIA_ENGINE_READY_HAVE_FUTURE_DATA = 3,
    MF_MEDIA_ENGINE_READY_HAVE_ENOUGH_DATA = 4 
} MF_MEDIA_ENGINE_READY;


//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MEDIA_ENGINE_CANPLAY
//
//  Synopsis:   Defines the likelihood that the <audio>/<video> elements will be able
///             to play a source
//
//  See http://dev.w3.org/html5/spec/video.html#dom-navigator-canplaytype for details
//------------------------------------------------------------------------------
typedef enum MF_MEDIA_ENGINE_CANPLAY
{
    MF_MEDIA_ENGINE_CANPLAY_NOT_SUPPORTED = 0,
    MF_MEDIA_ENGINE_CANPLAY_MAYBE = 1,
    MF_MEDIA_ENGINE_CANPLAY_PROBABLY = 2,
} MF_MEDIA_ENGINE_CANPLAY;


//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MEDIA_ENGINE_PRELOAD
//
//  Synopsis:   Defines different types of preloads
//
//  See http://dev.w3.org/html5/spec/video.html#attr-media-preload for details
//------------------------------------------------------------------------------
typedef enum MF_MEDIA_ENGINE_PRELOAD
{
    MF_MEDIA_ENGINE_PRELOAD_MISSING = 0,
    MF_MEDIA_ENGINE_PRELOAD_EMPTY = 1,
    MF_MEDIA_ENGINE_PRELOAD_NONE = 2,
    MF_MEDIA_ENGINE_PRELOAD_METADATA = 3,
    MF_MEDIA_ENGINE_PRELOAD_AUTOMATIC = 4
} MF_MEDIA_ENGINE_PRELOAD;


cpp_quote("#ifndef _MFVideoNormalizedRect_")
cpp_quote("#define _MFVideoNormalizedRect_")
typedef struct MFVideoNormalizedRect
{
    float left;
    float top;
    float right;
    float bottom;
} MFVideoNormalizedRect;
cpp_quote("#endif")

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngine
//
//  Synopsis:   IMFMediaEngine provides audio and video playback for the
//              HTML5 <audio> and <video> elements.
//
//  See http://dev.w3.org/html5/spec/video.html#video for details
//------------------------------------------------------------------------------
[
    object,
    uuid(98a1b0bb-03eb-4935-ae7c-93c1fa0e1c93),
    pointer_default(unique),
    local
]
interface IMFMediaEngine : IUnknown
{
    // Error state
    HRESULT GetError(
        [out, annotation("_Outptr_")] IMFMediaError** ppError
        );

    HRESULT SetErrorCode(
        [in, annotation("_In_")] MF_MEDIA_ENGINE_ERR error
        );
    
    // Network state
    HRESULT SetSourceElements(
        [in, annotation("_In_")] IMFMediaEngineSrcElements* pSrcElements
        );

    HRESULT SetSource(
        [in, annotation("_In_")] BSTR pUrl
        );

    HRESULT GetCurrentSource(
        [out, annotation("_Out_")] BSTR* ppUrl
        );

    USHORT GetNetworkState();

    MF_MEDIA_ENGINE_PRELOAD GetPreload();

    HRESULT SetPreload(
        [in, annotation("_In_")] MF_MEDIA_ENGINE_PRELOAD Preload
        );

    HRESULT GetBuffered(
        [out, annotation("_Outptr_")] IMFMediaTimeRange** ppBuffered
        );

    HRESULT Load();

    HRESULT CanPlayType(
        [in, annotation("_In_")] BSTR type,
        [out, annotation("_Out_")] MF_MEDIA_ENGINE_CANPLAY* pAnswer
        );
    
    // Ready state
    USHORT GetReadyState();

    BOOL IsSeeking();

    
    // Playback state
    double GetCurrentTime();

    HRESULT SetCurrentTime(
        [in, annotation("_In_")] double seekTime
        );

    double GetStartTime();

    double GetDuration();

    BOOL IsPaused();

    double GetDefaultPlaybackRate();

    HRESULT SetDefaultPlaybackRate(
        [in, annotation("_In_")] double Rate
        );

    double GetPlaybackRate();

    HRESULT SetPlaybackRate(
        [in, annotation("_In_")] double Rate
        );

    HRESULT GetPlayed(
        [out, annotation("_Outptr_")] IMFMediaTimeRange** ppPlayed 
        );

    HRESULT GetSeekable(
        [out, annotation("_Outptr_")] IMFMediaTimeRange** ppSeekable
        );

    BOOL IsEnded();

    BOOL GetAutoPlay();

    HRESULT SetAutoPlay(
        [in, annotation("_In_")] BOOL AutoPlay
        );

    BOOL GetLoop();

    HRESULT SetLoop(
        [in, annotation("_In_")] BOOL Loop
        );

    HRESULT Play();

    HRESULT Pause();

    // Controls
    BOOL GetMuted();

    HRESULT SetMuted(
        [in, annotation("_In_")] BOOL Muted 
        );

    double GetVolume();

    HRESULT SetVolume(
        [in, annotation("_In_")] double Volume
        );

    // Extensions
    BOOL HasVideo();

    BOOL HasAudio();

    HRESULT GetNativeVideoSize(
        [out, annotation("_Out_opt_")] DWORD *cx,
        [out, annotation("_Out_opt_")] DWORD *cy
        );

    HRESULT GetVideoAspectRatio(
        [out, annotation("_Out_opt_")] DWORD *cx,
        [out, annotation("_Out_opt_")] DWORD *cy
        );

    HRESULT Shutdown();

    HRESULT TransferVideoFrame(
        [in, annotation("_In_")] IUnknown* pDstSurf,
        [in, annotation("_In_opt_")] const MFVideoNormalizedRect* pSrc,
        [in, annotation("_In_")] const RECT* pDst,
        [in, annotation("_In_opt_")] const MFARGB* pBorderClr
        );

    HRESULT OnVideoStreamTick(
        [out, annotation("_Out_")] LONGLONG* pPts
        );
};  


typedef enum MF_MEDIA_ENGINE_S3D_PACKING_MODE
{
    MF_MEDIA_ENGINE_S3D_PACKING_MODE_NONE = 0,
    MF_MEDIA_ENGINE_S3D_PACKING_MODE_SIDE_BY_SIDE = 1,
    MF_MEDIA_ENGINE_S3D_PACKING_MODE_TOP_BOTTOM = 2

} MF_MEDIA_ENGINE_S3D_PACKING_MODE;


typedef enum MF_MEDIA_ENGINE_STATISTIC
{
    MF_MEDIA_ENGINE_STATISTIC_FRAMES_RENDERED = 0,
    MF_MEDIA_ENGINE_STATISTIC_FRAMES_DROPPED = 1,
    MF_MEDIA_ENGINE_STATISTIC_BYTES_DOWNLOADED = 2,
    MF_MEDIA_ENGINE_STATISTIC_BUFFER_PROGRESS = 3,
    MF_MEDIA_ENGINE_STATISTIC_FRAMES_PER_SECOND = 4,
    MF_MEDIA_ENGINE_STATISTIC_PLAYBACK_JITTER = 5,
    MF_MEDIA_ENGINE_STATISTIC_FRAMES_CORRUPTED  = 6,
    MF_MEDIA_ENGINE_STATISTIC_TOTAL_FRAME_DELAY = 7,

} MF_MEDIA_ENGINE_STATISTIC;

typedef enum MF_MEDIA_ENGINE_SEEK_MODE
{
    MF_MEDIA_ENGINE_SEEK_MODE_NORMAL          = 0,
    MF_MEDIA_ENGINE_SEEK_MODE_APPROXIMATE     = 1,
} MF_MEDIA_ENGINE_SEEK_MODE;

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineEx
//
//  Synopsis:   IMFMediaEngineEx extends the media engine beyond the basic 
//              specification of the HTML5 <audio> and <video> elements.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(83015ead-b1e6-40d0-a98a-37145ffe1ad1),
    pointer_default(unique),
    local
]
interface IMFMediaEngineEx : IMFMediaEngine
{
    HRESULT SetSourceFromByteStream(
        [in, annotation("_In_")] IMFByteStream* pByteStream,
        [in, annotation("_In_")] BSTR pURL
        );

    HRESULT GetStatistics(
        [in, annotation("_In_")] MF_MEDIA_ENGINE_STATISTIC StatisticID,
        [out, annotation("_Out_")] PROPVARIANT* pStatistic
        );

    HRESULT UpdateVideoStream(
        [in, annotation("_In_opt_")] const MFVideoNormalizedRect* pSrc,
        [in, annotation("_In_opt_")] const RECT* pDst,
        [in, annotation("_In_opt_")] const MFARGB* pBorderClr
        );

    double GetBalance();

    HRESULT SetBalance(
        [in, annotation("_In_")] double balance
        );

    BOOL IsPlaybackRateSupported (
        [in, annotation("_In_")] double rate
        );

    HRESULT FrameStep(
        [in, annotation("_In_")] BOOL Forward
        );

    HRESULT GetResourceCharacteristics(
        [out, annotation("_Out_")] DWORD* pCharacteristics
        );

    HRESULT GetPresentationAttribute (  
        [in, annotation("_In_")] REFGUID guidMFAttribute,
        [out, annotation("_Out_")] PROPVARIANT *pvValue
        );

    HRESULT GetNumberOfStreams(  
        [out, annotation("_Out_")] DWORD *pdwStreamCount
        );

    HRESULT GetStreamAttribute (  
        [in, annotation("_In_")] DWORD dwStreamIndex,
        [in, annotation("_In_")] REFGUID guidMFAttribute,
        [out, annotation("_Out_")] PROPVARIANT *pvValue
        );

    HRESULT GetStreamSelection(  
        [in, annotation("_In_")] DWORD dwStreamIndex,
        [out, annotation("_Out_")] BOOL* pEnabled
        );

    HRESULT SetStreamSelection(  
        [in, annotation("_In_")] DWORD dwStreamIndex,
        [in, annotation("_In_")] BOOL Enabled
        );

    HRESULT ApplyStreamSelections();

    HRESULT IsProtected(  
        [out, annotation("_Out_")] BOOL* pProtected
        );

    HRESULT InsertVideoEffect(
        [in, annotation("_In_")] IUnknown* pEffect,
        [in, annotation("_In_")] BOOL fOptional
        );

    HRESULT InsertAudioEffect(
        [in, annotation("_In_")] IUnknown* pEffect,
        [in, annotation("_In_")] BOOL fOptional
        );

    HRESULT RemoveAllEffects();

    HRESULT SetTimelineMarkerTimer(  
        [in, annotation("_In_")] double timeToFire
        );

    HRESULT GetTimelineMarkerTimer(  
        [out, annotation("_Out_")] double* pTimeToFire
        );

    HRESULT CancelTimelineMarkerTimer();

    // Stereoscopic 3D support
    BOOL IsStereo3D();

    HRESULT GetStereo3DFramePackingMode(
        [out, annotation("_Out_")] MF_MEDIA_ENGINE_S3D_PACKING_MODE* packMode
        );
    HRESULT SetStereo3DFramePackingMode(
        [in, annotation("_In_")] MF_MEDIA_ENGINE_S3D_PACKING_MODE packMode
        );

    HRESULT GetStereo3DRenderMode(
        [out, annotation("_Out_")] MF3DVideoOutputType* outputType
        );

    HRESULT SetStereo3DRenderMode(
        [in, annotation("_In_")] MF3DVideoOutputType outputType
        );

    // DComp support
    HRESULT EnableWindowlessSwapchainMode(
        [in, annotation("_In_")] BOOL fEnable
        );

    HRESULT GetVideoSwapchainHandle(
        [out, annotation("_Out_")] HANDLE* phSwapchain
        );

    // video mirroring
    HRESULT EnableHorizontalMirrorMode(
        [in, annotation("_In_")] BOOL fEnable
        );

    // audio settings for next resource load
    HRESULT GetAudioStreamCategory(
        [out, annotation("_Out_")] UINT32* pCategory
        );

    HRESULT SetAudioStreamCategory(
        [in, annotation("_In_")] UINT32 category
        );

    HRESULT GetAudioEndpointRole(
        [out, annotation("_Out_")] UINT32* pRole
        );

    HRESULT SetAudioEndpointRole(
        [in, annotation("_In_")] UINT32 role
        );

    HRESULT GetRealTimeMode(
        [out, annotation("_Out_")] BOOL* pfEnabled
        );

    HRESULT SetRealTimeMode(
        [in, annotation("_In_")] BOOL fEnable
        );

    // advanced seeking support
    HRESULT SetCurrentTimeEx(
        [in, annotation("_In_")] double seekTime,
        [in, annotation("_In_")] MF_MEDIA_ENGINE_SEEK_MODE seekMode
        );

    // timer control
    HRESULT EnableTimeUpdateTimer(
        [in, annotation("_In_")] BOOL fEnableTimer
        );
};

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineAudioEndpointId
//
//  Synopsis:   IMFMediaEngineAudioEndpointId extends the media engine for audio endpoint Ids
//
//------------------------------------------------------------------------------
[
    object,
    uuid(7a3bac98-0e76-49fb-8c20-8a86fd98eaf2),
    pointer_default(unique),
    local
]
interface IMFMediaEngineAudioEndpointId : IUnknown
{
    HRESULT SetAudioEndpointId(
        [in, annotation("_In_opt_")] LPCWSTR pszEndpointId
        );

    HRESULT GetAudioEndpointId(
        [out, annotation("_Outptr_")] LPWSTR* ppszEndpointId
        );
};

typedef enum MF_MEDIA_ENGINE_EXTENSION_TYPE
{
    MF_MEDIA_ENGINE_EXTENSION_TYPE_MEDIASOURCE = 0,
    MF_MEDIA_ENGINE_EXTENSION_TYPE_BYTESTREAM = 1
} MF_MEDIA_ENGINE_EXTENSION_TYPE;

//+-----------------------------------------------------------------------------
//
//  Interface:  IMediaEngineExtension
//
//  Synopsis:   Allows Media Engine clients to extend the range of formats 
//              supported by the Media Engine by providing the Media Engine
//              with a mechanism to load custom MF Media Sources.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(2f69d622-20b5-41e9-afdf-89ced1dda04e),
    pointer_default(unique),
    local
]
interface IMFMediaEngineExtension : IUnknown
{
    HRESULT CanPlayType(
        [in, annotation("_In_")] BOOL AudioOnly, // are we being called by an audio or video tag
        [in, annotation("_In_")] BSTR MimeType,  // mime type of interest
        [out, annotation("_Out_")] MF_MEDIA_ENGINE_CANPLAY* pAnswer // answer returned here
        );

    HRESULT BeginCreateObject(
        [in, annotation("_In_")] BSTR bstrURL,                   // URL of object to be created
        [in, annotation("_In_opt_")] IMFByteStream* pByteStream, // optional bytestream to use
        [in, annotation("_In_")] MF_OBJECT_TYPE type,            // type of object to be created
        [out, annotation("_Outptr_")] IUnknown** ppIUnknownCancelCookie,// cancel cookie to be used if we abort the operation early
        [in, annotation("_In_")] IMFAsyncCallback* pCallback,    // callback to be invoked when operation completes
        [in, annotation("_In_opt_")] IUnknown* punkState         // optional async state
        );
            
    HRESULT CancelObjectCreation(
        [in, annotation("_In_")] IUnknown* pIUnknownCancelCookie // cancel cookie from BeginCreateObject
        );

    HRESULT EndCreateObject(
        [in, annotation("_In_")] IMFAsyncResult* pResult,        // Object creation result
        [out, annotation("_Outptr_")] IUnknown** ppObject     // pointer to created object
        );
};

enum MF_MEDIA_ENGINE_FRAME_PROTECTION_FLAGS 
{
    MF_MEDIA_ENGINE_FRAME_PROTECTION_FLAG_PROTECTED = 0x01,
    MF_MEDIA_ENGINE_FRAME_PROTECTION_FLAG_REQUIRES_SURFACE_PROTECTION = 0x02,
    MF_MEDIA_ENGINE_FRAME_PROTECTION_FLAG_REQUIRES_ANTI_SCREEN_SCRAPE_PROTECTION = 0x04,
};

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineProtectedContent
//
//  Synopsis:   Support for playback of DRM'ed content by the  
//              supported by the Media Engine by providing the Media Engine
//              with a mechanism to load custom MF Media Sources.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(9f8021e8-9c8c-487e-bb5c-79aa4779938c),
    local
]
interface IMFMediaEngineProtectedContent : IUnknown
{
    //  Call this to share surfaces in a device with the PMP process
    HRESULT ShareResources([annotation("_In_")] IUnknown *pUnkDeviceContext);

    //  Get required frame protections
    //  these may be required by some or all frames in the content
    HRESULT GetRequiredProtections([out, annotation("_Out_")] DWORD *pFrameProtectionFlags);

    //  Set the window to apply link protections to
    HRESULT SetOPMWindow([in, annotation("_In_")] HWND hwnd);

    //  Transfer a frame from protected content
    HRESULT TransferVideoFrame(
        [in, annotation("_In_")] IUnknown* pDstSurf,
        [in, annotation("_In_opt_")] const MFVideoNormalizedRect* pSrc,
        [in, annotation("_In_")] const RECT* pDst,
        [in, annotation("_In_opt_")] const MFARGB* pBorderClr,
        [out, annotation("_Out_")] DWORD *pFrameProtectionFlags
        );

    //  Set the content protection manager
    HRESULT SetContentProtectionManager([in, annotation("_In_opt_")] IMFContentProtectionManager *pCPM);

    //  Set certificate - needed for accessing raw protected frames
    HRESULT SetApplicationCertificate(
        [in, annotation("_In_reads_bytes_(cbBlob)")] const BYTE *pbBlob,
        [in, annotation("_In_")] DWORD cbBlob
        );
}

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */")
#pragma endregion

#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")

//+-----------------------------------------------------------------------------
//
//  Interface:  IAudioSourceProvider
//
//  Synopsis:   IAudioSourceProvider allows the caller (when Web Audio is connected)
//              to obtain uncompressed audio data (i.e. audio "frame server")
//
//------------------------------------------------------------------------------
[
    object,
    uuid(EBBAF249-AFC2-4582-91C6-B60DF2E84954),
    pointer_default(unique),
    local
]
interface IAudioSourceProvider : IUnknown
{
    HRESULT ProvideInput(
    [in, annotation("_In_")] DWORD dwSampleCount,
    [in, annotation("_Inout_")] DWORD* pdwChannelCount,
    [out, annotation("_Out_writes_opt_(dwSampleCount * (*pdwChannelCount))")] float* pInterleavedAudioData
    );
};

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineWebSupport
//
//  Synopsis:   IMFMediaEngineWebSupport extends the Media Engine to support the
//              latest W3C specifications.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(ba2743a1-07e0-48ef-84b6-9a2ed023ca6c),
    pointer_default(unique),
    local
]
interface IMFMediaEngineWebSupport : IUnknown
{
    BOOL ShouldDelayTheLoadEvent();

    HRESULT ConnectWebAudio(
        [in, annotation("_In_")] DWORD dwSampleRate,
        [out, annotation("_COM_Outptr_")] IAudioSourceProvider** ppSourceProvider
        );

    HRESULT DisconnectWebAudio();
};


////////////////////////////////////////////////////////////////////////////////
//
// Media Source Extension see: 
//
//  http://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html
//
////////////////////////////////////////////////////////////////////////////////


// Media Source Extension creation attributes

// MF_MSE_CALLBACK
// Data type:  IUnknown (IMFMediaSourceExtensionNotify)
// guid:fdd6dfaa-bd85-4af3-9e0f-a01d539d876a
cpp_quote("EXTERN_GUID(MF_MSE_CALLBACK,")
cpp_quote("0x9063a7c0, 0x42c5, 0x4ffd, 0xa8, 0xa8, 0x6f, 0xcf, 0x9e, 0xa3, 0xd0, 0x0c);")

// MF_MSE_ACTIVELIST_CALLBACK
// Data type:  IUnknown (IMFBufferListNotify)
// guid:fdd6dfaa-bd85-4af3-9e0f-a01d539d876a
cpp_quote("EXTERN_GUID(MF_MSE_ACTIVELIST_CALLBACK,")
cpp_quote("0x949bda0f, 0x4549, 0x46d5, 0xad, 0x7f, 0xb8, 0x46, 0xe1, 0xab, 0x16, 0x52);")

// MF_MSE_BUFFERLIST_CALLBACK
// Data type:  IUnknown (IMFBufferListNotify)
// guid:fdd6dfaa-bd85-4af3-9e0f-a01d539d876a
cpp_quote("EXTERN_GUID(MF_MSE_BUFFERLIST_CALLBACK,")
cpp_quote("0x42e669b0, 0xd60e, 0x4afb, 0xa8, 0x5b, 0xd8, 0xe5, 0xfe, 0x6b, 0xda, 0xb5);")

// MF_MSE_VP9_SUPPORT
// Data type:  UINT32 (MF_MSE_VP9_SUPPORT)
// guid:92D78429-D88B-4FF0-8322-803EFA6E9626
cpp_quote("EXTERN_GUID(MF_MSE_VP9_SUPPORT,")
cpp_quote("0x92d78429, 0xd88b, 0x4ff0, 0x83, 0x22, 0x80, 0x3e, 0xfa, 0x6e, 0x96, 0x26);")

// MF_MSE_OPUS_SUPPORT
// Data type:  UINT32 (MF_MSE_OPUS_SUPPORT)
// guid:4d224cc1-8cc4-48a3-a7a7-e4c16ce6388a
cpp_quote("EXTERN_GUID(MF_MSE_OPUS_SUPPORT,")
cpp_quote("0x4d224cc1, 0x8cc4, 0x48a3, 0xa7, 0xa7, 0xe4, 0xc1, 0x6c, 0xe6, 0x38, 0x8a);")

//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MSE_VP9_SUPPORT_TYPE 
//
//  Synopsis:   Controls VP9 support in MSE
//
//------------------------------------------------------------------------------
typedef enum MF_MSE_VP9_SUPPORT_TYPE
{
    MF_MSE_VP9_SUPPORT_DEFAULT = 0,
    MF_MSE_VP9_SUPPORT_ON = 1,
    MF_MSE_VP9_SUPPORT_OFF = 2,
} MF_MSE_VP9_SUPPORT_TYPE;

//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MSE_OPUS_SUPPORT_TYPE 
//
//  Synopsis:   Controls Opus support in MSE
//
//------------------------------------------------------------------------------
typedef enum MF_MSE_OPUS_SUPPORT_TYPE
{
    MF_MSE_OPUS_SUPPORT_ON = 0,
    MF_MSE_OPUS_SUPPORT_OFF = 1,
} MF_MSE_OPUS_SUPPORT_TYPE;


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaSourceExtensionNotify
//
//  Synopsis:   callback interfaces used to notify MSE clients about important
//              events within the MSE.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(a7901327-05dd-4469-a7b7-0e01979e361d),
    pointer_default(unique),
    local
]
interface IMFMediaSourceExtensionNotify : IUnknown
{
    void OnSourceOpen();
    void OnSourceEnded();
    void OnSourceClose();
};


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFBufferListNotify
//
//  Synopsis:   callback interfaces used to notify MSE buffer list clients
//              about important events associated with the buffer list.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(24cd47f7-81d8-4785-adb2-af697a963cd2),
    pointer_default(unique),
    local
]
interface IMFBufferListNotify : IUnknown
{
    void OnAddSourceBuffer();
    void OnRemoveSourceBuffer();
};


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFSourceBufferNotify
//
//  Synopsis:   callback interfaces used to notify MSE buffer list clients
//              about important events associated with the buffer list.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(87e47623-2ceb-45d6-9b88-d8520c4dcbbc),
    pointer_default(unique),
    local
]
interface IMFSourceBufferNotify : IUnknown
{        
    void OnUpdateStart();

    void OnAbort();
    void OnError([in, annotation("_In_")] HRESULT hr);
    void OnUpdate();

    void OnUpdateEnd();
};

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFSourceBuffer
//
//  Synopsis:   interface to a Source Buffer
//
//------------------------------------------------------------------------------
[
    object,
    uuid(e2cd3a4b-af25-4d3d-9110-da0e6f8ee877),
    pointer_default(unique),
    local
]
interface IMFSourceBuffer : IUnknown
{
    BOOL GetUpdating();

    HRESULT GetBuffered(
        [out, annotation("_Outptr_")] IMFMediaTimeRange** ppBuffered
        );

    double GetTimeStampOffset();
    HRESULT SetTimeStampOffset(
        [in, annotation("_In_")] double offset
        );

    double GetAppendWindowStart();
    HRESULT SetAppendWindowStart(
        [in, annotation("_In_")] double time
        );

    double GetAppendWindowEnd();
    HRESULT SetAppendWindowEnd(
        [in, annotation("_In_")] double time
        );

    HRESULT Append(
        [in, annotation("_In_reads_bytes_(len)")] const BYTE* pData,
        [in, annotation("_In_")] DWORD len
        );

    HRESULT AppendByteStream(
        [in, annotation("_In_")] IMFByteStream* pStream,
        [in, annotation("_In_opt_")] DWORDLONG* pMaxLen
        );

    HRESULT Abort();

    HRESULT Remove(
        [in, annotation("_In_")] double start,
        [in, annotation("_In_")] double end
        );
};

cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")
typedef enum MF_MSE_APPEND_MODE
{
    MF_MSE_APPEND_MODE_SEGMENTS = 0,
    MF_MSE_APPEND_MODE_SEQUENCE = 1,
} MF_MSE_APPEND_MODE;

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFSourceBufferAppendMode
//
//  Synopsis:   controls the Source Buffer's AppendMode attribute
//
//------------------------------------------------------------------------------
[
    object,
    uuid(19666fb4-babe-4c55-bc03-0a074da37e2a),
    pointer_default(unique),
    local
]
interface IMFSourceBufferAppendMode : IUnknown
{
    MF_MSE_APPEND_MODE GetAppendMode();
    HRESULT SetAppendMode(
        [in, annotation("_In_")] MF_MSE_APPEND_MODE mode
        );
}
cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFSourceBufferList
//
//  Synopsis:   SourceBufferList interface.
//              Events generated:
//                  onAddSourceBuffer
//                  onRemoveSourceBuffer
//
//------------------------------------------------------------------------------
[
    object,
    uuid(249981f8-8325-41f3-b80c-3b9e3aad0cbe),
    pointer_default(unique),
    local
]
interface IMFSourceBufferList : IUnknown
{
    DWORD GetLength();

    IMFSourceBuffer* GetSourceBuffer(
        [in, annotation("_In_")] DWORD index
        );
};


//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MSE_READY
//
//  Synopsis:   Defines different ready states of the Media Source Extension
//
//  See 
//------------------------------------------------------------------------------
typedef enum MF_MSE_READY
{
    MF_MSE_READY_CLOSED = 1,
    MF_MSE_READY_OPEN = 2,
    MF_MSE_READY_ENDED = 3,
} MF_MSE_READY;

//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MSE_ERROR
//
//  Synopsis:   Defines different error states of the Media Source Extension
//
//  See 
//------------------------------------------------------------------------------
typedef enum MF_MSE_ERROR
{
    MF_MSE_ERROR_NOERROR = 0,
    MF_MSE_ERROR_NETWORK = 1,
    MF_MSE_ERROR_DECODE = 2,
    MF_MSE_ERROR_UNKNOWN_ERROR = 3
} MF_MSE_ERROR;


//+-----------------------------------------------------------------------------
//
//  Class:      IMFMediaSourceExtension
//
//  Synopsis:   Media Source extension interface
//              events generated:
//                  onSourceOpen
//                  onSourceEnded
//                  onSourceClose
//
//------------------------------------------------------------------------------
[
    object,
    uuid(e467b94e-a713-4562-a802-816a42e9008a),
    pointer_default(unique),
    local
]
interface IMFMediaSourceExtension : IUnknown
{
    IMFSourceBufferList* GetSourceBuffers();
    IMFSourceBufferList* GetActiveSourceBuffers();

    // enum State { "closed", "open", "ended" };
    MF_MSE_READY GetReadyState();

    double GetDuration();
    HRESULT SetDuration(
        [in, annotation("_In_")] double duration
        );

    HRESULT AddSourceBuffer(
        [in, annotation("_In_")] BSTR type,
        [in, annotation("_In_")] IMFSourceBufferNotify* pNotify,
        [out, annotation("_Outptr_")] IMFSourceBuffer** ppSourceBuffer
        );

    HRESULT RemoveSourceBuffer(
        [in, annotation("_In_")] IMFSourceBuffer* pSourceBuffer
        );

    // enum EOSError { "network", "decode" };
    HRESULT SetEndOfStream(
        [in, annotation("_In_")] MF_MSE_ERROR error
        );

    BOOL IsTypeSupported(
        [in, annotation("_In_")] BSTR type
        );

    IMFSourceBuffer* GetSourceBuffer(
        [in, annotation("_In_")] DWORD dwStreamIndex
        );
};

//+-----------------------------------------------------------------------------
//
//  Class:      IMFMediaSourceExtensionLiveSeekableRange
//
//  Synopsis:   Media Source extension interface for setting and clearing
//              the live seekable range.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(5D1ABFD6-450A-4D92-9EFC-D6B6CBC1F4DA),
    pointer_default(unique),
    local
]
interface IMFMediaSourceExtensionLiveSeekableRange : IUnknown
{
    HRESULT SetLiveSeekableRange(
        [in, annotation("_In_")] double start,
        [in, annotation("_In_")] double end
        );

    HRESULT ClearLiveSeekableRange();
};

//////////////////////////////////////////////////////////////////////////////
//
//  Encrypted Media Extensions (EME)
//
//  See http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html
//
//////////////////////////////////////////////////////////////////////////////

interface IMFMediaEngineEME;
interface IMFMediaKeys;
interface IMFMediaKeySession;
interface IMFMediaKeySessionNotify;
interface IMFCdmSuspendNotify;

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineEME
//
//  Synopsis:   Extensions to the media engine for EME extensions
//
//------------------------------------------------------------------------------
[
    object,
    uuid(50dc93e4-ba4f-4275-ae66-83e836e57469),
    pointer_default(unique),
    local
]
interface IMFMediaEngineEME : IUnknown
{
    HRESULT get_Keys(
       [annotation("_COM_Outptr_result_maybenull_")] IMFMediaKeys **keys
       );
    HRESULT SetMediaKeys(
       [annotation("_In_opt_")] IMFMediaKeys *keys
       );
}

[
    object,
    uuid(654a6bb3-e1a3-424a-9908-53a43a0dfda0),
    pointer_default(unique),
    local
]
interface IMFMediaEngineSrcElementsEx : IMFMediaEngineSrcElements
{
    HRESULT AddElementEx(
        [annotation("_In_opt_")] BSTR pURL, 
        [annotation("_In_opt_")] BSTR pType, 
        [annotation("_In_opt_")] BSTR pMedia,
        [annotation("_In_opt_")] BSTR keySystem
        );
    HRESULT GetKeySystem(
        [annotation("_In_")] DWORD index,
        [annotation("_Outptr_result_maybenull_")] BSTR* pType
        );
}

// needKey event handler
// MF_MEDIA_ENGINE_NEEDKEY_CALLBACK
// Data type: IUnknown (IMFMediaEngineNeedKeyNotify)
// 7ea80843-b6e4-432c-8ea4-7848ffe4220e
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_NEEDKEY_CALLBACK,")
cpp_quote("0x7ea80843, 0xb6e4, 0x432c, 0x8e, 0xa4, 0x78, 0x48, 0xff, 0xe4, 0x22, 0x0e);")


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaKeysNotify
//
//  Synopsis:   Implement NeedKey
//
//------------------------------------------------------------------------------
[
    object,
    uuid(46a30204-a696-4b18-8804-246b8f031bb1),
    pointer_default(unique),
    local
]
interface IMFMediaEngineNeedKeyNotify : IUnknown
{
   void NeedKey(
      [annotation("_In_reads_bytes_opt_(cb)")] const BYTE *initData,
      [annotation("_In_")] DWORD cb
      );
}

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaKeys
//
//  Synopsis:   Media Keys interface for EME
//
//------------------------------------------------------------------------------
[
    object,
    uuid(5cb31c05-61ff-418f-afda-caaf41421a38),
    pointer_default(unique),
    local
]
interface IMFMediaKeys : IUnknown
{
   HRESULT CreateSession(
      [annotation("_In_opt_")] BSTR mimeType,
      [annotation("_In_reads_bytes_opt_(cb)")] const BYTE *initData,
      [annotation("_In_opt_")] DWORD cb,
      [annotation("_In_reads_bytes_opt_(cbCustomData)")] const BYTE *customData,
      [annotation("_In_")] DWORD cbCustomData,
      [annotation("_In_")] IMFMediaKeySessionNotify *notify,
      [annotation("_COM_Outptr_")] IMFMediaKeySession **ppSession
      );

   HRESULT get_KeySystem(
      [annotation("_COM_Outptr_")] BSTR *keySystem
      );

   HRESULT Shutdown();

   HRESULT GetSuspendNotify([annotation("_COM_Outptr_")] IMFCdmSuspendNotify **notify);
}


//  Errors - see MediaKeyError interface
typedef enum _MF_MEDIA_ENGINE_KEYERR {
    MF_MEDIAENGINE_KEYERR_UNKNOWN = 1,
    MF_MEDIAENGINE_KEYERR_CLIENT = 2,
    MF_MEDIAENGINE_KEYERR_SERVICE = 3,
    MF_MEDIAENGINE_KEYERR_OUTPUT = 4,
    MF_MEDIAENGINE_KEYERR_HARDWARECHANGE = 5,
    MF_MEDIAENGINE_KEYERR_DOMAIN = 6
} MF_MEDIA_ENGINE_KEYERR;


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaKeySession
//
//  Synopsis:   Media Key Session interface for EME
//
//------------------------------------------------------------------------------
[
    object,
    uuid(24fa67d5-d1d0-4dc5-995c-c0efdc191fb5),
    pointer_default(unique),
    local
]
interface IMFMediaKeySession : IUnknown
{
   //  Caller must turn this into a MediaKeyError object
   HRESULT GetError([annotation("_Out_")] USHORT *code, [annotation("_Out_")] DWORD *systemCode);

   HRESULT get_KeySystem(
      [annotation("_COM_Outptr_")] BSTR *keySystem
      );

   HRESULT get_SessionId(
      [annotation("_COM_Outptr_")] BSTR *sessionId
      );

   HRESULT Update([annotation("_In_reads_bytes_(cb)")] const BYTE *key, [annotation("_In_")] DWORD cb);

   HRESULT Close();
}

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaKeySessionNotify
//
//  Synopsis:   Events for MediaKeySession
//
//------------------------------------------------------------------------------
[
    object,
    uuid(6a0083f9-8947-4c1d-9ce0-cdee22b23135),
    pointer_default(unique),
    local
]
interface IMFMediaKeySessionNotify : IUnknown
{
   void KeyMessage(
      [annotation("_In_opt_")] BSTR destinationURL,
      [annotation("_In_reads_bytes_(cb)")] const BYTE *message,
      [annotation("_In_")] DWORD cb
      );

   void KeyAdded();

   //  Caller should turn data into MediaKeyError object
   void KeyError(
      [annotation("_In_")] USHORT code,
      [annotation("_In_")] DWORD systemCode
      );

}

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFCdmSuspendNotify
//
//  Synopsis:   Events for MediaKeySession
//
//------------------------------------------------------------------------------
[
    object,
    uuid(7a5645d2-43bd-47fd-87b7-dcd24cc7d692),
    pointer_default(unique)
]
interface IMFCdmSuspendNotify : IUnknown
{
   HRESULT Begin();
   HRESULT End();
}

//  End of Encrypted Media Extensions

//+-----------------------------------------------------------------------------
//
//  Interface:  MF_HDCP_STATUS
//
//  Synopsis:   HDCP Status values
//
//------------------------------------------------------------------------------
typedef enum _MF_HDCP_STATUS
{
    MF_HDCP_STATUS_ON = 0,
    MF_HDCP_STATUS_OFF = 1,
    MF_HDCP_STATUS_ON_WITH_TYPE_ENFORCEMENT = 2
} MF_HDCP_STATUS;

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFHDCPStatus
//
//  Synopsis:   HDCP Status set/get interface
//
//------------------------------------------------------------------------------
[
    object,
    uuid(DE400F54-5BF1-40CF-8964-0BEA136B1E3D),
    pointer_default(unique),
    local
]
interface IMFHDCPStatus : IUnknown
{
    HRESULT Query(
        [in, annotation("_Inout_")] MF_HDCP_STATUS *pStatus,
        [in, annotation("_Inout_")] BOOL *pfStatus
        );

    HRESULT Set(
        [in, annotation("_In_")] MF_HDCP_STATUS status
        );
};

//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MEDIA_ENGINE_OPM_STATUS
//
//  Synopsis:   Defines the status of OPM:
//              0. MF_MEDIA_ENGINE_OPM_NOT_REQUESTED: default status, used to 
//                     return the correct status when the content is unprotected
//              1. MF_MEDIA_ENGINE_OPM_ESTABLISHED: OPM succussfully established
//              2. MF_MEDIA_ENGINE_OPM_FAILED_VM: running in a VM
//              3. MF_MEDIA_ENGINE_OPM_FAILED_BDA: there is no graphics driver,
//                     system is using BDA
//              4. MF_MEDIA_ENGINE_OPM_FAILED_UNSIGNED_DRIVER: the graphics 
//                     driver is not PE signed, falling back to WARP
//              5. MF_MEDIA_ENGINE_OPM_FAILED: OPM failed for other reasons
//
//------------------------------------------------------------------------------
typedef enum MF_MEDIA_ENGINE_OPM_STATUS
{
    MF_MEDIA_ENGINE_OPM_NOT_REQUESTED = 0,
    MF_MEDIA_ENGINE_OPM_ESTABLISHED = 1,
    MF_MEDIA_ENGINE_OPM_FAILED_VM = 2,
    MF_MEDIA_ENGINE_OPM_FAILED_BDA = 3,
    MF_MEDIA_ENGINE_OPM_FAILED_UNSIGNED_DRIVER = 4,
    MF_MEDIA_ENGINE_OPM_FAILED = 5

} MF_MEDIA_ENGINE_OPM_STATUS;

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineOPMInfo
//
//  Synopsis:   Interface to get OPM information and constriction status
//
//------------------------------------------------------------------------------
[
    object,
    uuid(765763e6-6c01-4b01-bb0f-b829f60ed28c),
    pointer_default(unique),
    local
]
interface IMFMediaEngineOPMInfo : IUnknown
{
    HRESULT GetOPMInfo(
        [out, annotation("_Out_")] MF_MEDIA_ENGINE_OPM_STATUS* pStatus,
        [out, annotation("_Out_")] BOOL* pConstricted
        );
}


cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

cpp_quote("#ifndef NO_MEDIA_ENGINE_FACTORY")

#pragma region Application Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)")

//
// MFMediaEngine creation attributes
//

// MF_MEDIA_ENGINE_CALLBACK
// Data type: IUnknown (IMFMediaEngineNotify)
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_CALLBACK,")
cpp_quote("0xc60381b8,0x83a4,0x41f8,0xa3,0xd0,0xde,0x05,0x07,0x68,0x49,0xa9);")

// MF_MEDIA_ENGINE_DXGI_MANAGER
// Data type: IUnknown
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_DXGI_MANAGER,")
cpp_quote("0x065702da,0x1094,0x486d,0x86,0x17,0xee,0x7c,0xc4,0xee,0x46,0x48);" )

// MF_MEDIA_ENGINE_EXTENSION
// Data type: IUnknown (IMFMediaEngineExtension)
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_EXTENSION,")
cpp_quote("0x3109fd46,0x060d,0x4b62,0x8d,0xcf,0xfa,0xff,0x81,0x13,0x18,0xd2);")

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */")
#pragma endregion

#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")

// MF_MEDIA_ENGINE_PLAYBACK_HWND
// Data type: UINT64 
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_PLAYBACK_HWND,")
cpp_quote("0xd988879b,0x67c9,0x4d92,0xba,0xa7,0x6e,0xad,0xd4,0x46,0x03,0x9d);")

// MF_MEDIA_ENGINE_OPM_HWND - needed for protected content when there is no PLAYBACK_HWND
// Data type: UINT64 
// a0be8ee7-0572-4f2c-a801-2a151bd3e726
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_OPM_HWND,")
cpp_quote("0xa0be8ee7, 0x0572, 0x4f2c, 0xa8, 0x01, 0x2a, 0x15, 0x1b, 0xd3, 0xe7, 0x26);")

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

#pragma region Application Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)")

// MF_MEDIA_ENGINE_PLAYBACK_VISUAL
// Data type: IUnknown
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_PLAYBACK_VISUAL,")
cpp_quote("0x6debd26f,0x6ab9,0x4d7e,0xb0,0xee,0xc6,0x1a,0x73,0xff,0xad,0x15);")

// MF_MEDIA_ENGINE_COREWINDOW - needed for app state (and protected content when there is no PLAYBACK_HWND)
// Data type: IUnknown (ICoreWindow)
// fccae4dc-0b7f-41c2-9f96-4659948acddc
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_COREWINDOW,")
cpp_quote("0xfccae4dc, 0x0b7f, 0x41c2, 0x9f, 0x96, 0x46, 0x59, 0x94, 0x8a, 0xcd, 0xdc);")

// MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT
// Data type: UINT32 (actually a  DXGI_FORMAT type)
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT,")
cpp_quote("0x5066893c,0x8cf9,0x42bc,0x8b,0x8a,0x47,0x22,0x12,0xe5,0x27,0x26);")

// MF_MEDIA_ENGINE_CONTENT_PROTECTION_FLAGS
// Data type:  UINT32 - MF_MEDIA_ENGINE_PROTECTION_FLAGS
// guid:e0350223-5aaf-4d76-a7c3-06de70894db4
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_CONTENT_PROTECTION_FLAGS,")
cpp_quote("0xe0350223, 0x5aaf, 0x4d76, 0xa7, 0xc3, 0x06, 0xde, 0x70, 0x89, 0x4d, 0xb4);")

// MF_MEDIA_ENGINE_CONTENT_PROTECTION_MANAGER
// Data type:  IUnknown (IMFContentProtectionManager)
// guid:fdd6dfaa-bd85-4af3-9e0f-a01d539d876a
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_CONTENT_PROTECTION_MANAGER,")
cpp_quote("0xfdd6dfaa, 0xbd85, 0x4af3, 0x9e, 0x0f, 0xa0, 0x1d, 0x53, 0x9d, 0x87, 0x6a);")

// MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE
// Data type:  UINT32
// Values are from the ERole enumeration
// guid:d2cb93d1-116a-44f2-9385-f7d0fda2fb46
// Note: Sets the default audio device endpoint role, can be changed later
//       by calling IMFMediaEngineEx::SetAudioEndpointRole.
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_AUDIO_ENDPOINT_ROLE,")
cpp_quote("0xd2cb93d1, 0x116a, 0x44f2, 0x93, 0x85, 0xf7, 0xd0, 0xfd, 0xa2, 0xfb, 0x46);")

// MF_MEDIA_ENGINE_AUDIO_CATEGORY
// Data type:  UINT32
// guid:c8d4c51d-350e-41f2-ba46-faebbb0857f6
// Note: Sets the default audio category, can be changed later
//       by calling IMFMediaEngineEx::SetAudioStreamCategory.
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_AUDIO_CATEGORY,")
cpp_quote("0xc8d4c51d, 0x350e, 0x41f2, 0xba, 0x46, 0xfa, 0xeb, 0xbb, 0x08, 0x57, 0xf6);")

// MF_MEDIA_ENGINE_STREAM_CONTAINS_ALPHA_CHANNEL
// Data type:  VT_BOOL
// guid:5cbfaf44-d2b2-4cfb-80a7-d429c74c789d
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_STREAM_CONTAINS_ALPHA_CHANNEL,")
cpp_quote("0x5cbfaf44, 0xd2b2, 0x4cfb, 0x80, 0xa7, 0xd4, 0x29, 0xc7, 0x4c, 0x78, 0x9d);")

// MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
// Data type:  GUID
// guid:4e0212e2-e18f-41e1-95e5-c0e7e9235bc3
// Note: set this to one of the browser compatibility modes defined below.
//       when defining new modes, ensure that Data1 is greater than previous modes,
//       while leaving space for future modes to be defined
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE,")
cpp_quote("0x4e0212e2, 0xe18f, 0x41e1, 0x95, 0xe5, 0xc0, 0xe7, 0xe9, 0x23, 0x5b, 0xc3);")

// MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE9
// guid:052c2d39-40c0-4188-ab86-f828273b7522
// Note: set as the value for MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE9,")
cpp_quote("0x052c2d39, 0x40c0, 0x4188, 0xab, 0x86, 0xf8, 0x28, 0x27, 0x3b, 0x75, 0x22);")

// MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE10
// guid:11a47afd-6589-4124-b312-6158ec517fc3
// Note: set as the value for MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE10,")
cpp_quote("0x11a47afd, 0x6589, 0x4124, 0xb3, 0x12, 0x61, 0x58, 0xec, 0x51, 0x7f, 0xc3);")

// MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11
// guid:1cf1315f-ce3f-4035-9391-16142f775189
// Note: set as the value for MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11,")
cpp_quote("0x1cf1315f, 0xce3f, 0x4035, 0x93, 0x91, 0x16, 0x14, 0x2f, 0x77, 0x51, 0x89);")

cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD)")
// MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE
// guid:a6f3e465-3aca-442c-a3f0-ad6ddad839ae
// Note: set as the value for MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE,")
cpp_quote("0xa6f3e465, 0x3aca, 0x442c, 0xa3, 0xf0, 0xad, 0x6d, 0xda, 0xd8, 0x39, 0xae);")

// MF_MEDIA_ENGINE_COMPATIBILITY_MODE
// Data type:  GUID
// guid:3ef26ad4-dc54-45de-b9af-76c8-c66bfa8e
// Note: set this to one of the compatibility modes defined below.
//       when defining new modes, ensure that Data1 is greater than previous modes,
//       while leaving space for future modes to be defined
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_COMPATIBILITY_MODE,")
cpp_quote("0x3ef26ad4, 0xdc54, 0x45de, 0xb9, 0xaf, 0x76, 0xc8, 0xc6, 0x6b, 0xfa, 0x8e);")

// MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WWA_EDGE
// guid:15b29098-9f01-4e4d-b65a-c06c-6c89da2a
// Note: set as the value for MF_MEDIA_ENGINE_COMPATIBILITY_MODE
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WWA_EDGE,")
cpp_quote("0x15b29098, 0x9f01, 0x4e4d, 0xb6, 0x5a, 0xc0, 0x6c, 0x6c, 0x89, 0xda, 0x2a);")

// MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WIN10
// guid:5b25e089-6ca7-4139-a2cb-fcaa-b39552a3
// Note: set as the value for MF_MEDIA_ENGINE_COMPATIBILITY_MODE
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_COMPATIBILITY_MODE_WIN10,")
cpp_quote("0x5b25e089, 0x6ca7, 0x4139, 0xa2, 0xcb, 0xfc, 0xaa, 0xb3, 0x95, 0x52, 0xa3);")
cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

// MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE
// Data type: IUnknown
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_SOURCE_RESOLVER_CONFIG_STORE,")
cpp_quote("0x0ac0c497, 0xb3c4, 0x48c9, 0x9c, 0xde, 0xbb, 0x8c, 0xa2, 0x44, 0x2c, 0xa3);")

// MF_MEDIA_ENGINE_TRACK_ID
// Data type: UINT32
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_TRACK_ID,")
cpp_quote("0x65bea312, 0x4043, 0x4815, 0x8e, 0xab, 0x44, 0xdc, 0xe2, 0xef, 0x8f, 0x2a);")

// MF_MEDIA_ENGINE_TELEMETRY_APPLICATION_ID
// Data type: GUID
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_TELEMETRY_APPLICATION_ID,")
cpp_quote("0x1e7b273b, 0xa7e4, 0x402a, 0x8f, 0x51, 0xc4, 0x8e, 0x88, 0xa2, 0xca, 0xbc);")

// MF_MEDIA_ENGINE_SYNCHRONOUS_CLOSE
// Data type: UINT32 (treat as BOOL)
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_SYNCHRONOUS_CLOSE,")
cpp_quote("0xc3c2e12f, 0x7e0e, 0x4e43, 0xb9, 0x1c, 0xdc, 0x99, 0x2c, 0xcd, 0xfa, 0x5e);")

// MF_MEDIA_ENGINE_MEDIA_PLAYER_MODE
// Data type: UINT32 (treat as BOOL)
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_MEDIA_PLAYER_MODE,")
cpp_quote("0x3ddd8d45, 0x5aa1, 0x4112, 0x82, 0xe5, 0x36, 0xf6, 0xa2, 0x19, 0x7e, 0x6e);")

typedef enum MF_MEDIA_ENGINE_CREATEFLAGS
{
    MF_MEDIA_ENGINE_AUDIOONLY                   = 0x0001,
    MF_MEDIA_ENGINE_WAITFORSTABLE_STATE         = 0x0002,
    MF_MEDIA_ENGINE_FORCEMUTE                   = 0x0004,
    MF_MEDIA_ENGINE_REAL_TIME_MODE              = 0x0008,   // sets the default real time mode, can be changed later by calling IMFMediaEngineEx::SetRealTimeMode
    MF_MEDIA_ENGINE_DISABLE_LOCAL_PLUGINS       = 0x0010,
    MF_MEDIA_ENGINE_CREATEFLAGS_MASK            = 0x001F,
} MF_MEDIA_ENGINE_CREATEFLAGS;

typedef enum MF_MEDIA_ENGINE_PROTECTION_FLAGS
{
   MF_MEDIA_ENGINE_ENABLE_PROTECTED_CONTENT = 1,
   MF_MEDIA_ENGINE_USE_PMP_FOR_ALL_CONTENT = 2,   //  Testing
   MF_MEDIA_ENGINE_USE_UNPROTECTED_PMP = 4        //  Testing

} MF_MEDIA_ENGINE_PROTECTION_FLAGS;


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineClassFactory
//
//  Synopsis:   Allows client applications to create a new instance of the 
//              Media Engine.  CoInitialize and MFStartup must be called 
//              prior to using this interface.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(4D645ACE-26AA-4688-9BE1-DF3516990B93),
    pointer_default(unique),
    local
]
interface IMFMediaEngineClassFactory : IUnknown
{
    HRESULT CreateInstance( 
        [in, annotation("_In_")] DWORD dwFlags,
        [in, annotation("_In_")] IMFAttributes* pAttr,
        [out, annotation("_Outptr_")] IMFMediaEngine** ppPlayer
        );

    HRESULT CreateTimeRange(
        [out, annotation("_Outptr_")] IMFMediaTimeRange** ppTimeRange
        );

    HRESULT CreateError(
        [out, annotation("_Outptr_")] IMFMediaError** ppError
        );
}

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */")
#pragma endregion

#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")

[
    object,
    uuid(c56156c6-ea5b-48a5-9df8-fbe035d0929e),
    pointer_default(unique),
    local
]
interface IMFMediaEngineClassFactoryEx : IMFMediaEngineClassFactory
{
    HRESULT CreateMediaSourceExtension( 
        [in, annotation("_In_")] DWORD dwFlags,
        [in, annotation("_In_")] IMFAttributes* pAttr,
        [out, annotation("_COM_Outptr_")] IMFMediaSourceExtension** ppMSE
        );

    HRESULT CreateMediaKeys(
        [annotation("_In_")] BSTR keySystem,
        [annotation("_In_opt_")] BSTR cdmStorePath,
        [annotation("_COM_Outptr_")] IMFMediaKeys **ppKeys
        );

    HRESULT IsTypeSupported(
        [annotation("_In_opt_")] BSTR type,
        [annotation("_In_")] BSTR keySystem,
        [annotation("_Out_")] BOOL* isSupported
        );
}

[
    object,
    uuid(09083cef-867f-4bf6-8776-dee3a7b42fca),
    pointer_default(unique),
    local
]
interface IMFMediaEngineClassFactory2 : IUnknown
{
    HRESULT CreateMediaKeys2(
        [annotation("_In_")] BSTR keySystem,
        [annotation("_In_")] BSTR defaultCdmStorePath,
        [annotation("_In_opt_")] BSTR inprivateCdmStorePath,
        [annotation("_COM_Outptr_")] IMFMediaKeys **ppKeys
        );
}

[
    object,
    uuid(332EC562-3758-468D-A784-E38F23552128),
    pointer_default(unique),
    local
]
interface IMFExtendedDRMTypeSupport : IUnknown
{
    HRESULT IsTypeSupportedEx(
        [annotation("_In_opt_")] BSTR type,
        [annotation("_In_")] BSTR keySystem,
        [annotation("_Out_")] MF_MEDIA_ENGINE_CANPLAY * pAnswer
        );
}

[
    object,
    uuid(a724b056-1b2e-4642-a6f3-db9420c52908),
    pointer_default(unique),
    local
]
interface IMFMediaEngineSupportsSourceTransfer : IUnknown
{
    HRESULT ShouldTransferSource([out, annotation("_Out_")] BOOL* pfShouldTransfer);

    HRESULT DetachMediaSource(
        [out, annotation("_COM_Outptr_")] IMFByteStream** ppByteStream,
        [out, annotation("_COM_Outptr_")] IMFMediaSource** ppMediaSource,
        [out, annotation("_COM_Outptr_")] IMFMediaSourceExtension** ppMSE
        );

    HRESULT AttachMediaSource(
        [in, annotation("_In_opt_")] IMFByteStream* pByteStream,
        [in, annotation("_In_")] IMFMediaSource* pMediaSource,
        [in, annotation("_In_opt_")] IMFMediaSourceExtension* pMSE
        );
}

//TODO_NTDDI_WIN10_TH2
cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

// <summary>
// This interface is implemented by objects that implement IMFMediaEngine.
// It transfers the state of one IMFMediaEngine object to another.
// It is used by the Edge browser for transferring the state from an IMFMediaEngine
// used for local playback to a Sharing Engine (IMFMediaSharingEngine), and vice versa.
// </summary>
[
     object,
     uuid(24230452-fe54-40cc-94f3-fcc394c340d6),
     pointer_default(unique),
     local
]
interface IMFMediaEngineTransferSource : IUnknown
{
    HRESULT TransferSourceToMediaEngine([in, annotation("_In_")] IMFMediaEngine* destination);
}

cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

#pragma region Application Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)")

/////////////////////////////////////////////////////////////////////////////
// CLSID_MFMediaEngineClassFactory
// Data type: GUID
// CLSID for creating the Media Engine class factory.
//
// {B44392DA-499B-446b-A4CB-005FEAD0E6D5}
cpp_quote("EXTERN_GUID(CLSID_MFMediaEngineClassFactory,")
cpp_quote("0xb44392da, 0x499b, 0x446b, 0xa4, 0xcb, 0x0, 0x5f, 0xea, 0xd0, 0xe6, 0xd5);")

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */")
#pragma endregion

cpp_quote("#endif // (NO_MEDIA_ENGINE_FACTORY) ")

cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")

//////////////////////////////////////////////////////////////////////////////
//
//  Timed Text
//
//////////////////////////////////////////////////////////////////////////////

//
// MFMediaEngine services
//

// MF_MEDIA_ENGINE_TIMEDTEXT
// guid: {805EA411-92E0-4E59-9B6E-5C7D7915E64F}
// Data type: IMFTimedText
// Application can interact with Timed Text component after retrieving it from
// Media Engine using IMFGetService interface and passing MF_MEDIA_ENGINE_TIMEDTEXT
// as a service id.
cpp_quote("EXTERN_GUID( MF_MEDIA_ENGINE_TIMEDTEXT, 0x805ea411, 0x92e0, 0x4e59, 0x9b, 0x6e, 0x5c, 0x7d, 0x79, 0x15, 0xe6, 0x4f);")

typedef enum MF_TIMED_TEXT_TRACK_KIND
{
    MF_TIMED_TEXT_TRACK_KIND_UNKNOWN = 0,
    MF_TIMED_TEXT_TRACK_KIND_SUBTITLES = 1,
    MF_TIMED_TEXT_TRACK_KIND_CAPTIONS = 2,
    MF_TIMED_TEXT_TRACK_KIND_METADATA = 3,
} MF_TIMED_TEXT_TRACK_KIND;

typedef enum MF_TIMED_TEXT_UNIT_TYPE
{
    MF_TIMED_TEXT_UNIT_TYPE_PIXELS = 0,
    MF_TIMED_TEXT_UNIT_TYPE_PERCENTAGE = 1
} MF_TIMED_TEXT_UNIT_TYPE;

typedef enum MF_TIMED_TEXT_FONT_STYLE
{
    MF_TIMED_TEXT_FONT_STYLE_NORMAL = 0,
    MF_TIMED_TEXT_FONT_STYLE_OBLIQUE = 1,
    MF_TIMED_TEXT_FONT_STYLE_ITALIC = 2
} MF_TIMED_TEXT_FONT_STYLE;

typedef enum MF_TIMED_TEXT_ALIGNMENT
{
    MF_TIMED_TEXT_ALIGNMENT_START = 0,
    MF_TIMED_TEXT_ALIGNMENT_END = 1,
    MF_TIMED_TEXT_ALIGNMENT_CENTER = 2,
} MF_TIMED_TEXT_ALIGNMENT;

typedef enum MF_TIMED_TEXT_DISPLAY_ALIGNMENT
{
    MF_TIMED_TEXT_DISPLAY_ALIGNMENT_BEFORE = 0,
    MF_TIMED_TEXT_DISPLAY_ALIGNMENT_AFTER = 1,
    MF_TIMED_TEXT_DISPLAY_ALIGNMENT_CENTER = 2,
} MF_TIMED_TEXT_DISPLAY_ALIGNMENT;

typedef enum MF_TIMED_TEXT_DECORATION
{
    MF_TIMED_TEXT_DECORATION_NONE = 0,
    MF_TIMED_TEXT_DECORATION_UNDERLINE = 1,
    MF_TIMED_TEXT_DECORATION_LINE_THROUGH = 2,
    MF_TIMED_TEXT_DECORATION_OVERLINE = 4
} MF_TIMED_TEXT_DECORATION;

typedef enum MF_TIMED_TEXT_WRITING_MODE
{
    MF_TIMED_TEXT_WRITING_MODE_LRTB = 0,
    MF_TIMED_TEXT_WRITING_MODE_RLTB = 1,
    MF_TIMED_TEXT_WRITING_MODE_TBRL = 2,
    MF_TIMED_TEXT_WRITING_MODE_TBLR = 3,
    MF_TIMED_TEXT_WRITING_MODE_LR = 4,
    MF_TIMED_TEXT_WRITING_MODE_RL = 5,
    MF_TIMED_TEXT_WRITING_MODE_TB = 6
} MF_TIMED_TEXT_WRITING_MODE;

typedef enum MF_TIMED_TEXT_SCROLL_MODE
{
    MF_TIMED_TEXT_SCROLL_MODE_POP_ON = 0,
    MF_TIMED_TEXT_SCROLL_MODE_ROLL_UP = 1
} MF_TIMED_TEXT_SCROLL_MODE;

typedef enum MF_TIMED_TEXT_ERROR_CODE
{
    // No error
    MF_TIMED_TEXT_ERROR_CODE_NOERROR = 0,
    // Fatal, non-continuable error, the state of the component will
    // be reset after that.
    MF_TIMED_TEXT_ERROR_CODE_FATAL = 1,
    // Data format error - continuable
    MF_TIMED_TEXT_ERROR_CODE_DATA_FORMAT = 2,
    // Network error - continuable
    MF_TIMED_TEXT_ERROR_CODE_NETWORK = 3,
    // Internal error, involved data sources will be disabled
    // but the error is continuable
    MF_TIMED_TEXT_ERROR_CODE_INTERNAL = 4
} MF_TIMED_TEXT_ERROR_CODE;

typedef enum MF_TIMED_TEXT_CUE_EVENT
{
    // Cue has become active
    MF_TIMED_TEXT_CUE_EVENT_ACTIVE,
    // Cue has become inactive
    MF_TIMED_TEXT_CUE_EVENT_INACTIVE,
    // All cues has been deactivated
    MF_TIMED_TEXT_CUE_EVENT_CLEAR
} MF_TIMED_TEXT_CUE_EVENT;

typedef enum MF_TIMED_TEXT_TRACK_READY_STATE
{
    // Loading track cues has not been started yet.
    MF_TIMED_TEXT_TRACK_READY_STATE_NONE,
    // Track cues are being loaded.
    MF_TIMED_TEXT_TRACK_READY_STATE_LOADING,
    // Track cues are loaded and ready.
    MF_TIMED_TEXT_TRACK_READY_STATE_LOADED,
    // Track error occurred.
    MF_TIMED_TEXT_TRACK_READY_STATE_ERROR,
} MF_TIMED_TEXT_TRACK_READY_STATE;

typedef enum MF_TIMED_TEXT_RUBY_POSITION
{
    MF_TIMED_TEXT_RUBY_POSITION_BEFORE = 0,
    MF_TIMED_TEXT_RUBY_POSITION_AFTER = 1,
    MF_TIMED_TEXT_RUBY_POSITION_OUTSIDE = 2,
} MF_TIMED_TEXT_RUBY_POSITION;

typedef enum MF_TIMED_TEXT_RUBY_ALIGN
{
    MF_TIMED_TEXT_RUBY_ALIGN_CENTER = 0,
    MF_TIMED_TEXT_RUBY_ALIGN_START = 1,
    MF_TIMED_TEXT_RUBY_ALIGN_END = 2,
    MF_TIMED_TEXT_RUBY_ALIGN_SPACEAROUND = 3,
    MF_TIMED_TEXT_RUBY_ALIGN_SPACEBETWEEN = 4,
    MF_TIMED_TEXT_RUBY_ALIGN_WITHBASE = 5
} MF_TIMED_TEXT_RUBY_ALIGN;

typedef enum MF_TIMED_TEXT_RUBY_RESERVE
{
    MF_TIMED_TEXT_RUBY_RESERVE_NONE = 0,
    MF_TIMED_TEXT_RUBY_RESERVE_BEFORE = 1,
    MF_TIMED_TEXT_RUBY_RESERVE_AFTER = 2,
    MF_TIMED_TEXT_RUBY_RESERVE_BOTH = 3,
    MF_TIMED_TEXT_RUBY_RESERVE_OUTSIDE = 4
} MF_TIMED_TEXT_RUBY_RESERVE;

typedef enum MF_TIMED_TEXT_BOUTEN_TYPE
{
    MF_TIMED_TEXT_BOUTEN_TYPE_NONE = 0,
    MF_TIMED_TEXT_BOUTEN_TYPE_AUTO = 1,
    MF_TIMED_TEXT_BOUTEN_TYPE_FILLEDCIRCLE = 2,
    MF_TIMED_TEXT_BOUTEN_TYPE_OPENCIRCLE = 3,
    MF_TIMED_TEXT_BOUTEN_TYPE_FILLEDDOT = 4,
    MF_TIMED_TEXT_BOUTEN_TYPE_OPENDOT = 5,
    MF_TIMED_TEXT_BOUTEN_TYPE_FILLEDSESAME = 6,
    MF_TIMED_TEXT_BOUTEN_TYPE_OPENSESAME = 7
} 	MF_TIMED_TEXT_BOUTEN_TYPE;

typedef enum MF_TIMED_TEXT_BOUTEN_POSITION
{
    MF_TIMED_TEXT_BOUTEN_POSITION_BEFORE = 0,
    MF_TIMED_TEXT_BOUTEN_POSITION_AFTER = 1,
    MF_TIMED_TEXT_BOUTEN_POSITION_OUTSIDE = 2
} 	MF_TIMED_TEXT_BOUTEN_POSITION;


interface IMFTimedText;
interface IMFTimedTextNotify;
interface IMFTimedTextTrack;
interface IMFTimedTextTrackList;
interface IMFTimedTextCue;
interface IMFTimedTextCueList;
interface IMFTimedTextBinary;
interface IMFTimedTextRegion;
interface IMFTimedTextStyle;
interface IMFTimedTextFormattedText;

[
    object,
    uuid(1f2a94c9-a3df-430d-9d0f-acd85ddc29af),
    pointer_default(unique),
    local
]
interface IMFTimedText : IUnknown
{
    HRESULT RegisterNotifications(
        [in, annotation("_In_opt_")] IMFTimedTextNotify* notify
        );

    HRESULT SelectTrack(
        [in, annotation("_In_")] DWORD trackId,
        [in, annotation("_In_")] BOOL selected
        );

    HRESULT AddDataSource(
        [in, annotation("_In_")] IMFByteStream* byteStream,
        [in, annotation("_In_opt_")] LPCWSTR label,
        [in, annotation("_In_opt_")] LPCWSTR language,
        [in, annotation("_In_")] MF_TIMED_TEXT_TRACK_KIND kind,
        [in, annotation("_In_")] BOOL isDefault,
        [in, annotation("_Out_")] DWORD* trackId
        );

    HRESULT AddDataSourceFromUrl(
        [in, annotation("_In_")] LPCWSTR url,
        [in, annotation("_In_opt_")] LPCWSTR label,
        [in, annotation("_In_opt_")] LPCWSTR language,        
        [in, annotation("_In_")] MF_TIMED_TEXT_TRACK_KIND kind,
        [in, annotation("_In_")] BOOL isDefault,
        [in, annotation("_Out_")] DWORD* trackId
        );

    HRESULT AddTrack(
        [in, annotation("_In_opt_")] LPCWSTR label,
        [in, annotation("_In_opt_")] LPCWSTR language,
        [in, annotation("_In_")] MF_TIMED_TEXT_TRACK_KIND kind,
        [out, annotation("_COM_Outptr_")] IMFTimedTextTrack** track
        );

    HRESULT RemoveTrack(
        [in, annotation("_In_")] IMFTimedTextTrack* track
        );

    HRESULT GetCueTimeOffset(
        [out, annotation("_Out_")] double* offset
        );

    HRESULT SetCueTimeOffset(
        [in, annotation("_In_")] double offset
        );

    HRESULT GetTracks(
        [out, annotation("_COM_Outptr_")] IMFTimedTextTrackList** tracks
        );

    HRESULT GetActiveTracks(
        [out, annotation("_COM_Outptr_")] IMFTimedTextTrackList** activeTracks
        );

    HRESULT GetTextTracks(
        [out, annotation("_COM_Outptr_")] IMFTimedTextTrackList** textTracks
        );

    HRESULT GetMetadataTracks(
        [out, annotation("_COM_Outptr_")] IMFTimedTextTrackList** metadataTracks
        );

    HRESULT SetInBandEnabled([in, annotation("_In_")] BOOL enabled);

    BOOL IsInBandEnabled();
}

[
    object,
    uuid(df6b87b6-ce12-45db-aba7-432fe054e57d),
    pointer_default(unique),
    local
]
interface IMFTimedTextNotify : IUnknown
{
    void TrackAdded(
        [in, annotation("_In_")] DWORD trackId
        );

    void TrackRemoved(
        [in, annotation("_In_")] DWORD trackId
        );

    void TrackSelected(
        [in, annotation("_In_")] DWORD trackId,
        [in, annotation("_In_")] BOOL selected
        );

    void TrackReadyStateChanged(
        [in, annotation("_In_")] DWORD trackId
        );

    void Error(
        [in, annotation("_In_")] MF_TIMED_TEXT_ERROR_CODE errorCode,
        [in, annotation("_In_")] HRESULT extendedErrorCode,
        [in, annotation("_In_")] DWORD sourceTrackId
        );

    void Cue(
        [in, annotation("_In_")] MF_TIMED_TEXT_CUE_EVENT cueEvent,
        [in, annotation("_In_")] double currentTime,
        [in, annotation("_In_opt_")] IMFTimedTextCue *cue
        );

    void Reset();
}

[
    object,
    uuid(8822c32d-654e-4233-bf21-d7f2e67d30d4),
    pointer_default(unique),
    local
]
interface IMFTimedTextTrack : IUnknown
{
    DWORD GetId();

    HRESULT GetLabel(
        [out, annotation("_Outptr_")] LPWSTR* label
        );

    HRESULT SetLabel(
        [in, annotation("_In_")] LPCWSTR label
        );

    HRESULT GetLanguage(
        [out, annotation("_Outptr_")] LPWSTR* language
        );

    MF_TIMED_TEXT_TRACK_KIND GetTrackKind();

    BOOL IsInBand();

    HRESULT GetInBandMetadataTrackDispatchType(
        [out, annotation("_Outptr_")] LPWSTR* dispatchType
        );

    BOOL IsActive();

    MF_TIMED_TEXT_ERROR_CODE GetErrorCode();

    HRESULT GetExtendedErrorCode();

    HRESULT GetDataFormat([out, annotation("_Out_")] GUID* format);

    MF_TIMED_TEXT_TRACK_READY_STATE GetReadyState();

    HRESULT GetCueList([out, annotation("_COM_Outptr_")] IMFTimedTextCueList** cues);
}

[
    object,
    uuid(23ff334c-442c-445f-bccc-edc438aa11e2),
    pointer_default(unique),
    local
]
interface IMFTimedTextTrackList : IUnknown
{
    DWORD GetLength();

    HRESULT GetTrack(
        [in, annotation("_In_")] DWORD index,
        [out, annotation("_COM_Outptr_")] IMFTimedTextTrack **track
        );

    HRESULT GetTrackById(
        [in, annotation("_In_")] DWORD trackId,
        [out, annotation("_COM_Outptr_")] IMFTimedTextTrack **track
        );
}

[
    object,
    uuid(1e560447-9a2b-43e1-a94c-b0aaabfbfbc9),
    pointer_default(unique),
    local
]
interface IMFTimedTextCue : IUnknown
{
    DWORD GetId();

    HRESULT GetOriginalId(
        [out, annotation("_Outptr_")] LPWSTR* originalId
        );

    MF_TIMED_TEXT_TRACK_KIND GetCueKind();

    double GetStartTime();

    double GetDuration();

    DWORD GetTrackId();

    HRESULT GetData(
        [out, annotation("_COM_Outptr_result_maybenull_")] IMFTimedTextBinary **data
        );

    HRESULT GetRegion(
        [out, annotation("_COM_Outptr_result_maybenull_")] IMFTimedTextRegion **region
        );

    HRESULT GetStyle(
        [out, annotation("_COM_Outptr_result_maybenull_")] IMFTimedTextStyle **style
        );

    DWORD GetLineCount();

    HRESULT GetLine(
        [in, annotation("_In_")] DWORD index,
        [out, annotation("_COM_Outptr_")] IMFTimedTextFormattedText **line
        );
}

[
    object,
    uuid(e13af3c1-4d47-4354-b1f5-e83ae0ecae60),
    pointer_default(unique),
    local
]
interface IMFTimedTextFormattedText : IUnknown
{
    HRESULT GetText(
        [out, annotation("_Outptr_result_maybenull_")] LPWSTR *text
        );

    DWORD GetSubformattingCount();

    HRESULT GetSubformatting(
        [in, annotation("_In_")] DWORD index,
        [out, annotation("_Out_")] DWORD *firstChar,
        [out, annotation("_Out_")] DWORD *charLength,
        [out, annotation("_COM_Outptr_result_maybenull_")] IMFTimedTextStyle **style
        );
}

[
    object,
    uuid(09b2455d-b834-4f01-a347-9052e21c450e),
    pointer_default(unique),
    local
]
interface IMFTimedTextStyle : IUnknown
{
    HRESULT GetName(
        [out, annotation("_Outptr_")] LPWSTR *name
        );

    BOOL IsExternal();

    HRESULT GetFontFamily(
        [out, annotation("_Outptr_")] LPWSTR *fontFamily
        );

    HRESULT GetFontSize(
        [out, annotation("_Out_")] double *fontSize,
        [out, annotation("_Out_")] MF_TIMED_TEXT_UNIT_TYPE *unitType
        );

    HRESULT GetColor(
        [out, annotation("_Out_")] MFARGB *color
        );

    HRESULT GetBackgroundColor(
        [out, annotation("_Out_")] MFARGB *bgColor
        );

    HRESULT GetShowBackgroundAlways(
        [out, annotation("_Out_")] BOOL *showBackgroundAlways
        );

    HRESULT GetFontStyle(
        [out, annotation("_Out_")] MF_TIMED_TEXT_FONT_STYLE *fontStyle
        );

    HRESULT GetBold(
        [out, annotation("_Out_")] BOOL *bold
        );

    HRESULT GetRightToLeft(
        [out, annotation("_Out_")] BOOL *rightToLeft
        );

    HRESULT GetTextAlignment(
        [out, annotation("_Out_")] MF_TIMED_TEXT_ALIGNMENT *textAlign
        );

    HRESULT GetTextDecoration(
        [out, annotation("_Out_")] DWORD *textDecoration
        );

    HRESULT GetTextOutline(
        [out, annotation("_Out_")] MFARGB *color,
        [out, annotation("_Out_")] double *thickness,
        [out, annotation("_Out_")] double *blurRadius,
        [out, annotation("_Out_")] MF_TIMED_TEXT_UNIT_TYPE *unitType
        );
}

[
    object,
    uuid(c8d22afc-bc47-4bdf-9b04-787e49ce3f58),
    pointer_default(unique),
    local
]
interface IMFTimedTextRegion : IUnknown
{
    HRESULT GetName(
        [out, annotation("_Outptr_")] LPWSTR *name
        );

    HRESULT GetPosition(
        [out, annotation("_Out_")] double *pX,
        [out, annotation("_Out_")] double *pY,
        [out, annotation("_Out_")] MF_TIMED_TEXT_UNIT_TYPE *unitType
        );

    HRESULT GetExtent(
        [out, annotation("_Out_")] double *pWidth,
        [out, annotation("_Out_")] double *pHeight,
        [out, annotation("_Out_")] MF_TIMED_TEXT_UNIT_TYPE *unitType
        );

    HRESULT GetBackgroundColor(
        [out, annotation("_Out_")] MFARGB *bgColor
        );

    HRESULT GetWritingMode(
        [out, annotation("_Out_")] MF_TIMED_TEXT_WRITING_MODE *writingMode
        );

    HRESULT GetDisplayAlignment(
        [out, annotation("_Out_")] MF_TIMED_TEXT_DISPLAY_ALIGNMENT *displayAlign
        );

    HRESULT GetLineHeight(
        [out, annotation("_Out_")] double *pLineHeight,
        [out, annotation("_Out_")] MF_TIMED_TEXT_UNIT_TYPE *unitType
        );

    HRESULT GetClipOverflow(
        [out, annotation("_Out_")] BOOL *clipOverflow
        );

    HRESULT GetPadding(
        [out, annotation("_Out_")] double *before,
        [out, annotation("_Out_")] double *start,
        [out, annotation("_Out_")] double *after,
        [out, annotation("_Out_")] double *end,
        [out, annotation("_Out_")] MF_TIMED_TEXT_UNIT_TYPE *unitType
        );

    HRESULT GetWrap(
        [out, annotation("_Out_")] BOOL *wrap
        );

    HRESULT GetZIndex(
        [out, annotation("_Out_")] INT32 *zIndex
        );

    HRESULT GetScrollMode(
        [out, annotation("_Out_")] MF_TIMED_TEXT_SCROLL_MODE *scrollMode
        );
}

[
    object,
    uuid(4ae3a412-0545-43c4-bf6f-6b97a5c6c432),
    pointer_default(unique),
    local
]
interface IMFTimedTextBinary : IUnknown
{
    HRESULT GetData(
        [out, annotation("_Outptr_result_bytebuffer_(*length)")] const BYTE **data,
        [out, annotation("_Out_")] DWORD *length
        );
}

[
    object,
    uuid(ad128745-211b-40a0-9981-fe65f166d0fd),
    pointer_default(unique),
    local
]
interface IMFTimedTextCueList : IUnknown
{
    DWORD GetLength();

    HRESULT GetCueByIndex(
        [in, annotation("_In_")] DWORD index,
        [out, annotation("_COM_Outptr_")] IMFTimedTextCue** cue
        );

    HRESULT GetCueById(
        [in, annotation("_In_")] DWORD id,
        [out, annotation("_COM_Outptr_")] IMFTimedTextCue** cue
        );

    HRESULT GetCueByOriginalId(
        [in, annotation("_In_")] LPCWSTR originalId,
        [out, annotation("_COM_Outptr_")] IMFTimedTextCue** cue
        );

    HRESULT AddTextCue(
        [in, annotation("_In_")] double start,
        [in, annotation("_In_")] double duration,
        [in, annotation("_In_")] LPCWSTR text,
        [out, annotation("_COM_Outptr_opt_")] IMFTimedTextCue** cue
        );

    HRESULT AddDataCue(
        [in, annotation("_In_")] double start,
        [in, annotation("_In_")] double duration,
        [in, annotation("_In_reads_bytes_(dataSize)")] const BYTE* data,
        [in, annotation("_In_")] DWORD dataSize,
        [out, annotation("_COM_Outptr_opt_")] IMFTimedTextCue** cue
        );

    HRESULT RemoveCue(
        [in, annotation("_In_")] IMFTimedTextCue* cue
        );
}

[
    object,
    uuid(76c6a6f5-4955-4de5-b27b-14b734cc14b4),
    pointer_default(unique),
    local
]
interface IMFTimedTextRuby : IUnknown
{
    HRESULT GetRubyText(
        [out, annotation("_Outptr_")] LPWSTR* rubyText
    );
    HRESULT GetRubyPosition(
        [out, annotation("_Out_")] MF_TIMED_TEXT_RUBY_POSITION* value
    );
    HRESULT GetRubyAlign(
        [out, annotation("_Out_")] MF_TIMED_TEXT_RUBY_ALIGN* value
    );
    HRESULT GetRubyReserve(
        [out, annotation("_Out_")] MF_TIMED_TEXT_RUBY_RESERVE* value
    );
}

[
    object,
    uuid(3c5f3e8a-90c0-464e-8136-898d2975f847),
    pointer_default(unique),
    local
]
interface IMFTimedTextBouten : IUnknown
{
    HRESULT GetBoutenType(
        [out, annotation("_Out_")] MF_TIMED_TEXT_BOUTEN_TYPE* value
    );
    HRESULT GetBoutenColor(
        [out, annotation("_Out_")] MFARGB* value
    );
    HRESULT GetBoutenPosition(
        [out, annotation("_Out_")] MF_TIMED_TEXT_BOUTEN_POSITION* value
    );
}

[
    object,
    uuid(db639199-c809-4c89-bfca-d0bbb9729d6e),
    pointer_default(unique),
    local
]
interface IMFTimedTextStyle2 : IUnknown
{
    HRESULT GetRuby(
        [out, annotation("_COM_Outptr_result_maybenull_")] IMFTimedTextRuby** ruby
    );
    HRESULT GetBouten(
        [out, annotation("_COM_Outptr_result_maybenull_")] IMFTimedTextBouten** bouten
    );
    // Tate-chu-yoko
    HRESULT IsTextCombined(
        [out, annotation("_Out_")] BOOL* value
    );
    // Slanted Text, when is 0, that means the texts are not slanted texts
    HRESULT GetFontAngleInDegrees(
        [out, annotation("_Out_")] double* value
    );
}


cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WIN8) ")

cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")
// MF_MEDIA_ENGINE_CONTINUE_ON_CODEC_ERROR
// Data type: UINT32 
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_CONTINUE_ON_CODEC_ERROR,")
cpp_quote("0xdbcdb7f9,0x48e4,0x4295,0xb7,0x0d,0xd5,0x18,0x23,0x4e,0xeb,0x38);")

//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MEDIA_ENGINE_STREAMTYPE_FAILED
//
//  Synopsis:   Defines stream type that failed to render
//
//------------------------------------------------------------------------------
typedef enum MF_MEDIA_ENGINE_STREAMTYPE_FAILED
{
    MF_MEDIA_ENGINE_STREAMTYPE_FAILED_UNKNOWN = 0,
    MF_MEDIA_ENGINE_STREAMTYPE_FAILED_AUDIO = 1,
    MF_MEDIA_ENGINE_STREAMTYPE_FAILED_VIDEO = 2,
} MF_MEDIA_ENGINE_STREAMTYPE_FAILED;

cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

#pragma region EME2
//////////////////////////////////////////////////////////////////////////////
//
//  Encrypted Media Extensions (EME 2) March 31,2015
//
//  See http://www.w3.org/TR/2015/WD-encrypted-media-20150331/
//
//////////////////////////////////////////////////////////////////////////////
interface IMFMediaEngineEMENotify;
interface IMFMediaEngineClassFactory3;
interface IMFMediaKeySystemAccess;
interface IMFMediaKeySessionNotify2;
interface IMFMediaKeys2;
interface IMFMediaKeySession2;

cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")
cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

// EME2Events event handler
// MF_MEDIA_ENGINE_EME2_CALLBACK
// Data type: IUnknown (IMFMediaEngineEME2Notify)
// 494553a7-a481-4cb7-bec5-380903513731
cpp_quote("EXTERN_GUID(MF_MEDIA_ENGINE_EME_CALLBACK,")
cpp_quote("0x494553a7, 0xa481, 0x4cb7, 0xbe, 0xc5, 0x38, 0x09, 0x03, 0x51, 0x37, 0x31);")


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineEMENotify
//
//  Synopsis:   Implement EME2 Events for MediaEngine
//
//------------------------------------------------------------------------------
[
    object,
    uuid(9e184d15-cdb7-4f86-b49e-566689f4a601),
    local
]
interface IMFMediaEngineEMENotify : IUnknown
{
    void Encrypted(
        [annotation("_In_reads_bytes_opt_(cb)")] const BYTE *pbInitData,
        [annotation("_In_")] DWORD cb,
        [annotation("_In_")] BSTR bstrInitDataType
        );

    void WaitingForKey();
}

cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")
cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

#pragma region Application Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)")
cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

//+-----------------------------------------------------------------------------
//
//  Enumeration:  MF_MEDIA_KEYS_REQUIREMENT
//
//  Synopsis:   Defines requirement for DistinctiveId and PersistedState
//
//------------------------------------------------------------------------------
typedef enum MF_MEDIAKEYS_REQUIREMENT
{
    MF_MEDIAKEYS_REQUIREMENT_REQUIRED = 1,
    MF_MEDIAKEYS_REQUIREMENT_OPTIONAL = 2,
    MF_MEDIAKEYS_REQUIREMENT_NOT_ALLOWED = 3
} MF_MEDIAKEYS_REQUIREMENT;

cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")
cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */")
#pragma endregion

#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")
cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaKeySessionNotify2
//
//  Synopsis:   Implement EME2 Events for MediaKeySession
//
//------------------------------------------------------------------------------
[
    object,
    uuid(c3a9e92a-da88-46b0-a110-6cf953026cb9),
    local
]
interface IMFMediaKeySessionNotify2 : IMFMediaKeySessionNotify
{
    void KeyMessage2(
        [annotation("_In_")] MF_MEDIAKEYSESSION_MESSAGETYPE eMessageType,
        [annotation("_In_opt_")] BSTR destinationURL,
        [annotation("_In_reads_bytes_(cbMessage)")] const BYTE *pbMessage,
        [annotation("_In_")] DWORD cbMessage
        );

    void KeyStatusChange();
}

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaKeySystemAccess
//
//  Synopsis:   Implement return value of requestMediaKeySystemAccess for EME
//
//------------------------------------------------------------------------------
[
    object,
    uuid(aec63fda-7a97-4944-b35c-6c6df8085cc3),
    local
]
interface IMFMediaKeySystemAccess : IUnknown
{
    HRESULT CreateMediaKeys(
        [annotation("_In_opt_")] IPropertyStore *pCdmCustomConfig,
        [annotation("_COM_Outptr_")] IMFMediaKeys2 **ppKeys
        );

    HRESULT get_SupportedConfiguration(
        [annotation("_COM_Outptr_")] IPropertyStore **ppSupportedConfiguration
        );

    HRESULT get_KeySystem(
        [annotation("_Out_")] BSTR *pKeySystem
        );
}


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineClassFactory3
//
//  Synopsis:   Implement requestMediaKeySystemAccess for EME
//
//------------------------------------------------------------------------------
[
    object,
    uuid(3787614f-65f7-4003-b673-ead8293a0e60),
    local
]
interface IMFMediaEngineClassFactory3 : IUnknown
{
    HRESULT CreateMediaKeySystemAccess(
        [annotation("_In_")] BSTR keySystem,
        [annotation("_In_count_(uSize)")] IPropertyStore **ppSupportedConfigurationsArray,
        [annotation("_In_")] UINT uSize,
        [annotation("_COM_Outptr_")] IMFMediaKeySystemAccess **ppKeyAccess
        );
}

cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")
cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

#pragma region Application Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)")
cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

// Attributes for MediaKeySystemConfigurations
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_INITDATATYPES =     { { 0x497d231b, 0x4eb9, 0x4df0, { 0xb4, 0x74, 0xb9, 0xaf, 0xeb, 0x0a, 0xdf, 0x38 } }, PID_FIRST_USABLE+0x00000001 }; ")
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_DISTINCTIVEID =     { { 0x7dc9c4a5, 0x12be, 0x497e, { 0x8b, 0xff, 0x9b, 0x60, 0xb2, 0xdc, 0x58, 0x45 } }, PID_FIRST_USABLE+0x00000002 }; ")
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_PERSISTEDSTATE =    { { 0x5d4df6ae, 0x9af1, 0x4e3d, { 0x95, 0x5b, 0x0e, 0x4b, 0xd2, 0x2f, 0xed, 0xf0 } }, PID_FIRST_USABLE+0x00000003 }; ")
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_AUDIOCAPABILITIES = { { 0x980fbb84, 0x297d, 0x4ea7, { 0x89, 0x5f, 0xbc, 0xf2, 0x8a, 0x46, 0x28, 0x81 } }, PID_FIRST_USABLE+0x00000004 }; ")
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_VIDEOCAPABILITIES = { { 0xb172f83d, 0x30dd, 0x4c10, { 0x80, 0x06, 0xed, 0x53, 0xda, 0x4d, 0x3b, 0xdb } }, PID_FIRST_USABLE+0x00000005 }; ")
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_LABEL =             { { 0x9eae270e, 0xb2d7, 0x4817, { 0xb8, 0x8f, 0x54, 0x00, 0x99, 0xf2, 0xef, 0x4e } }, PID_FIRST_USABLE+0x00000006 }; ")
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_SESSIONTYPES =      { { 0x7623384f, 0x00f5, 0x4376, { 0x86, 0x98, 0x34, 0x58, 0xdb, 0x03, 0x0e, 0xd5 } }, PID_FIRST_USABLE+0x00000007 }; ")

// Attributes for Audio/Video Capabilities
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_ROBUSTNESS =  { { 0x9d3d2b9e, 0x7023, 0x4944, { 0xa8, 0xf5, 0xec, 0xca, 0x52, 0xa4, 0x69, 0x90 } }, PID_FIRST_USABLE+0x00000001 }; ")
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_CONTENTTYPE = { { 0x289fb1fc, 0xd9c4, 0x4cc7, { 0xb2, 0xbe, 0x97, 0x2b, 0x0e, 0x9b, 0x28, 0x3a } }, PID_FIRST_USABLE+0x00000002 }; ")

// Attributes to pass to CreateMediaKeys
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_CDM_INPRIVATESTOREPATH = { { 0xec305fd9, 0x039f, 0x4ac8, { 0x98, 0xda, 0xe7, 0x92, 0x1e, 0x00, 0x6a, 0x90 } }, PID_FIRST_USABLE+0x00000001 }; ")
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_EME_CDM_STOREPATH =          { { 0xf795841e, 0x99f9, 0x44d7, { 0xaf, 0xc0, 0xd3, 0x09, 0xc0, 0x4c, 0x94, 0xab } }, PID_FIRST_USABLE+0x00000002 }; ")

cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")
cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */")
#pragma endregion

#pragma region Desktop Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")
cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaKeys2
//
//  Synopsis:   Implement IMFMediaKeys2 for EME
//
//------------------------------------------------------------------------------
[
    object,
    uuid(45892507-ad66-4de2-83a2-acbb13cd8d43),
    local
]
interface IMFMediaKeys2 : IMFMediaKeys
{
    HRESULT CreateSession2(
        [annotation("_In_")] MF_MEDIAKEYSESSION_TYPE eSessionType,
        [annotation("_In_")] IMFMediaKeySessionNotify2 *pMFMediaKeySessionNotify2,
        [annotation("_COM_Outptr_")] IMFMediaKeySession2 **ppSession
        );

    HRESULT SetServerCertificate(
        [annotation("_In_reads_bytes_opt_(cb)")] const BYTE *pbServerCertificate,
        [annotation("_In_")] DWORD cb
        );

    HRESULT GetDOMException(
        [annotation("_In_")] HRESULT systemCode, 
        [annotation("_Out_")] HRESULT *code
        );
}

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaKeySession2
//
//  Synopsis:   Implement IMFMediaKeySession2 for EME
//
//------------------------------------------------------------------------------
[
    object,
    uuid(e9707e05-6d55-4636-b185-3de21210bd75),
    local
]
interface IMFMediaKeySession2 : IMFMediaKeySession
{
    HRESULT get_KeyStatuses(
        [annotation("_Outptr_result_buffer_(*puSize)")] MFMediaKeyStatus **pKeyStatusesArray,
        [annotation("_Out_")] UINT *puSize
        );

    HRESULT Load(
        [annotation("_In_")] BSTR bstrSessionId,
        [annotation("_Out_")] BOOL *pfLoaded
        );

    HRESULT GenerateRequest(
        [annotation("_In_")] BSTR initDataType,
        [annotation("_In_reads_bytes_(cb)")] const BYTE *pbInitData,
        [annotation("_In_")] DWORD cb
        );

    HRESULT get_Expiration(
        [annotation("_Out_")] double *dblExpiration
        );

    HRESULT Remove();

    HRESULT Shutdown();
}

cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")
cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */")
#pragma endregion

#pragma region Application Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)")
cpp_quote("#if (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")

//////////////////////////////////////////////////////////////////////////////
//
//  Store CDMs May 10, 2019
//
//  Allows direct usage of CDM objects that can be defined in store apps.
//
//////////////////////////////////////////////////////////////////////////////

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineClassFactory4
//
//  Synopsis:   Implement direct access of CDM object that could be defined in store apps.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(fbe256c1-43cf-4a9b-8cb8-ce8632a34186),
    local
]
interface IMFMediaEngineClassFactory4 : IUnknown
{
    HRESULT CreateContentDecryptionModuleFactory(
        [in, annotation("_In_")] LPCWSTR keySystem,
        [in, annotation("_In_")] REFIID riid,
        [out, iid_is(riid), annotation("_Outptr_")] LPVOID *ppvObject
        );
}


cpp_quote("#endif // (WINVER >= _WIN32_WINNT_WINTHRESHOLD) ")
cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */")
#pragma endregion
