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

import "unknwn.idl";

cpp_quote("#if 0")
interface IDirect3DSurface9;
interface IDirect3DDevice9;
typedef LONGLONG REFERENCE_TIME;
typedef DWORD D3DFORMAT;
typedef DWORD D3DPOOL;
typedef HANDLE HMONITOR;
typedef struct { char dummy; } AM_MEDIA_TYPE;
typedef struct { char dummy; } D3DCOLOR;
cpp_quote("#endif")

interface IVMRSurface9;
interface IVMRSurfaceAllocator9;
interface IVMRSurfaceAllocatorEx9;
interface IVMRSurfaceAllocatorNotify9;
interface IVMRImagePresenter9;
interface IVMRImagePresenterConfig9;
interface IVMRMonitorConfig9;
interface IVMRWindowlessControl9;
interface IVMRMixerControl9;
interface IVMRImageCompositor9;
interface IVMRMixerBitmap9;
interface IVMRFilterConfig9;
interface IVMRAspectRatioControl9;
interface IVMRVideoStreamControl9;

typedef enum _VMR9PresentationFlags
{
    VMR9Sample_SyncPoint = 0x1,
    VMR9Sample_Preroll = 0x2,
    VMR9Sample_Discontinuity = 0x4,
    VMR9Sample_TimeValid = 0x8,
    VMR9Sample_SrcDstRectsValid = 0x10
} VMR9PresentationFlags;

typedef struct _VMR9PresentationInfo
{
    DWORD dwFlags; /* Flags defined above */
    IDirect3DSurface9 *lpSurf;
    REFERENCE_TIME rtStart;
    REFERENCE_TIME rtEnd;
    SIZE szAspectRatio;
    RECT rcSrc;
    RECT rcDst;
    DWORD dwReserved1;
    DWORD dwReserved2;
} VMR9PresentationInfo;

[
    local,
    object,
    uuid(69188c61-12a3-40f0-8ffc-342e7b433fd7),
    helpstring("IVMRImagePresenter9 interface"),
    pointer_default(unique)
]
interface IVMRImagePresenter9 : IUnknown
{
    HRESULT StartPresenting([in] DWORD_PTR id);
    HRESULT StopPresenting([in] DWORD_PTR id);
    HRESULT PresentImage([in] DWORD_PTR id, [in] VMR9PresentationInfo *info);
};

typedef enum _VMR9SurfaceAllocationFlags
{
    VMR9AllocFlag_3DRenderTarget = 0x1,
    VMR9AllocFlag_DXVATarget = 0x2,
    VMR9AllocFlag_TextureSurface = 0x4,
    VMR9AllocFlag_OffscreenSurface = 0x8,
    VMR9AllocFlag_RGBDynamicSwitch = 0x10,
    VMR9AllocFlag_UsageReserved = 0xe0,
    VMR9AllocFlag_UsageMask = 0xff,
} VMR9SurfaceAllocationFlags;

typedef struct _VMR9AllocationInfo
{
    DWORD dwFlags; /* Flags defined above */
    DWORD dwWidth;
    DWORD dwHeight;
    D3DFORMAT Format;
    D3DPOOL Pool;
    DWORD MinBuffers;
    SIZE szAspectRatio;
    SIZE szNativeSize;
} VMR9AllocationInfo;

[
    local,
    object,
    uuid(8d5148ea-3f5d-46cf-9df1-d1b896eedb1f),
    helpstring("IVMRSurfaceAllocator9 interface"),
    pointer_default(unique)
]
interface IVMRSurfaceAllocator9 : IUnknown
{
    HRESULT InitializeDevice([in] DWORD_PTR id, [in] VMR9AllocationInfo *allocinfo, [in, out] DWORD *numbuffers);
    HRESULT TerminateDevice([in] DWORD_PTR id);
    HRESULT GetSurface([in] DWORD_PTR id, [in] DWORD surfaceindex, [in] DWORD flags, [out] IDirect3DSurface9 **surface);
    HRESULT AdviseNotify([in] IVMRSurfaceAllocatorNotify9 *allocnotify);
};

