/*
 * 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("propetry Video")] HRESULT Video([in] OUTPUT_STATE newVal);
	[propget, id(3), helpstring("property Audio")] HRESULT Audio([out, retval] OUTPUT_STATE *pVal);
	[propput, id(3), helpstring("propetry 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, optional] IGraphBuilder *pFilterGraph);

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

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

	HRESULT AddMediaStream(
		[in, optional] IUnknown *pStreamObject,
		[in, optional] const MSPID *PurposeId,
		[in] DWORD dwFlags,
		[out, optional] 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, optional] 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, optional] BYTE * pbBuffer,
		[in] DWORD dwFlags,
		[in, optional] 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);")
