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;


//+-----------------------------------------------------------------------------
//
//  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;


//+-----------------------------------------------------------------------------
//
//  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;

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

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

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
        );
}

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