[
    local,
    object,
    uuid(6de9a68a-a928-4522-bf57-655ae3866456),
    helpstring("IVMRSurfaceAllocatorEx9 interface"),
    pointer_default(unique)
]
interface IVMRSurfaceAllocatorEx9 : IVMRSurfaceAllocator9
{
    HRESULT GetSurfaceEx([in] DWORD_PTR id, [in] DWORD surfaceindex, [in] DWORD flags, [out] IDirect3DSurface9 **surface, [out] RECT *dest);
};

[
    local,
    object,
    uuid(dca3f5df-bb3a-4d03-bd81-84614bfbfa0c),
    helpstring("IVMRSurfaceAllocatorNotify9 interface"),
    pointer_default(unique)
]
interface IVMRSurfaceAllocatorNotify9 : IUnknown
{
    HRESULT AdviseSurfaceAllocator([in] DWORD_PTR id, [in] IVMRSurfaceAllocator9 *alloc);
    HRESULT SetD3DDevice([in] IDirect3DDevice9 *device, [in] HMONITOR monitor);
    HRESULT ChangeD3DDevice([in] IDirect3DDevice9 *device, [in] HMONITOR monitor);
    HRESULT AllocateSurfaceHelper([in] VMR9AllocationInfo *allocinfo, [in, out] DWORD *numbuffers, [out] IDirect3DSurface9 **surface);
    HRESULT NotifyEvent([in] LONG code, [in] LONG_PTR param1, [in] LONG_PTR param2);
};

typedef enum _VMR9AspectRatioMode
{
    VMR9ARMode_None,
    VMR9ARMode_LetterBox
} VMR9AspectRatioMode;

[
    local,
    object,
    uuid(8f537d09-f85e-4414-b23b-502e54c79927),
    helpstring("IVMRWindowlessControl interface"),
    pointer_default(unique)
]
interface IVMRWindowlessControl9 : IUnknown
{
    HRESULT GetNativeVideoSize([out] LONG *width, [out] LONG *height, [out] LONG *arwidth, [out] LONG *arheight);
    HRESULT GetMinIdealVideoSize([out] LONG *width, [out] LONG *height);
    HRESULT GetMaxIdealVideoSize([out] LONG *width, [out] LONG *height);
    HRESULT SetVideoPosition([in] const RECT *source, [in] const RECT *dest);
    HRESULT GetVideoPosition([out] RECT *source, [out] RECT *dest);
    HRESULT GetAspectRatioMode([out] DWORD *mode);
    HRESULT SetAspectRatioMode([in] DWORD mode);
    HRESULT SetVideoClippingWindow([in] HWND hwnd);
    HRESULT RepaintVideo([in] HWND hwnd, [in] HDC hdc);
    HRESULT DisplayModeChanged();
    HRESULT GetCurrentImage([out] BYTE **dib);
    HRESULT SetBorderColor([in] COLORREF color);
    HRESULT GetBorderColor([out] COLORREF *color);
};

typedef enum _VMR9MixerPrefs
{
    /* Decimation */
    MixerPref9_NoDecimation = 0x1,
    MixerPref9_DecimateOutput = 0x2,
    MixerPref9_ARAdjustXorY = 0x4,
    MixerPref9_NonSquareMixing = 0x8,
    MixerPref9_DecimateMask = 0xf,

    /* Filtering */
    MixerPref9_BiLinearFiltering = 0x10,
    MixerPref9_PointFiltering = 0x20,
    MixerPref9_AnisotropicFiltering = 0x40,
    MixerPref9_PyramidalQuadFiltering = 0x80,
    MixerPref9_GaussianQuadFiltering = 0x100,
    MixerPref9_FilteringReserved = 0xe00,
    MixerPref9_FilteringMask = 0xff0,

    /* Render target */
    MixerPref9_RenderTargetRGB = 0x1000,
    MixerPref9_RenderTargetYUV = 0x2000,
    MixerPref9_RenderTargetReserved = 0xfc000,

    MixerPref9_DynamicSwitchToBOB = 0x100000,
    MixerPref9_DynamicDecimateBy2 = 0x200000,
    MixerPref9_DynamicReserved = 0xc00000,
    MixerPref9_DynamicMask = 0xf00000,
} VMR9MixerPrefs;

typedef struct _VMR9NormalizedRect
{
    FLOAT left;
    FLOAT top;
    FLOAT right;
    FLOAT bottom;
} VMR9NormalizedRect;

