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),
    helpstring("IMFMediaError Interface"),
    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),
    helpstring("IMFMediaTimeRange Interface"),
    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;


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaEngineNotify
//
//  Synopsis:   IMFMediaEngineNotify fires events
//
//  This interface is implemented by the component using IMFMediaEngine
//------------------------------------------------------------------------------
[
    object,
    uuid(fee7c112-e776-42b5-9bbf-0048524e2bd5),
    helpstring("IMFMediaEngineNotify Interface"),
    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),
    helpstring("IMFMediaEngineSrcElements Interface"),
    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),
    helpstring("IMFMediaEngine Interface"),
    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),
    helpstring("IMFMediaEngineEx Interface"),
    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,
        [in, 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
        );
};


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),
    helpstring("IMFMediaEngineExtension Interface"),
    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),
    helpstring("IMFMediaEngineProtectedContent Interface"),
    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)")

////////////////////////////////////////////////////////////////////////////////
//
// 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);")


//+-----------------------------------------------------------------------------
//
//  Interface:  IMFMediaSourceExtensionNotify
//
//  Synopsis:   callback interfaces used to notify MSE clients about important
//              events within the MSE.
//
//------------------------------------------------------------------------------
[
    object,
    uuid(a7901327-05dd-4469-a7b7-0e01979e361d),
    helpstring("IMFMediaSourceExtensionNotify Interface"),
    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),
    helpstring("IMFBufferListNotify Interface"),
    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),
    helpstring("IMFSourceBufferNotify Interface"),
    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),
    helpstring("IMFSourceBuffer Interface"),
    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
        );
};

//+-----------------------------------------------------------------------------
//
//  Interface:  IMFSourceBufferList
//
//  Synopsis:   SourceBufferList interface.
//              Events generated:
//                  onAddSourceBuffer
//                  onRemoveSourceBuffer
//
//------------------------------------------------------------------------------
[
    object,
    uuid(249981f8-8325-41f3-b80c-3b9e3aad0cbe),
    helpstring("IMFSourceBufferList Interface"),
    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),
    helpstring("IMFMediaSourceExtension Interface"),
    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
        );
};


//////////////////////////////////////////////////////////////////////////////
//
//  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),
    helpstring("IMFMediaEngineEME Interface"),
    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),
    helpstring("IMFMediaEngineSrcElementsEx Interface"),
    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),
    helpstring("IMFMediaKeysNotify Interface"),
    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),
    helpstring("IMFMediaKeys Interface"),
    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),
    helpstring("IMFMediaKeySession Interface"),
    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),
    helpstring("IMFMediaKeySessionNotify Interface"),
    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),
    helpstring("IMFCdmSuspendNotify Interface"),
    pointer_default(unique)
]
interface IMFCdmSuspendNotify : IUnknown
{
   HRESULT Begin();
   HRESULT End();
}

//  End of Encrypted Media Extensions


//+-----------------------------------------------------------------------------
//
//  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),
    helpstring("IMFMediaEngineOPMInfo Interface"),
    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);")

// 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);")

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_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);")

// 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);")

#if (WINVER >= _WIN32_WINNT_WINBLUE)
// 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);")
#endif // (WINVER >= _WIN32_WINNT_WINBLUE)

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),
    helpstring("IMFMediaEngineClassFactory Interface"),
    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),
    helpstring("IMFMediaEngineClassFactoryEx Interface"),
    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),
    helpstring("IMFMediaEngineClassFactory2 Interface"),
    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(a724b056-1b2e-4642-a6f3-db9420c52908),
    helpstring("IMFMediaEngineSupportsSourceTransfer Interface"),
    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
        );
}

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("#endif // (WINVER >= _WIN32_WINNT_WIN7) ")


