/*
 * Copyright 2004 Christian Costa
 *
 * 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";
import "mmstream.idl";
import "strmif.idl";

cpp_quote("#include <ddraw.h>")
cpp_quote("#include <mmsystem.h>")
cpp_quote("#include <mmstream.h>")
cpp_quote("#include <ddstream.h>")
cpp_quote("#include <austream.h>")

cpp_quote("#if 0")
interface IDirectDraw;
interface IDirectDrawSurface;
cpp_quote("#endif")

interface IAMMultiMediaStream;
interface IAMMediaStream;
interface IMediaStreamFilter;
interface IAMMediaTypeStream;
interface IAMMediaTypeSample;

enum {
	AMMSF_NOGRAPHTHREAD      = 0x00000001
};

enum {
	AMMSF_ADDDEFAULTRENDERER = 0x00000001,
	AMMSF_CREATEPEER         = 0x00000002,
	AMMSF_STOPIFNOSAMPLES	 = 0x00000004,
	AMMSF_NOSTALL		 = 0x00000008
};

enum {
	AMMSF_RENDERTYPEMASK     = 0x00000003,
	AMMSF_RENDERTOEXISTING   = 0x00000000,
	AMMSF_RENDERALLSTREAMS   = 0x00000001,
	AMMSF_NORENDER           = 0x00000002,
	AMMSF_NOCLOCK            = 0x00000004,
	AMMSF_RUN                = 0x00000008
};


typedef [v1_enum] enum {
	Disabled = 0,
	ReadData = 1,
	RenderData = 2
} OUTPUT_STATE;

[
object,
uuid(7DB01C96-C0C3-11d0-8FF1-00C04FD9189D),
dual,
helpstring("IDirectShowStream Interface"),
pointer_default(unique)
]
interface IDirectShowStream : IDispatch
{
	[propget, id(1), helpstring("property FileName")] HRESULT FileName([out, retval] BSTR *pVal);
	[propput, id(1), helpstring("property FileName")] HRESULT FileName([in] BSTR newVal);
	[propget, id(2), helpstring("property Video")] HRESULT Video([out, retval] OUTPUT_STATE *pVal);
	[propput, id(2), helpstring("property Video")] HRESULT Video([in] OUTPUT_STATE newVal);
	[propget, id(3), helpstring("property Audio")] HRESULT Audio([out, retval] OUTPUT_STATE *pVal);
	[propput, id(3), helpstring("property Audio")] HRESULT Audio([in] OUTPUT_STATE newVal);
}

[
object,
uuid(BEBE595C-9A6F-11d0-8FDE-00C04FD9189D),
pointer_default(unique)
]
interface IAMMultiMediaStream : IMultiMediaStream
{
	HRESULT Initialize(
		[in] STREAM_TYPE StreamType,
		[in] DWORD dwFlags,
		[in] IGraphBuilder *pFilterGraph);

	HRESULT GetFilterGraph(
		[out] IGraphBuilder **ppGraphBuilder);

	HRESULT GetFilter(
		[out] IMediaStreamFilter **ppFilter);

	HRESULT AddMediaStream(
		[in] IUnknown *pStreamObject,
		[in] const MSPID *PurposeId,
		[in] DWORD dwFlags,
		[out] IMediaStream **ppNewStream);

	HRESULT OpenFile(
		[in] LPCWSTR pszFileName,
		[in] DWORD dwFlags);

	HRESULT OpenMoniker(
		[in] IBindCtx *pCtx,
		[in] IMoniker *pMoniker,
		[in] DWORD dwFlags);

	HRESULT Render(
		[in] DWORD dwFlags);
}


[
object,
uuid(BEBE595D-9A6F-11d0-8FDE-00C04FD9189D),
pointer_default(unique)
]
interface IAMMediaStream : IMediaStream
{
	HRESULT Initialize(
		[in] IUnknown *pSourceObject,
		[in] DWORD dwFlags,
		[in] REFMSPID PurposeId,
		[in] const STREAM_TYPE StreamType);

	HRESULT SetState(
		[in] FILTER_STATE State);

	HRESULT JoinAMMultiMediaStream(
		[in] IAMMultiMediaStream *pAMMultiMediaStream);

	HRESULT JoinFilter(
		[in] IMediaStreamFilter *pMediaStreamFilter);

	HRESULT JoinFilterGraph(
		[in] IFilterGraph *pFilterGraph);
}


[
object,
local,
uuid(BEBE595E-9A6F-11d0-8FDE-00C04FD9189D),
pointer_default(unique)
]
interface IMediaStreamFilter : IBaseFilter
{
	HRESULT AddMediaStream(
		[in] IAMMediaStream *pAMMediaStream);

	HRESULT GetMediaStream(
		[in] REFMSPID idPurpose,
		[out] IMediaStream **ppMediaStream);

	HRESULT EnumMediaStreams(
		[in] long Index,
		[out] IMediaStream **ppMediaStream);

	HRESULT SupportSeeking(
		[in] BOOL bRenderer);

	HRESULT ReferenceTimeToStreamTime(
		[in] [out] REFERENCE_TIME *pTime);

	HRESULT GetCurrentStreamTime(
		[out] REFERENCE_TIME *pCurrentStreamTime);

	HRESULT WaitUntil(
		[in]  REFERENCE_TIME WaitStreamTime);

	HRESULT Flush(
		[in] BOOL bCancelEOS);

	HRESULT EndOfStream();
}


[
object,
local,
uuid(AB6B4AFC-F6E4-11d0-900D-00C04FD9189D),
pointer_default(unique)
]
interface IDirectDrawMediaSampleAllocator : IUnknown
{
	HRESULT GetDirectDraw(IDirectDraw **ppDirectDraw);
}


[
object,
local,
uuid(AB6B4AFE-F6E4-11d0-900D-00C04FD9189D),
pointer_default(unique)
]
interface IDirectDrawMediaSample : IUnknown
{
	HRESULT GetSurfaceAndReleaseLock(
		[out] IDirectDrawSurface **ppDirectDrawSurface,
		[out] RECT * pRect);

	HRESULT LockMediaSamplePointer(void);
}


[
object,
local,
uuid(AB6B4AFA-F6E4-11d0-900D-00C04FD9189D),
pointer_default(unique)
]

interface IAMMediaTypeStream : IMediaStream
{
	HRESULT GetFormat(
		[out] AM_MEDIA_TYPE * pMediaType,
		[in] DWORD dwFlags);

	HRESULT SetFormat(
		[in] AM_MEDIA_TYPE * pMediaType,
		[in] DWORD dwFlags);

	HRESULT CreateSample(
		[in] long lSampleSize,
		[in] BYTE * pbBuffer,
		[in] DWORD dwFlags,
		[in] IUnknown *pUnkOuter,
		[out] IAMMediaTypeSample ** ppAMMediaTypeSample);

	HRESULT GetStreamAllocatorRequirements(
		[out] ALLOCATOR_PROPERTIES *pProps);

	HRESULT SetStreamAllocatorRequirements(
		[in] ALLOCATOR_PROPERTIES *pProps);
}


[
object,
local,
uuid(AB6B4AFB-F6E4-11d0-900D-00C04FD9189D),
pointer_default(unique)
]
interface IAMMediaTypeSample : IStreamSample
{
	HRESULT SetPointer(
		[in] BYTE *pBuffer,
		[in] long lSize);

	HRESULT GetPointer(
		[out] BYTE ** ppBuffer);

	long GetSize(void);

	HRESULT GetTime(
		[out] REFERENCE_TIME * pTimeStart,
		[out] REFERENCE_TIME * pTimeEnd);

	HRESULT SetTime(
		[in] REFERENCE_TIME * pTimeStart,
		[in] REFERENCE_TIME * pTimeEnd);

	HRESULT IsSyncPoint(void);

	HRESULT SetSyncPoint(
		BOOL bIsSyncPoint);

	HRESULT IsPreroll(void);

	HRESULT SetPreroll(
		BOOL bIsPreroll);

	long GetActualDataLength(void);

	HRESULT SetActualDataLength(long Len);

	HRESULT GetMediaType(
		AM_MEDIA_TYPE **ppMediaType);

	HRESULT SetMediaType(
		AM_MEDIA_TYPE *pMediaType);

	HRESULT IsDiscontinuity(void);

	HRESULT SetDiscontinuity(
		BOOL bDiscontinuity);

	HRESULT GetMediaTime(
		[out] LONGLONG * pTimeStart,
		[out] LONGLONG * pTimeEnd);

	HRESULT SetMediaTime(
		[in] LONGLONG * pTimeStart,
		[in] LONGLONG * pTimeEnd);
}

[
    uuid(49C47CE5-9BA4-11d0-8212-00C04FC32C45)
]
coclass AMMultiMediaStream
{
    [default] dispinterface IDirectShowStream;
}

cpp_quote("DEFINE_GUID(CLSID_AMDirectDrawStream,  0x49c47ce4, 0x9ba4, 0x11d0, 0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45);")
cpp_quote("DEFINE_GUID(CLSID_AMAudioStream,       0x8496e040, 0xaf4c, 0x11d0, 0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45);")
cpp_quote("DEFINE_GUID(CLSID_AMAudioData,         0xf2468580, 0xaf8a, 0x11d0, 0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45);")
cpp_quote("DEFINE_GUID(CLSID_AMMediaTypeStream,   0xcf0f2f7c, 0xf7bf, 0x11d0, 0x90, 0x0d, 0x00, 0xc0, 0x4f, 0xd9, 0x18, 0x9d);")
cpp_quote("DEFINE_GUID(CLSID_MediaStreamFilter,   0x49c47ce0, 0x9ba4, 0x11d0, 0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45);")