typedef enum _VMR9ProcAmpControlFlags
{
    ProcAmpControl9_Brightness = 0x1,
    ProcAmpControl9_Contrast = 0x2,
    ProcAmpControl9_Hue = 0x4,
    ProcAmpControl9_Saturation = 0x8,
    ProcAmpControl9_Mask = 0xf
} VMR9ProcAmpControlFlags;

typedef struct _VMR9ProcAmpControl
{
    DWORD dwSize;
    DWORD dwFlags;
    FLOAT Brightness;
    FLOAT Contrast;
    FLOAT Hue;
    FLOAT Saturation;
} VMR9ProcAmpControl;

typedef struct _VMR9ProcAmpControlRange
{
    DWORD dwSize;
    VMR9ProcAmpControlFlags dwProperty;
    FLOAT MinValue;
    FLOAT MaxValue;
    FLOAT DefaultValue;
    FLOAT StepSize;
} VMR9ProcAmpControlRange;

[
    local,
    object,
    uuid(1a777eaa-47c8-4930-b2c9-8fee1c1b0f3b),
    helpstring("IVMRMixerControl9 interface"),
    pointer_default(unique)
]
interface IVMRMixerControl9 : IUnknown
{
    HRESULT SetAlpha([in] DWORD streamid, [in] FLOAT alpha);
    HRESULT GetAlpha([in] DWORD streamid, [out] FLOAT *alpha);
    HRESULT SetZOrder([in] DWORD streamid, [in] DWORD zorder);
    HRESULT GetZOrder([in] DWORD streamid, [out] DWORD *zorder);
    HRESULT SetOutputRect([in] DWORD streamid, [in] const VMR9NormalizedRect *rect);
    HRESULT GetOutputRect([in] DWORD streamid, [out] VMR9NormalizedRect *rect);
    HRESULT SetBackgroundClr([in] COLORREF back);
    HRESULT GetBackgroundClr([out] COLORREF *back);
    HRESULT SetMixingPrefs([in] DWORD mixingprefs);
    HRESULT GetMixingPrefs([out] DWORD *mixingprefs);
    HRESULT SetProcAmpControl([in] DWORD streamid, [in] VMR9ProcAmpControl *control);
    HRESULT GetProcAmpControl([in] DWORD streamid, [in, out] VMR9ProcAmpControl *control);
    HRESULT GetProcAmpControlRange([in] DWORD streamid, [in, out] VMR9ProcAmpControlRange *controlrange);
};

typedef struct _VMR9AlphaBitmap
{
    DWORD dwFlags;
    HDC hdc;
    IDirect3DSurface9 *pDDS;
    RECT rSrc;
    VMR9NormalizedRect *rDest;
    FLOAT fAlpha;
    COLORREF clrSrcKey;
    DWORD dwFilterMode;
} VMR9AlphaBitmap;

typedef enum _VMR9AlphaBitmapFlags
{
    VMR9AlphaBitmap_Disable = 0x1,
    VMR9AlphaBitmap_hDC = 0x2,
    VMR9AlphaBitmap_EntireDDS = 0x4,
    VMR9AlphaBitmap_SrcColorKey = 0x8,
    VMR9AlphaBitmap_SrcRect = 0x10,
    VMR9AlphaBitmap_FilterMode = 0x20
} VMR9AlphaBitmapFlags;

[
    local,
    object,
    uuid(ced175e5-1935-4820-81bd-ff6ad00c9108),
    helpstring("IVMRMixerBitmap interface"),
    pointer_default(unique)
]
interface IVMRMixerBitmap9 : IUnknown
{
    HRESULT SetAlphaBitmap([in] const VMR9AlphaBitmap *bitmap);
    HRESULT UpdateAlphaBitmapParameters([in] const VMR9AlphaBitmap *bitmap);
    HRESULT GetAlphaBitmapParameters([out] VMR9AlphaBitmap *bitmap);
};

[
    local,
    object,
    uuid(dfc581a1-6e1f-4c3a-8d0a-5e9792ea2afc),
    helpstring("IVMRSurface interface"),
    pointer_default(unique)
]
interface IVMRSurface9 : IUnknown
{
    HRESULT IsSurfaceLocked();
    HRESULT LockSurface([out] BYTE **surface);
    HRESULT UnlockSurface();
    HRESULT GetSurface([out] IDirect3DSurface9 **surface);
};

typedef enum _VMR9RenderPrefs
{
   RenderPrefs9_DoNotRenderBorder = 0x1,
   RenderPrefs9_Mask = 0x1
} VMR9RenderPrefs;

[
    local,
    object,
    uuid(45c15cab-6e22-420a-8043-ae1f0ac02c7d),
    helpstring("IVMRImagePresenterConfig9 interface"),
    pointer_default(unique)
]
interface IVMRImagePresenterConfig9 : IUnknown
{
    HRESULT SetRenderingPrefs([in] DWORD renderflags);
    HRESULT GetRenderingPrefs([out] DWORD *renderflags);
};

[
    local,
    object,
    uuid(d0cfe38b-93e7-4772-8957-0400c49a4485),
    helpstring("IVMRMixerStreamConfig interface"),
    pointer_default(unique)
]
interface IVMRVideoStreamControl9: IUnknown
{
    HRESULT SetStreamActiveState([in] BOOL active);
    HRESULT GetStreamActiveState([out] BOOL *active);
};

typedef enum _VMR9Mode
{
    VMR9Mode_Windowed = 0x1,
    VMR9Mode_Windowless = 0x2,
    VMR9Mode_Renderless = 0x4,
    VMR9Mode_Mask = 0x7
} VMR9Mode;

[
    local,
    object,
    uuid(5a804648-4f66-4867-9c43-4f5c822cf1b8),
    helpstring("IVMRFilterConfig9 interface"),
    pointer_default(unique)
]
interface IVMRFilterConfig9 : IUnknown
{
    HRESULT SetImageCompositor([in] IVMRImageCompositor9 *compositor);
    HRESULT SetNumberOfStreams([in] DWORD max);
    HRESULT GetNumberOfStreams([out] DWORD *max);
    HRESULT SetRenderingPrefs([in] DWORD renderflags);
    HRESULT GetRenderingPrefs([out] DWORD *renderflags);
    HRESULT SetRenderingMode([in] DWORD mode);
    HRESULT GetRenderingMode([out] DWORD *mode);
};

[
    local,
    object,
    uuid(00d96c29-bbde-4efc-9901-bb5036392146),
    helpstring("IVMRAspectRatioControl9 interface"),
    pointer_default(unique)
]
interface IVMRAspectRatioControl9 : IUnknown
{
    HRESULT GetAspectRatioMode([out] DWORD *mode);
    HRESULT SetAspectRatioMode([in] DWORD mode);
}

#define VMR9DEVICENAMELEN 32
#define VMR9DEVICEDESCRIPTIONLEN 512

typedef struct _VMR9MonitorInfo
{
    UINT uDevID;
    RECT rcMonitor;
    HMONITOR hMon;
    DWORD dwFlags;
    WCHAR szDevice[VMR9DEVICENAMELEN];
    WCHAR szDescription[VMR9DEVICEDESCRIPTIONLEN];
    LARGE_INTEGER liDriverVersion;
    DWORD dwVendorId;
    DWORD dwDeviceId;
    DWORD dwSubSysId;
    DWORD dwRevision;
} VMR9MonitorInfo;

[
    local,
    object,
    uuid(46c2e457-8ba0-4eef-b80b-0680f0978749),
    helpstring("IVMRMonitorConfig9 interface"),
    pointer_default(unique)
]
interface IVMRMonitorConfig9 : IUnknown
{
    HRESULT SetMonitor([in] UINT uDev);
    HRESULT GetMonitor([out] UINT *uDev);
    HRESULT SetDefaultMonitor([in] UINT uDev);
    HRESULT GetDefaultMonitor([out] UINT *uDev);
    HRESULT GetAvailableMonitors([out, size_is(arraysize)] VMR9MonitorInfo *info, [in] DWORD arraysize, [out] DWORD *numdev);
};

typedef enum _VMR9DeinterlacePrefs
{
    DeinterlacePref9_NextBest = 0x1,
    DeinterlacePref9_BOB = 0x2,
    DeinterlacePref9_Weave = 0x4,
    DeinterlacePref9_Mask = 0x7
} VMR9DeinterlacePrefs;

typedef enum _VMR9DeinterlaceTech
{
    DeinterlaceTech9_Unknown = 0,
    DeinterlaceTech9_BOBLineReplicate = 0x1,
    DeinterlaceTech9_BOBVerticalStretch = 0x2,
    DeinterlaceTech9_MedianFiltering = 0x4,
    DeinterlaceTech9_EdgeFiltering = 0x10,
    DeinterlaceTech9_FieldAdaptive = 0x20,
    DeinterlaceTech9_PixelAdaptive = 0x40,
    DeinterlaceTech9_MotionVectorSteered = 0x80
} VMR9DeinterlaceTech;

typedef struct _VMR9Frequency
{
    DWORD dwNumerator;
    DWORD dwDenominator;
} VMR9Frequency;

typedef enum _VMR9_SampleFormat
{
    VMR9_SampleReserved = 1,
    VMR9_SampleProgressiveFrame = 2,
    VMR9_SampleFieldInterleavedEvenFirst = 3,
    VMR9_SampleFieldInterleavedOddFirst = 4,
    VMR9_SampleFieldSingleEven = 5,
    VMR9_SampleFieldSingleOdd = 6,
} VMR9_SampleFormat;

typedef struct _VMR9VideoDesc
{
    DWORD dwSize;
    DWORD dwSampleWidth;
    DWORD dwSampleHeight;
    VMR9_SampleFormat SampleFormat;
    DWORD dwFourCC;
    VMR9Frequency InputSampleFreq;
    VMR9Frequency OutputFrameFreq;
} VMR9VideoDesc;

typedef struct _VMR9DeinterlaceCaps {
    DWORD dwSize;
    DWORD dwNumPreviousOutputFrames;
    DWORD dwNumForwardRefSamples;
    DWORD dwNumBackwardRefSamples;
    VMR9DeinterlaceTech DeinterlaceTechnology;
} VMR9DeinterlaceCaps;

[
    local,
    object,
    uuid(a215fb8d-13c2-4f7f-993c-003d6271a459),
    helpstring("IVMRDeinterlaceControl9 interface"),
    pointer_default(unique)
]
interface IVMRDeinterlaceControl9 : IUnknown
{
    HRESULT GetNumberOfDeinterlaceModes([in] VMR9VideoDesc *desc, [in, out] DWORD *nummodes, [out] GUID *modes);
    HRESULT GetDeinterlaceModeCaps([in] GUID *mode, [in] VMR9VideoDesc *desc, [out] VMR9DeinterlaceCaps *caps);
    HRESULT GetDeinterlaceMode([in] DWORD streamid, [out] GUID *mode);
    HRESULT SetDeinterlaceMode([in] DWORD streamid, [in] GUID *mode);
    HRESULT GetDeinterlacePrefs([out] DWORD *prefs);
    HRESULT SetDeinterlacePrefs([in] DWORD prefs);
    HRESULT GetActualDeinterlaceMode([in] DWORD streamid, [out] GUID *mode);
};

typedef struct _VMR9VideoStreamInfo {
    IDirect3DSurface9 *pddsVideoSurface;
    DWORD dwWidth;
    DWORD dwHeight;
    DWORD dwStrmID;
    FLOAT fAlpha;
    VMR9NormalizedRect rNormal;
    REFERENCE_TIME rtStart;
    REFERENCE_TIME rtEnd;
    VMR9_SampleFormat SampleFormat;
} VMR9VideoStreamInfo;

[
    local,
    object,
    uuid(4a5c89eb-df51-4654-ac2a-e48e02bbabf6),
    helpstring("IVMRImageCompositor9 interface"),
    pointer_default(unique)
]
interface IVMRImageCompositor9 : IUnknown
{
    HRESULT InitCompositionDevice([in] IUnknown *d3ddev);
    HRESULT TermCompositionDevice([in] IUnknown *d3ddev);
    HRESULT CompositeImage([in] IUnknown *d3ddev, [in] IDirect3DSurface9 *d3dtarget, [in] AM_MEDIA_TYPE *mttarget,
                           [in] REFERENCE_TIME start, [in] REFERENCE_TIME stop, D3DCOLOR back,
                           [in] VMR9VideoStreamInfo *info, [in] UINT streams);
};
