Last active
April 26, 2016 04:40
-
-
Save thedeemon/46748f91afdbcf339f55da9b355a6b56 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module dshow; | |
import core.sys.windows.com, core.sys.windows.windows; | |
GUID Guid(string str)() { | |
static assert(str.length==36, "Guid string must be 36 chars long"); | |
enum GUIDstring = "GUID(0x" ~ str[0..8] ~ ", 0x" ~ str[9..13] ~ ", 0x" ~ str[14..18] ~ | |
", [0x" ~ str[19..21] ~ ", 0x" ~ str[21..23] ~ ", 0x" ~ str[24..26] ~ ", 0x" ~ str[26..28] | |
~ ", 0x" ~ str[28..30] ~ ", 0x" ~ str[30..32] ~ ", 0x" ~ str[32..34] ~ ", 0x" ~ str[34..36] ~ "])"; | |
return mixin(GUIDstring); | |
} | |
const GUID IID_IPersist = IPersist.iid; | |
interface IPersist : IUnknown | |
{ | |
static const GUID iid = { 0x0000010c,0x0000,0x0000,[ 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ] }; | |
HRESULT GetClassID | |
( | |
/+[out]+/ CLSID *pClassID | |
); | |
} | |
alias DWORD_PTR HSEMAPHORE; | |
alias DWORD_PTR HEVENT; | |
alias DWORD LCID; | |
alias LONG DISPID; | |
alias ushort VARTYPE; | |
alias double DOUBLE; | |
alias short VARIANT_BOOL; | |
alias short _VARIANT_BOOL; | |
alias double DATE; | |
alias ulong DWORDLONG; | |
struct tagCY { | |
LONGLONG int64; | |
} | |
alias tagCY CY; | |
alias BSTR = wchar*; | |
struct VIDEOINFOHEADER { | |
RECT rcSource; // The bit we really want to use | |
RECT rcTarget; // Where the video should go | |
DWORD dwBitRate; // Approximate bit data rate | |
DWORD dwBitErrorRate; // Bit error rate for this stream | |
REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units) | |
BITMAPINFOHEADER bmiHeader; | |
} | |
struct _AMMediaType | |
{ | |
GUID majortype; | |
GUID subtype; | |
BOOL bFixedSizeSamples; | |
BOOL bTemporalCompression; | |
ULONG lSampleSize; | |
GUID formattype; | |
IUnknown pUnk; | |
ULONG cbFormat; | |
/+[size_is(cbFormat)]+/ BYTE * pbFormat; | |
} | |
alias _AMMediaType AM_MEDIA_TYPE; | |
void FreeMediaType(AM_MEDIA_TYPE* mt) { | |
if (mt.cbFormat != 0) { | |
CoTaskMemFree(mt.pbFormat); | |
mt.cbFormat = 0; | |
mt.pbFormat = NULL; | |
} | |
if (mt.pUnk !is null) { | |
mt.pUnk.Release(); | |
mt.pUnk = NULL; | |
} | |
} | |
void DeleteMediaType(AM_MEDIA_TYPE *pmt) { | |
if (pmt !is null) { | |
FreeMediaType(pmt); | |
CoTaskMemFree(pmt); | |
} | |
} | |
__gshared auto MEDIATYPE_Video = Guid!"73646976-0000-0010-8000-00AA00389B71"; | |
enum /+ _PinDirection+/ | |
{ | |
PINDIR_INPUT, | |
PINDIR_OUTPUT | |
} | |
alias int _PinDirection; | |
alias int PIN_DIRECTION; | |
alias LONGLONG REFERENCE_TIME; | |
alias double REFTIME; | |
struct _PinInfo | |
{ | |
IBaseFilter pFilter; // the filter this pin is on | |
PIN_DIRECTION dir; // am I an input or output pin? | |
WCHAR[MAX_PIN_NAME] achName; | |
} | |
alias _PinInfo PIN_INFO; | |
const GUID IID_IPin = IPin.iid; | |
interface IPin : IUnknown | |
{ | |
static const GUID iid = { 0x56a86891,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
// initiate a connection to another pin. calls ReceiveConnection on the | |
// other pin. Verifies that the connection is possible and may reject | |
// it. | |
// The mediatype parameter is optional. If it is not null, the pin must | |
// connect using that media type if possible. The subtype and/or format | |
// type can be GUID_NULL, meaning that the pin can fill them in as desired. | |
// This allows an application to partially specify the media type to be | |
// used for the connection, insisting on eg YUV 422 but leaving details | |
// (such as the image size) to be negotiated between the pins. | |
HRESULT Connect( | |
/+[in]+/ IPin pReceivePin, // connect yourself to this pin | |
/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ const( AM_MEDIA_TYPE)* pmt // (optional) connect using this type | |
); | |
// called by a connecting pin to make a connection | |
HRESULT ReceiveConnection( | |
/+[in]+/ IPin pConnector, | |
in const( AM_MEDIA_TYPE)*pmt // this is the media type we will exchange | |
); | |
// break a connection - no params since there is only one connection | |
// possible on this pin | |
HRESULT Disconnect(); | |
// Find the pin this pin is connected to (if any) | |
// The pointer returned is AddRef()d | |
// Fails if the pin is not connected | |
HRESULT ConnectedTo( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IPin *pPin | |
); | |
// Return the media type of a connection if the pin is connected | |
HRESULT ConnectionMediaType( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ AM_MEDIA_TYPE *pmt | |
); | |
// get information about the pin itself | |
HRESULT QueryPinInfo( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ PIN_INFO * pInfo | |
); | |
// We often want to know the direction. Rather than use the | |
// relatively expensive QueryPinInfo, use this | |
HRESULT QueryDirection( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ PIN_DIRECTION *pPinDir | |
); | |
// Get an identifier for the pin (allows connections to be saved). | |
// The storage will be allocated by the filter using CoTaskMemAlloc | |
// The caller should free it using CoTaskMemFree | |
HRESULT QueryId( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ LPWSTR * Id | |
); | |
// will the pin accept the format type, S_OK yes, S_FALSE no | |
HRESULT QueryAccept( | |
in const( AM_MEDIA_TYPE)*pmt | |
); | |
// return an enumerator for this pin's preferred media types | |
HRESULT EnumMediaTypes( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IEnumMediaTypes *ppEnum | |
); | |
// return an array of IPin* - the pins that this pin internally connects to | |
// All pins put in the array must be AddReffed (but no others) | |
// Errors: "Can't say" - FAIL; not enough slots - return S_FALSE | |
// Default: return E_NOTIMPL | |
// The filter graph will interpret E_NOTIMPL as any input pin connects to | |
// all visible output pins and vise versa. | |
// apPin can be NULL if nPin==0 (not otherwise). | |
HRESULT QueryInternalConnections( | |
/+[out /+ AM_ANNOTATION("__out_ecount_part_opt(*nPin, *nPin)") +/]+/ IPin *apPin, // array of IPin* | |
/+[in, out]+/ ULONG *nPin // on input, the number of slots | |
// on output the number of pins | |
); | |
// notify the pin that no more data is expected until a new run | |
// command is issued. End of stream should be queued and delivered after | |
// all queued data is delivered. Pass through if there is no queued data. | |
// Flush should flush any queued EOS. | |
// returns S_OK unless there is some error. | |
// input pins only: output pins will normally return E_UNEXPECTED. | |
HRESULT EndOfStream(); | |
// Flush | |
// Enter flush state: do the following steps (in order) | |
// -- prevent any more Receives succeeding (set a flushing flag) | |
// -- discard any queued data | |
// -- free anyone blocked on Receive in your filter | |
// -- pass BeginFlush to any downstream pins | |
HRESULT BeginFlush(); | |
// End flush state: do the following steps in order | |
// -- ensure no more data will be pushed by your filter | |
// (sync with thread if you have one, stop it pushing and | |
// discard any queued data) | |
// -- re-enable Receive (clear internal flushing flag) | |
// -- pass EndFlush to any downstream pins | |
HRESULT EndFlush(); | |
// informational: all data arriving after this call is part of a segment | |
// from StartTime to StopTime, played at rate. This allows filters that | |
// process buffers containing more than one sample to clip the rendering | |
// to within the start and stop times. | |
// | |
// A source pin will call a destination pin on this method after completing | |
// delivery of any previous data, and before any Receive calls for the | |
// new data | |
HRESULT NewSegment( | |
in REFERENCE_TIME tStart, | |
in REFERENCE_TIME tStop, | |
in double dRate); | |
} | |
const GUID IID_IEnumPins = IEnumPins.iid; | |
interface IEnumPins : IUnknown | |
{ | |
static const GUID iid = { 0x56a86892,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
HRESULT Next( | |
in ULONG cPins, // place this many pins... | |
/+[out, size_is(cPins) /+ AM_ANNOTATION("__out_ecount_part(cPins, *pcFetched)") +/]+/ IPin * ppPins, // ...in this array | |
/+[out /+ AM_ANNOTATION("__out_opt") +/]+/ ULONG * pcFetched // actual count passed | |
); | |
HRESULT Skip( | |
in ULONG cPins); | |
HRESULT Reset(); | |
HRESULT Clone( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IEnumPins *ppEnum | |
); | |
} | |
const GUID IID_IEnumMediaTypes = IEnumMediaTypes.iid; | |
interface IEnumMediaTypes : IUnknown | |
{ | |
static const GUID iid = { 0x89c31040,0x846b,0x11ce,[ 0x97,0xd3,0x00,0xaa,0x00,0x55,0x59,0x5a ] }; | |
// to call this member function pass in the address of a pointer to a | |
// media type. The interface will allocate the necessary AM_MEDIA_TYPE | |
// structures and initialise them with the variable format block | |
HRESULT Next( | |
in ULONG cMediaTypes, // place this many types... | |
/+[out, size_is(cMediaTypes) /+ AM_ANNOTATION("__out_ecount_part(cMediaTypes, *pcFetched)") +/]+/ | |
AM_MEDIA_TYPE ** ppMediaTypes, // ...in this array | |
/+[out /+ AM_ANNOTATION("__out_opt") +/]+/ ULONG * pcFetched // actual count passed | |
); | |
HRESULT Skip( | |
in ULONG cMediaTypes); | |
HRESULT Reset(); | |
HRESULT Clone( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IEnumMediaTypes *ppEnum | |
); | |
} | |
const GUID IID_IReferenceClock = IReferenceClock.iid; | |
interface IReferenceClock : IUnknown | |
{ | |
static const GUID iid = { 0x56a86897,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
// get the time now | |
HRESULT GetTime( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ REFERENCE_TIME *pTime | |
); | |
// ask for an async notification that a time has elapsed | |
HRESULT AdviseTime( | |
in REFERENCE_TIME baseTime, // base reference time | |
in REFERENCE_TIME streamTime, // stream offset time | |
in HEVENT hEvent, // advise via this event | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ DWORD_PTR * pdwAdviseCookie // where your cookie goes | |
); | |
// ask for an async periodic notification that a time has elapsed | |
HRESULT AdvisePeriodic( | |
in REFERENCE_TIME startTime, // starting at this time | |
in REFERENCE_TIME periodTime, // time between notifications | |
in HSEMAPHORE hSemaphore, // advise via a semaphore | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ DWORD_PTR * pdwAdviseCookie // where your cookie goes | |
); | |
// cancel a request for notification | |
HRESULT Unadvise( | |
in DWORD_PTR dwAdviseCookie); | |
} | |
enum MAX_PIN_NAME = 128; | |
enum MAX_FILTER_NAME = 128; | |
const GUID IID_IMediaFilter = IMediaFilter.iid; | |
interface IMediaFilter : IPersist | |
{ | |
static const GUID iid = { 0x56a86899,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
// tell the filter to transition to the new state. The state transition | |
// may not be instantaneous (external mechanical activity may be involved, | |
// for example). The state functions may return before the state | |
// transition has completed | |
// these functions will return S_OK if the transition is complete, S_FALSE if | |
// the transition is not complete but no error has occurred, or some error value | |
// if the transition failed. | |
HRESULT Stop(); | |
HRESULT Pause(); | |
// in order to synchronise independent streams, you must pass a time | |
// value with the Run command. This is the difference between stream | |
// time and reference time. That is, it is the amount to be added to | |
// the IMediaSample timestamp to get the time at which that sample | |
// should be rendered according to the reference clock. | |
// If we are starting at the beginning of the stream, it will thus be | |
// simply the time at which the first sample should appear. If we are | |
// restarting from Paused mode in midstream, then it will be the total | |
// time we have been paused added to the initial start time. | |
// the filtergraph will provide this information to its filters. If you | |
// are an app calling the filtergraph, it's ok to pass a start time of | |
// 0, in which case the filter graph will calculate a soon-as-possible | |
// time. FilterGraphs will accept 0 meaning ASAP; most filters will not. | |
HRESULT Run(REFERENCE_TIME tStart); | |
// possible states that the filter could be in | |
enum /+ _FilterState+/ | |
{ | |
State_Stopped, // not in use | |
State_Paused, // holding resources, ready to go | |
State_Running | |
} | |
alias int _FilterState; | |
alias int FILTER_STATE; | |
// find out what state the filter is in. | |
// If timeout is 0, will return immediately - if a state transition is | |
// not complete, it will return the state being transitioned into, and | |
// the return code will be VFW_S_STATE_INTERMEDIATE. if no state | |
// transition is in progress the state will be returned and the return | |
// code will be S_OK. | |
// | |
// If timeout is non-zero, GetState will not return until the state | |
// transition is complete, or the timeout expires. | |
// The timeout is in milliseconds. | |
// You can also pass in INFINITE as a special value for the timeout, in | |
// which case it will block indefinitely waiting for the state transition | |
// to complete. If the timeout expires, the state returned is the | |
// state we are trying to reach, and the return code will be | |
// VFW_S_STATE_INTERMEDIATE. If no state transition is in progress | |
// the routine returns immediately with return code S_OK. | |
// | |
// return State is State_Running, State_Paused or State_Stopped. | |
// return code is S_OK, or VFW_S_STATE_INTERMEDIATE if state | |
// transition is not complete or an error value if the method failed. | |
HRESULT GetState( | |
in DWORD dwMilliSecsTimeout, | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ FILTER_STATE *State); | |
// tell the filter the reference clock to which it should synchronize | |
// activity. This is most important to rendering filters and may not | |
// be of any interest to other filters. | |
HRESULT SetSyncSource( | |
/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ IReferenceClock pClock); | |
// get the reference clock currently in use (it may be NULL) | |
HRESULT GetSyncSource( | |
/+[out /+ AM_ANNOTATION("__deref_out_opt") +/]+/ IReferenceClock * pClock); | |
} | |
alias IMediaFilter PMEDIAFILTER; | |
//===================================================================== | |
//===================================================================== | |
// Defines IBaseFilter interface | |
// | |
// all multimedia components will expose this interface | |
// this interface abstracts an object that has typed input and output | |
// connections and can be dynamically aggregated. | |
// | |
// IMediaFilter supports synchronisation and activity state: IBaseFilter | |
// is derived from that since all filters need to support IMediaFilter, | |
// whereas a few objects (plug-in control distributors for example) will | |
// support IMediaFilter but not IBaseFilter. | |
// | |
// IMediaFilter is itself derived from IPersist so that every filter | |
//supports GetClassID() | |
//===================================================================== | |
//===================================================================== | |
struct _FilterInfo | |
{ | |
WCHAR[MAX_FILTER_NAME] achName; // maybe null if not part of graph | |
IFilterGraph pGraph; | |
} | |
alias _FilterInfo FILTER_INFO; | |
const GUID IID_IBaseFilter = IBaseFilter.iid; | |
interface IBaseFilter : IMediaFilter | |
{ | |
static const GUID iid = { 0x56a86895,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
// enumerate all the pins available on this filter | |
// allows enumeration of all pins only. | |
// | |
HRESULT EnumPins( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IEnumPins * ppEnum // enum interface returned here | |
); | |
// Convert the external identifier of a pin to an IPin * | |
// This pin id is quite different from the pin Name in CreatePin. | |
// In CreatePin the Name is invented by the caller. In FindPin the Id | |
// must have come from a previous call to IPin::QueryId. Whether or not | |
// this operation would cause a pin to be created depends on the filter | |
// design, but if called twice with the same id it should certainly | |
// return the same pin both times. | |
HRESULT FindPin( | |
/+[ string]+/ in LPCWSTR Id, | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IPin * ppPin | |
); | |
HRESULT QueryFilterInfo( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ FILTER_INFO * pInfo | |
); | |
// notify a filter that it has joined a filter graph. It is permitted to | |
// refuse. The filter should addref and store this interface for later use | |
// since it may need to notify events to this interface. A null pointer indicates | |
// that the filter is no longer part of a graph. | |
HRESULT JoinFilterGraph( | |
/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ IFilterGraph pGraph, | |
/+[ string /+ AM_ANNOTATION("__in_opt") +/]+/ in LPCWSTR pName | |
); | |
// return a Vendor information string. Optional - may return E_NOTIMPL. | |
// memory returned should be freed using CoTaskMemFree | |
HRESULT QueryVendorInfo( | |
/+[out, string /+ AM_ANNOTATION("__out") +/]+/ LPWSTR* pVendorInfo | |
); | |
} | |
const GUID IID_IEnumFilters = IEnumFilters.iid; | |
interface IEnumFilters : IUnknown | |
{ | |
static const GUID iid = { 0x56a86893,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
HRESULT Next | |
( in ULONG cFilters, // place this many filters... | |
/+[out /+ AM_ANNOTATION("__out_ecount_part(cFilters, *pcFetched)") +/]+/ IBaseFilter * ppFilter, // ...in this array of IBaseFilter* | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ ULONG * pcFetched // actual count passed returned here | |
); | |
HRESULT Skip | |
( in ULONG cFilters | |
); | |
HRESULT Reset(); | |
HRESULT Clone | |
( /+[out /+ AM_ANNOTATION("__out") +/]+/ IEnumFilters *ppEnum | |
); | |
} | |
// auto CLSID_FilterGraph = GUID(0xe436ebb3, 0x524f, 0x11ce, [0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70]); | |
const GUID IID_IFilterGraph = IFilterGraph.iid; | |
interface IFilterGraph : IUnknown | |
{ | |
static const GUID iid = { 0x56a8689f,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
//========================================================================== | |
// Low level filter functions | |
//========================================================================== | |
// Add a filter to the graph and name it with *pName. | |
// If the name is not unique, The request will fail. | |
// The Filter graph will call the JoinFilterGraph | |
// member function of the filter to inform it. | |
// This must be called before attempting Connect, ConnectDirect or Render | |
// for pins of the filter. | |
HRESULT AddFilter | |
( /+[in]+/ IBaseFilter pFilter, | |
/+[ string]+/ in LPCWSTR pName | |
); | |
// Remove a filter from the graph. The filter graph implementation | |
// will inform the filter that it is being removed. | |
HRESULT RemoveFilter | |
( /+[in]+/ IBaseFilter pFilter | |
); | |
// Set *ppEnum to be an enumerator for all filters in the graph. | |
HRESULT EnumFilters | |
( /+[out /+ AM_ANNOTATION("__out") +/]+/ IEnumFilters *ppEnum | |
); | |
// Set *ppFilter to be the filter which was added with the name *pName | |
// Will fail and set *ppFilter to NULL if the name is not in this graph. | |
HRESULT FindFilterByName | |
( /+[ string]+/ in LPCWSTR pName, | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IBaseFilter * ppFilter | |
); | |
//========================================================================== | |
// Low level connection functions | |
//========================================================================== | |
// Connect these two pins directly (i.e. without intervening filters) | |
// the media type is optional, and may be partially specified (that is | |
// the subtype and/or format type may be GUID_NULL). See IPin::Connect | |
// for details of the media type parameter. | |
HRESULT ConnectDirect | |
( /+[in]+/ IPin ppinOut, // the output pin | |
/+[in]+/ IPin ppinIn, // the input pin | |
/+[ unique /+ AM_ANNOTATION("__in_opt") +/]+/ in const( AM_MEDIA_TYPE)* pmt // optional mediatype | |
); | |
// Break the connection that this pin has and reconnect it to the | |
// same other pin. | |
HRESULT Reconnect | |
( /+[in]+/ IPin ppin // the pin to disconnect and reconnect | |
); | |
// Disconnect this pin, if connected. Successful no-op if not connected. | |
HRESULT Disconnect | |
( /+[in]+/ IPin ppin | |
); | |
//========================================================================== | |
// intelligent connectivity - now in IGraphBuilder, axextend.idl | |
//========================================================================== | |
//========================================================================== | |
// Whole graph functions | |
//========================================================================== | |
// Once a graph is built, it can behave as a (composite) filter. | |
// To control this filter, QueryInterface for IMediaFilter. | |
// The filtergraph will by default ensure that the graph has a sync source | |
// when it is made to Run. SetSyncSource(NULL) will prevent that and allow | |
// all the filters to run unsynchronised until further notice. | |
// SetDefaultSyncSource will set the default sync source (the same as would | |
// have been set by default on the first call to Run). | |
HRESULT SetDefaultSyncSource(); | |
} | |
const GUID IID_IGraphBuilder = IGraphBuilder.iid; | |
interface IGraphBuilder : IFilterGraph | |
{ | |
static const GUID iid = { 0x56a868a9,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
// Connect these two pins directly or indirectly, using transform filters | |
// if necessary. | |
HRESULT Connect | |
( in IPin ppinOut, // the output pin | |
in IPin ppinIn // the input pin | |
); | |
// Connect this output pin directly or indirectly, using transform filters | |
// if necessary to something that will render it. | |
HRESULT Render | |
( in IPin ppinOut // the output pin | |
); | |
// Build a filter graph that will render this file using this play list. | |
// If lpwstrPlayList is NULL then it will use the default play list | |
// which will typically render the whole file. | |
HRESULT RenderFile | |
( in LPCWSTR lpcwstrFile, | |
/+[ unique /+ AM_ANNOTATION("__in_opt") +/]+/ in LPCWSTR lpcwstrPlayList | |
); | |
// Add to the filter graph a source filter for this file. This would | |
// be the same source filter that would be added by calling Render. | |
// This call gives you more control over building | |
// the rest of the graph, e.g. AddFilter(<a renderer of your choice>) | |
// and then Connect the two. | |
// The IBaseFilter* interface exposed by the source filter is returned | |
// in ppFilter, addrefed already for you | |
// The filter will be known by the name lpcwstrFIlterName | |
// nn this filter graph, | |
HRESULT AddSourceFilter | |
( in LPCWSTR lpcwstrFileName, | |
/+[ unique /+ AM_ANNOTATION("__in_opt") +/]+/ in LPCWSTR lpcwstrFilterName, | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IBaseFilter *ppFilter | |
); | |
// If this call is made then trace information will be written to the | |
// file showing the actions taken in attempting to perform an operation. | |
HRESULT SetLogFile | |
( in DWORD_PTR hFile // open file handle e.g. from CreateFile | |
); | |
// Request that the graph builder should return as soon as possible from | |
// its current task. | |
// Note that it is possible fot the following to occur in the following | |
// sequence: | |
// Operation begins; Abort is requested; Operation completes normally. | |
// This would be normal whenever the quickest way to finish an operation | |
// was to simply continue to the end. | |
HRESULT Abort(); | |
// Return S_OK if the curent operation is to continue, | |
// return S_FALSE if the current operation is to be aborted. | |
// This method can be called as a callback from a filter which is doing | |
// some operation at the request of the graph. | |
HRESULT ShouldOperationContinue(); | |
} | |
alias /+[wire_marshal(wireVARIANT)]+/ tagVARIANT VARIANT; | |
struct tagVARIANT { | |
union { | |
struct /+ __tagVARIANT +/ { | |
VARTYPE vt; | |
WORD wReserved1; | |
WORD wReserved2; | |
WORD wReserved3; | |
union { | |
LONGLONG llVal; /* VT_I8 */ | |
BSTR bstrVal; /* VT_BSTR */ | |
}; | |
}; | |
}; | |
}; | |
alias VARIANT VARIANTARG; | |
struct tagDISPPARAMS | |
{ | |
/+[size_is(cArgs)]+/ VARIANTARG * rgvarg; | |
/+[size_is(cNamedArgs)]+/ DISPID * rgdispidNamedArgs; | |
UINT cArgs; | |
UINT cNamedArgs; | |
} | |
alias tagDISPPARAMS DISPPARAMS; | |
alias ITypeInfo = void*; | |
alias int OAFilterState; | |
struct tagEXCEPINFO | |
{ | |
WORD wCode; | |
WORD wReserved; | |
BSTR bstrSource; | |
BSTR bstrDescription; | |
BSTR bstrHelpFile; | |
DWORD dwHelpContext; | |
PVOID pvReserved; | |
HRESULT /*__stdcall*/ function( EXCEPINFO *) pfnDeferredFillIn; | |
SCODE scode; | |
} | |
alias tagEXCEPINFO EXCEPINFO; alias tagEXCEPINFO * LPEXCEPINFO; | |
const GUID IID_IDispatch = IDispatch.iid; | |
interface IDispatch : IUnknown | |
{ | |
static const GUID iid = { 0x00020400,0x0000,0x0000,[ 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ] }; | |
HRESULT GetTypeInfoCount( | |
/+[out]+/ UINT * pctinfo | |
); | |
HRESULT GetTypeInfo( | |
in UINT iTInfo, | |
in LCID lcid, | |
/+[out]+/ ITypeInfo * ppTInfo | |
); | |
HRESULT GetIDsOfNames( | |
in IID* riid, | |
/+[ size_is (cNames)]+/ in LPOLESTR * rgszNames, | |
/+[ range (0, 16384)]+/ in UINT cNames, | |
in LCID lcid, | |
/+[out, size_is(cNames)]+/ DISPID * rgDispId | |
); | |
/+[local]+/ | |
HRESULT Invoke( | |
in DISPID dispIdMember, | |
in IID* riid, | |
in LCID lcid, | |
in WORD wFlags, | |
/+[in, out]+/ DISPPARAMS * pDispParams, | |
/+[out]+/ VARIANT * pVarResult, | |
/+[out]+/ EXCEPINFO * pExcepInfo, | |
/+[out]+/ UINT * puArgErr | |
); | |
/+[ call_as(Invoke)]+/ final | |
HRESULT RemoteInvoke( | |
in DISPID dispIdMember, | |
in IID* riid, | |
in LCID lcid, | |
in DWORD dwFlags, | |
in DISPPARAMS * pDispParams, | |
/+[out]+/ VARIANT * pVarResult, | |
/+[out]+/ EXCEPINFO * pExcepInfo, | |
/+[out]+/ UINT * pArgErr, | |
in UINT cVarRef, | |
/+[ size_is (cVarRef)]+/ in UINT * rgVarRefIdx, | |
/+[in, out, size_is(cVarRef)]+/ VARIANTARG * rgVarRef | |
); | |
} | |
const GUID IID_IMediaControl = IMediaControl.iid; | |
interface IMediaControl : IDispatch | |
{ | |
static const GUID iid = { 0x56a868b1,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
// methods | |
HRESULT Run(); | |
HRESULT Pause(); | |
HRESULT Stop(); | |
//returns the state. same semantics as IMediaFilter::GetState | |
HRESULT GetState( | |
in LONG msTimeout, | |
/+[out]+/ OAFilterState* pfs); | |
// adds and connects filters needed to play the specified file | |
// (same as IFilterGraph::RenderFile) | |
HRESULT RenderFile( | |
in BSTR strFilename); | |
// adds to the graph the source filter that can read this file, | |
// and returns an IFilterInfo object for it (actually returns | |
// an IDispatch for the IFilterInfo object). | |
HRESULT AddSourceFilter( | |
in BSTR strFilename, | |
/+[out]+/ IDispatch**ppUnk); | |
// get a collection of IFilterInfo objects representing the | |
// filters in the graph (returns IDispatch for an object | |
// that supports IAMCollection | |
/+[propget]+/ | |
HRESULT FilterCollection( | |
/+[out, retval]+/ IDispatch** ppUnk); | |
// get a collection of IRegFilter objects representing the | |
// filters available in the registry | |
/+[propget]+/ | |
HRESULT RegFilterCollection( | |
/+[out, retval]+/ IDispatch** ppUnk); | |
HRESULT StopWhenReady(); | |
} | |
const GUID IID_IFileSinkFilter = IFileSinkFilter.iid; | |
interface IFileSinkFilter : IUnknown | |
{ | |
static const GUID iid = { 0xa2104830,0x7c70,0x11cf,[ 0x8b,0xce,0x00,0xaa,0x00,0xa3,0xf1,0xa6 ] }; | |
// Output to this file. default is to open the existing file | |
HRESULT SetFileName(LPCOLESTR pszFileName, // Pointer to absolute path of output file | |
/+[ unique /+ AM_ANNOTATION("__in_opt") +/]+/ const( AM_MEDIA_TYPE)*pmt // Media type of file - can be NULL | |
); | |
// Get the current file name | |
HRESULT GetCurFile(/+[out /+ AM_ANNOTATION("__out") +/]+/ LPOLESTR *ppszFileName, // Pointer to the path for the current file | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ AM_MEDIA_TYPE *pmt // Pointer to the media type | |
); | |
} | |
const GUID IID_IFileSourceFilter = IFileSourceFilter.iid; | |
interface IFileSourceFilter : IUnknown | |
{ | |
static const GUID iid = { 0x56a868a6,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
// Load a file and assign it the given media type | |
HRESULT Load( | |
in LPCOLESTR pszFileName, // Pointer to absolute path of file to open | |
/+[ unique /+ AM_ANNOTATION("__in_opt") +/]+/ in const( AM_MEDIA_TYPE)*pmt // Media type of file - can be NULL | |
); | |
// Get the currently loaded file name | |
HRESULT GetCurFile( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ LPOLESTR *ppszFileName, // Pointer to the path for the current file | |
/+[out /+ AM_ANNOTATION("__out_opt") +/]+/ AM_MEDIA_TYPE *pmt // Pointer to the media type | |
); | |
} | |
const GUID IID_IAMCopyCaptureFileProgress = IAMCopyCaptureFileProgress.iid; | |
interface IAMCopyCaptureFileProgress : IUnknown | |
{ | |
static const GUID iid = { 0x670d1d20,0xa068,0x11d0,[ 0xb3,0xf0,0x00,0xaa,0x00,0x37,0x61,0xc5 ] }; | |
// If you support this interface somewhere, this function will be called | |
// periodically while ICaptureGraphBuilder::CopyCaptureFile is executing | |
// to let you know the progress | |
// | |
// Return S_OK from this function to continue. Return S_FALSE to abort the | |
// copy | |
HRESULT Progress(int iProgress); | |
} | |
const GUID IID_ICaptureGraphBuilder2 = ICaptureGraphBuilder2.iid; | |
//auto CLSID_CaptureGraphBuilder2 = Guid!"BF87B6E1-8C27-11d0-B3F0-00AA003761C5"; | |
interface ICaptureGraphBuilder2 : IUnknown | |
{ | |
static const GUID iid = { 0x93E5A4E0,0x2D50,0x11d2,[ 0xAB,0xFA,0x00,0xA0,0xC9,0xC6,0xE3,0x8D ] }; | |
// Use this filtergraph | |
HRESULT SetFiltergraph(IGraphBuilder pfg); | |
// what filtergraph are you using? | |
// *ppfg->Release() when you're done with it | |
HRESULT GetFiltergraph(/+[out]+/ IGraphBuilder *ppfg); | |
// creates a rendering section in the filtergraph consisting of a MUX | |
// of some filetype, and a file writer (and connects them together) | |
// *ppf->Release() when you're done with it | |
// *ppSink->Release() when you're done with it | |
HRESULT SetOutputFileName(const( GUID)*pType, // GUID of MUX filter to use | |
LPCOLESTR lpstrFile, // filename given to file writer | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IBaseFilter *ppf, // returns pointer to the MUX | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IFileSinkFilter *ppSink);// queried from file writer | |
// Looks for an interface on the filter and on the output pin of the given | |
// category and type. (Categories: CAPTURE/PREVIEW/VIDEOPORT/VBI etc. or | |
// NULL for "don't care". Type: MAJORTYPE_Video/Audio etc or NULL) | |
// !!! Will some filters have >1 capture pin? ie RGB and MPEG? | |
// It will also look upstream and downstream of | |
// the pin for the interface, to find interfaces on renderers, MUXES, TV | |
// Tuners, etc. | |
// Call *ppint->Release() when you're done with it | |
/+[local]+/ HRESULT FindInterface(/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ const( GUID)*pCategory, // can be NULL for all pins | |
/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ const( GUID)*pType, // Audio/Video/??? or NULL (don't care) | |
IBaseFilter *pf, | |
IID* riid, | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ void **ppint); | |
/+[ call_as(FindInterface)]+/ final HRESULT RemoteFindInterface( | |
/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ const( GUID)*pCategory, // can be NULL for all pins | |
/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ const( GUID)*pType, // Audio/Video/??? or NULL (don't care) | |
in IBaseFilter pf, | |
in IID* riid, | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IUnknown *ppint); | |
// Connects the pin of the given category and type of the source filter to | |
// the rendering filter, optionally through another filter (compressor?) | |
// (Type is a Majortype, like Video or Audio) | |
// For a non-NULL category, it will instantiate and connect additional | |
// required filters upstream too, like TV Tuners and Crossbars. | |
// If there is only one output pin on the source, use a NULL category | |
// and type. You can also have pSource be a pin | |
HRESULT RenderStream( | |
/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ const( GUID)*pCategory, // can be NULL if only one output pin | |
const( GUID)*pType, // Major type (Video/Audio/etc) | |
/+[in]+/ IUnknown pSource, // filter or pin | |
IBaseFilter pfCompressor, | |
IBaseFilter pfRenderer); // can be NULL | |
// Sends IAMStreamControl messages to the pin of the desired category, | |
// (eg. "capture" or "preview") and of the desired type (eg. VIDEO or AUDIO) | |
// A category MUST be given. If a filter is given, a type must be too. | |
// REFERENCE_TIME=NULL means NOW | |
// REFERENCE_TIME=MAX_TIME means never, or cancel previous request | |
// NULL controls all capture filters in the graph - you will get one | |
// notification for each filter with a pin of that category found | |
// returns S_FALSE if stop will be signalled before last sample is | |
// rendered. | |
// return a FAILURE code if the filter does not support IAMStreamControl | |
HRESULT ControlStream( | |
const( GUID)*pCategory, | |
const( GUID)*pType, // Major type (Video/Audio/etc) | |
IBaseFilter pFilter, | |
/+[/+ AM_ANNOTATION("__in_opt") +/]+/ REFERENCE_TIME *pstart, | |
/+[/+ AM_ANNOTATION("__in_opt") +/]+/ REFERENCE_TIME *pstop, | |
WORD wStartCookie, // high word reserved | |
WORD wStopCookie); // high word reserved | |
// creates a pre-allocated file of a given size in bytes | |
HRESULT AllocCapFile(LPCOLESTR lpstr, | |
DWORDLONG dwlSize); | |
// Copies the valid file data out of the old, possibly huge old capture | |
// file into a shorter new file. | |
// Return S_FALSE from your progress function to abort capture, S_OK to | |
// continue | |
HRESULT CopyCaptureFile( | |
/+[in /+ AM_ANNOTATION("__in") +/]+/ LPOLESTR lpwstrOld, | |
/+[in /+ AM_ANNOTATION("__in") +/]+/ LPOLESTR lpwstrNew, | |
in int fAllowEscAbort, // pressing ESC will abort? | |
/+[in]+/ IAMCopyCaptureFileProgress pCallback); // implement this to | |
// get progress | |
// Helper fn to find a certain pin on a filter. | |
HRESULT FindPin( | |
/+[in]+/ IUnknown pSource, | |
PIN_DIRECTION pindir, // input or output? | |
/+[/+ AM_ANNOTATION("__in_opt") +/]+/ const( GUID)*pCategory, // what category? (or NULL) | |
/+[/+ AM_ANNOTATION("__in_opt") +/]+/ const( GUID)*pType, // what Major type (or NULL) | |
BOOL fUnconnected, // must it be unconnected? | |
int num, // which pmatching this? (0 based) | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ IPin **ppPin); | |
} | |
const GUID IID_IMediaSample = IMediaSample.iid; | |
interface IMediaSample : IUnknown | |
{ | |
static const GUID iid = { 0x56a8689a,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
// get me a read/write pointer to this buffer's memory. I will actually | |
// want to use sizeUsed bytes. | |
HRESULT GetPointer(/+[out, annotation("__out")]+/ BYTE ** ppBuffer) @nogc; | |
// return the size in bytes of the buffer data area | |
int GetSize(); | |
// get the stream time at which this sample should start and finish. | |
HRESULT GetTime( | |
/+[out, annotation("__out")]+/ REFERENCE_TIME * pTimeStart, // put time here | |
/+[out, annotation("__out")]+/ REFERENCE_TIME * pTimeEnd | |
); | |
// Set the stream time at which this sample should start and finish. | |
// pTimeStart==pTimeEnd==NULL will invalidate the time stamps in | |
// this sample | |
HRESULT SetTime( | |
/+[ annotation ("__in_opt")]+/ in REFERENCE_TIME * pTimeStart, // put time here | |
/+[ annotation ("__in_opt")]+/ in REFERENCE_TIME * pTimeEnd | |
); | |
// sync-point property. If true, then the beginning of this | |
// sample is a sync-point. (note that if AM_MEDIA_TYPE.bTemporalCompression | |
// is false then all samples are sync points). A filter can start | |
// a stream at any sync point. S_FALSE if not sync-point, S_OK if true. | |
HRESULT IsSyncPoint(); | |
HRESULT SetSyncPoint(BOOL bIsSyncPoint); | |
// preroll property. If true, this sample is for preroll only and | |
// shouldn't be displayed. | |
HRESULT IsPreroll(); | |
HRESULT SetPreroll(BOOL bIsPreroll); | |
int GetActualDataLength() @nogc; | |
HRESULT SetActualDataLength(int); | |
// these allow for limited format changes in band - if no format change | |
// has been made when you receive a sample GetMediaType will return S_FALSE | |
HRESULT GetMediaType(/+[out, annotation("__out")]+/ AM_MEDIA_TYPE **ppMediaType); | |
HRESULT SetMediaType(/+[ annotation ("__in")]+/ in AM_MEDIA_TYPE *pMediaType); | |
// returns S_OK if there is a discontinuity in the data (this frame is | |
// not a continuation of the previous stream of data | |
// - there has been a seek or some dropped samples). | |
HRESULT IsDiscontinuity(); | |
// set the discontinuity property - TRUE if this sample is not a | |
// continuation, but a new sample after a seek or a dropped sample. | |
HRESULT SetDiscontinuity(BOOL bDiscontinuity); | |
// get the media times for this sample | |
HRESULT GetMediaTime( | |
/+[out, annotation("__out")]+/ LONGLONG * pTimeStart, | |
/+[out, annotation("__out")]+/ LONGLONG * pTimeEnd | |
); | |
// Set the media times for this sample | |
// pTimeStart==pTimeEnd==NULL will invalidate the media time stamps in | |
// this sample | |
HRESULT SetMediaTime( | |
/+[ annotation ("__in_opt")]+/ in LONGLONG * pTimeStart, | |
/+[ annotation ("__in_opt")]+/ in LONGLONG * pTimeEnd | |
); | |
} | |
const GUID IID_ISampleGrabberCB = ISampleGrabberCB.iid; | |
interface ISampleGrabberCB : IUnknown | |
{ | |
static const GUID iid = { 0x0579154A,0x2B53,0x4994,[ 0xB0,0xD0,0xE7,0x73,0x14,0x8E,0xFF,0x85 ] }; | |
HRESULT SampleCB( double SampleTime, IMediaSample pSample ); | |
HRESULT BufferCB( double SampleTime, BYTE * pBuffer, int BufferLen ); | |
} | |
const GUID IID_ISampleGrabber = ISampleGrabber.iid; | |
//CLSID_SampleGrabber = Guid!("C1F400A0-3F08-11d3-9F0B-006008039E37") | |
interface ISampleGrabber : IUnknown | |
{ | |
static const GUID iid = { 0x6B652FFF,0x11FE,0x4fce,[ 0x92,0xAD,0x02,0x66,0xB5,0xD7,0xC7,0x8F ] }; | |
// set this to have the filter immediate stop after | |
// garnishing a sample | |
// | |
HRESULT SetOneShot( BOOL OneShot ); | |
// set what media type we connect to. It can be partially | |
// specified by setting only the major type, OR the major and | |
// subtype, OR major, subtype, and the formattype. | |
// | |
HRESULT SetMediaType( const( AM_MEDIA_TYPE)* pType ); | |
// after something's connected to this filter, find out | |
// what it is | |
// | |
HRESULT GetConnectedMediaType( AM_MEDIA_TYPE * pType ); | |
// call this to buffer incoming samples, so the next two methods will work | |
// If this is not called, the next two methods will return | |
// E_INVALIDARG | |
// | |
HRESULT SetBufferSamples( BOOL BufferThem ); | |
// pass in NULL for pBuffer to get out the buffer size you need to | |
// allocate. This will NOT return a pointer to a compressed dib | |
// any longer! It will return the IMediaSample's GetPointer buffer. | |
// | |
HRESULT GetCurrentBuffer( /+[in,out]+/ int * pBufferSize, | |
/+[out]+/ int * pBuffer ); | |
// return the currently buffered sample | |
// | |
HRESULT GetCurrentSample( /+[out,retval]+/ IMediaSample * ppSample ); | |
// if this callback is set, then it will be called for | |
// every sample passing through the filter. Do not take a long time | |
// in the callback for smooth playback (obviously!) | |
// | |
HRESULT SetCallback(ISampleGrabberCB pCallback, int WhichMethodToCallback ); | |
}; | |
enum /+ AM_SEEKING_SeekingFlags+/ | |
{ | |
AM_SEEKING_NoPositioning = 0x00, // No change | |
AM_SEEKING_AbsolutePositioning = 0x01, // Position is supplied and is absolute | |
AM_SEEKING_RelativePositioning = 0x02, // Position is supplied and is relative | |
AM_SEEKING_IncrementalPositioning = 0x03, // (Stop) position relative to current | |
// Useful for seeking when paused (use +1) | |
AM_SEEKING_PositioningBitsMask = 0x03, // Useful mask | |
AM_SEEKING_SeekToKeyFrame = 0x04, // Just seek to key frame (performance gain) | |
AM_SEEKING_ReturnTime = 0x08, // Plug the media time equivalents back into the supplied LONGLONGs | |
AM_SEEKING_Segment = 0x10, // At end just do EC_ENDOFSEGMENT, | |
// don't do EndOfStream | |
AM_SEEKING_NoFlush = 0x20 | |
} | |
alias int AM_SEEKING_SeekingFlags; | |
alias int AM_SEEKING_SEEKING_FLAGS; | |
enum /+ AM_SEEKING_SeekingCapabilities+/ | |
{ | |
AM_SEEKING_CanSeekAbsolute = 0x001, | |
AM_SEEKING_CanSeekForwards = 0x002, | |
AM_SEEKING_CanSeekBackwards = 0x004, | |
AM_SEEKING_CanGetCurrentPos = 0x008, | |
AM_SEEKING_CanGetStopPos = 0x010, | |
AM_SEEKING_CanGetDuration = 0x020, | |
AM_SEEKING_CanPlayBackwards = 0x040, | |
AM_SEEKING_CanDoSegments = 0x080, | |
AM_SEEKING_Source = 0x100 | |
} | |
alias int AM_SEEKING_SeekingCapabilities; | |
alias int AM_SEEKING_SEEKING_CAPABILITIES; | |
const GUID IID_IMediaSeeking = IMediaSeeking.iid; | |
interface IMediaSeeking : IUnknown | |
{ | |
static const GUID iid = { 0x36b73880,0xc2c8,0x11cf,[ 0x8b,0x46,0x00,0x80,0x5f,0x6c,0xef,0x60 ] }; | |
// Returns the capability flags | |
HRESULT GetCapabilities( /+[out /+ AM_ANNOTATION("__out") +/]+/ DWORD * pCapabilities ); | |
// And's the capabilities flag with the capabilities requested. | |
// Returns S_OK if all are present, S_FALSE if some are present, E_FAIL if none. | |
// *pCababilities is always updated with the result of the 'and'ing and can be | |
// checked in the case of an S_FALSE return code. | |
HRESULT CheckCapabilities( /+[in,out]+/ DWORD * pCapabilities ); | |
// returns S_OK if mode is supported, S_FALSE otherwise | |
HRESULT IsFormatSupported(in const( GUID)* pFormat); | |
HRESULT QueryPreferredFormat(/+[out /+ AM_ANNOTATION("__out") +/]+/ GUID * pFormat); | |
HRESULT GetTimeFormat(/+[out /+ AM_ANNOTATION("__out") +/]+/ GUID *pFormat); | |
// Returns S_OK if *pFormat is the current time format, otherwise S_FALSE | |
// This may be used instead of the above and will save the copying of the GUID | |
HRESULT IsUsingTimeFormat(in const( GUID)* pFormat); | |
// (may return VFE_E_WRONG_STATE if graph is stopped) | |
HRESULT SetTimeFormat(in const( GUID)* pFormat); | |
// return current properties | |
HRESULT GetDuration(/+[out /+ AM_ANNOTATION("__out") +/]+/ LONGLONG *pDuration); | |
HRESULT GetStopPosition(/+[out /+ AM_ANNOTATION("__out") +/]+/ LONGLONG *pStop); | |
HRESULT GetCurrentPosition(/+[out /+ AM_ANNOTATION("__out") +/]+/ LONGLONG *pCurrent); | |
// Convert time from one format to another. | |
// We must be able to convert between all of the formats that we say we support. | |
// (However, we can use intermediate formats (e.g. MEDIA_TIME).) | |
// If a pointer to a format is null, it implies the currently selected format. | |
HRESULT ConvertTimeFormat(/+[out /+ AM_ANNOTATION("__out") +/]+/ LONGLONG * pTarget, | |
/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ const( GUID)* pTargetFormat, | |
in LONGLONG Source, | |
/+[in /+ AM_ANNOTATION("__in_opt") +/]+/ const( GUID)* pSourceFormat ); | |
// Set current and end positions in one operation | |
// Either pointer may be null, implying no change | |
HRESULT SetPositions( /+[in,out /+ AM_ANNOTATION("__inout_opt") +/]+/ LONGLONG * pCurrent, in DWORD dwCurrentFlags | |
, | |
/+[in,out /+ AM_ANNOTATION("__inout_opt") +/]+/ LONGLONG * pStop, in DWORD dwStopFlags ); | |
// Get CurrentPosition & StopTime | |
// Either pointer may be null, implying not interested | |
HRESULT GetPositions( /+[out /+ AM_ANNOTATION("__out_opt") +/]+/ LONGLONG * pCurrent, | |
/+[out /+ AM_ANNOTATION("__out_opt") +/]+/ LONGLONG * pStop ); | |
// Get earliest / latest times to which we can currently seek "efficiently". | |
// This method is intended to help with graphs where the source filter has | |
// a very high latency. Seeking within the returned limits should just | |
// result in a re-pushing of already cached data. Seeking beyond these | |
// limits may result in extended delays while the data is fetched (e.g. | |
// across a slow network). | |
// (NULL pointer is OK, means caller isn't interested.) | |
HRESULT GetAvailable( /+[out /+ AM_ANNOTATION("__out_opt") +/]+/ LONGLONG * pEarliest, | |
/+[out /+ AM_ANNOTATION("__out_opt") +/]+/ LONGLONG * pLatest ); | |
// Rate stuff | |
HRESULT SetRate(in double dRate); | |
HRESULT GetRate(/+[out /+ AM_ANNOTATION("__out") +/]+/ double * pdRate); | |
// Preroll | |
HRESULT GetPreroll(/+[out /+ AM_ANNOTATION("__out") +/]+/ LONGLONG * pllPreroll); | |
} | |
////////////////////////////// | |
struct _COAUTHIDENTITY | |
{ | |
// User and Password length from lmcons.h | |
// Domain length === FQDN length which is 256 | |
/+[size_is(UserLength+1)]+/ USHORT * User; | |
/+[range(0,256)]+/ULONG UserLength; | |
/+[size_is(DomainLength+1)]+/ USHORT * Domain; | |
/+[range(0,256)]+/ULONG DomainLength; | |
/+[size_is(PasswordLength+1)]+/ USHORT * Password; | |
/+[range(0,256)]+/ULONG PasswordLength; | |
ULONG Flags; | |
} | |
alias _COAUTHIDENTITY COAUTHIDENTITY; | |
struct _COAUTHINFO | |
{ | |
DWORD dwAuthnSvc; | |
DWORD dwAuthzSvc; | |
LPWSTR pwszServerPrincName; | |
DWORD dwAuthnLevel; | |
DWORD dwImpersonationLevel; | |
COAUTHIDENTITY * pAuthIdentityData; | |
DWORD dwCapabilities; | |
} | |
alias _COAUTHINFO COAUTHINFO; | |
struct _COSERVERINFO | |
{ | |
DWORD dwReserved1; | |
LPWSTR pwszName; | |
COAUTHINFO * pAuthInfo; | |
DWORD dwReserved2; | |
} | |
alias _COSERVERINFO COSERVERINFO; | |
/+[__struct_bcount(cbStruct)]+/ struct tagBIND_OPTS | |
{ | |
DWORD cbStruct; | |
DWORD grfFlags; | |
DWORD grfMode; | |
DWORD dwTickCountDeadline; | |
} | |
alias tagBIND_OPTS BIND_OPTS; alias tagBIND_OPTS * LPBIND_OPTS; | |
struct tagBIND_OPTS2 | |
{ tagBIND_OPTS base; | |
DWORD dwTrackFlags; | |
DWORD dwClassContext; | |
LCID locale; | |
COSERVERINFO * pServerInfo; | |
} | |
alias tagBIND_OPTS2 BIND_OPTS2; | |
const GUID IID_IRunningObjectTable = IRunningObjectTable.iid; | |
interface IRunningObjectTable : IUnknown | |
{ | |
static const GUID iid = { 0x00000010,0x0000,0x0000,[ 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ] }; | |
HRESULT Register | |
( | |
in DWORD grfFlags, | |
/+[ unique]+/ /+[in]+/ IUnknown punkObject, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkObjectName, | |
/+[out]+/ DWORD *pdwRegister | |
); | |
HRESULT Revoke | |
( | |
in DWORD dwRegister | |
); | |
HRESULT IsRunning | |
( | |
/+[ unique]+/ /+[in]+/ IMoniker pmkObjectName | |
); | |
HRESULT GetObject | |
( | |
/+[ unique]+/ /+[in]+/ IMoniker pmkObjectName, | |
/+[out]+/ IUnknown *ppunkObject | |
); | |
HRESULT NoteChangeTime | |
( | |
in DWORD dwRegister, | |
in FILETIME *pfiletime | |
); | |
HRESULT GetTimeOfLastChange | |
( | |
/+[ unique]+/ /+[in]+/ IMoniker pmkObjectName, | |
/+[out]+/ FILETIME *pfiletime | |
); | |
HRESULT EnumRunning | |
( | |
/+[out]+/ IEnumMoniker *ppenumMoniker | |
); | |
} | |
const GUID IID_IEnumString = IEnumString.iid; | |
interface IEnumString : IUnknown | |
{ | |
static const GUID iid = { 0x00000101,0x0000,0x0000,[ 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ] }; | |
/+[local]+/ | |
HRESULT Next( | |
in ULONG celt, | |
/+[out, size_is(celt), length_is(*pceltFetched), annotation("__RPC__out_ecount_part(celt,*pceltFetched)")]+/ | |
LPOLESTR *rgelt, | |
/+[out]+/ ULONG *pceltFetched); | |
/+[ call_as(Next)]+/ final | |
HRESULT RemoteNext( | |
in ULONG celt, | |
/+[out, size_is(celt), length_is(*pceltFetched)]+/ | |
LPOLESTR *rgelt, | |
/+[out]+/ ULONG *pceltFetched); | |
HRESULT Skip( | |
in ULONG celt); | |
HRESULT Reset(); | |
HRESULT Clone( | |
/+[out]+/ IEnumString *ppenum); | |
} | |
const GUID IID_IBindCtx = IBindCtx.iid; | |
interface IBindCtx : IUnknown | |
{ | |
static const GUID iid = { 0x0000000e,0x0000,0x0000,[ 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ] }; | |
HRESULT RegisterObjectBound | |
( | |
/+[ unique]+/ /+[in]+/ IUnknown punk | |
); | |
HRESULT RevokeObjectBound | |
( | |
/+[ unique]+/ /+[in]+/ IUnknown punk | |
); | |
HRESULT ReleaseBoundObjects | |
(); | |
/+[local]+/ | |
HRESULT SetBindOptions | |
( | |
in BIND_OPTS *pbindopts | |
); | |
/+[ call_as(SetBindOptions)]+/ final | |
HRESULT RemoteSetBindOptions | |
( | |
in BIND_OPTS2 *pbindopts | |
); | |
/+[local]+/ | |
HRESULT GetBindOptions | |
( | |
/+[in, out]+/ BIND_OPTS *pbindopts | |
); | |
/+[ call_as(GetBindOptions)]+/ final | |
HRESULT RemoteGetBindOptions | |
( | |
/+[in, out]+/ BIND_OPTS2 *pbindopts | |
); | |
HRESULT GetRunningObjectTable | |
( | |
/+[out]+/ IRunningObjectTable *pprot | |
); | |
HRESULT RegisterObjectParam( | |
in LPOLESTR pszKey, | |
/+[ unique]+/ /+[in]+/ IUnknown punk | |
); | |
HRESULT GetObjectParam( | |
in LPOLESTR pszKey, | |
/+[out]+/ IUnknown *ppunk | |
); | |
HRESULT EnumObjectParam | |
( | |
/+[out]+/ IEnumString *ppenum | |
); | |
HRESULT RevokeObjectParam | |
( | |
in LPOLESTR pszKey | |
); | |
} | |
const GUID IID_IMoniker = IMoniker.iid; | |
interface IMoniker : IPersistStream | |
{ | |
static const GUID iid = { 0x0000000f,0x0000,0x0000,[ 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ] }; | |
/+[local]+/ | |
HRESULT BindToObject( | |
/+[ unique]+/ /+[in]+/ IBindCtx pbc, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkToLeft, | |
in IID* riidResult, | |
/+[out, iid_is(riidResult)]+/ void **ppvResult); | |
/+[ call_as(BindToObject)]+/ final | |
HRESULT RemoteBindToObject( | |
/+[ unique]+/ /+[in]+/ IBindCtx pbc, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkToLeft, | |
in IID* riidResult, | |
/+[out, iid_is(riidResult)]+/ IUnknown *ppvResult); | |
/+[local]+/ | |
HRESULT BindToStorage( | |
/+[ unique]+/ /+[in]+/ IBindCtx pbc, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkToLeft, | |
in IID* riid, | |
/+[out, iid_is(riid)]+/ void **ppvObj); | |
/+[ call_as(BindToStorage)]+/ final | |
HRESULT RemoteBindToStorage( | |
/+[ unique]+/ /+[in]+/ IBindCtx pbc, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkToLeft, | |
in IID* riid, | |
/+[out, iid_is(riid)]+/ IUnknown *ppvObj); | |
HRESULT Reduce( | |
/+[ unique]+/ /+[in]+/ IBindCtx pbc, | |
in DWORD dwReduceHowFar, | |
/+[in, out, unique]+/ IMoniker *ppmkToLeft, | |
/+[out]+/ IMoniker *ppmkReduced); | |
HRESULT ComposeWith( | |
/+[ unique]+/ /+[in]+/ IMoniker pmkRight, | |
in BOOL fOnlyIfNotGeneric, | |
/+[out]+/ IMoniker *ppmkComposite); | |
HRESULT Enum( | |
in BOOL fForward, | |
/+[out]+/ IEnumMoniker *ppenumMoniker); | |
HRESULT IsEqual( | |
/+[ unique]+/ /+[in]+/ IMoniker pmkOtherMoniker); | |
HRESULT Hash( | |
/+[out]+/ DWORD *pdwHash); | |
HRESULT IsRunning( | |
/+[ unique]+/ /+[in]+/ IBindCtx pbc, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkToLeft, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkNewlyRunning); | |
HRESULT GetTimeOfLastChange( | |
/+[ unique]+/ /+[in]+/ IBindCtx pbc, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkToLeft, | |
/+[out]+/ FILETIME *pFileTime); | |
HRESULT Inverse( | |
/+[out]+/ IMoniker *ppmk); | |
HRESULT CommonPrefixWith( | |
/+[ unique]+/ /+[in]+/ IMoniker pmkOther, | |
/+[out]+/ IMoniker *ppmkPrefix); | |
HRESULT RelativePathTo( | |
/+[ unique]+/ /+[in]+/ IMoniker pmkOther, | |
/+[out]+/ IMoniker *ppmkRelPath); | |
HRESULT GetDisplayName( | |
/+[ unique]+/ /+[in]+/ IBindCtx pbc, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkToLeft, | |
/+[out]+/ LPOLESTR *ppszDisplayName); | |
HRESULT ParseDisplayName( | |
/+[ unique]+/ /+[in]+/ IBindCtx pbc, | |
/+[ unique]+/ /+[in]+/ IMoniker pmkToLeft, | |
in LPOLESTR pszDisplayName, | |
/+[out]+/ ULONG *pchEaten, | |
/+[out]+/ IMoniker *ppmkOut); | |
HRESULT IsSystemMoniker( | |
/+[out]+/ DWORD *pdwMksys); | |
} | |
const GUID IID_IErrorLog = IErrorLog.iid; | |
interface IErrorLog : IUnknown | |
{ | |
static const GUID iid = { 0x3127CA40,0x446E,0x11CE,[ 0x81,0x35,0x00,0xAA,0x00,0x4B,0xB8,0x51 ] }; | |
HRESULT AddError( | |
in LPCOLESTR pszPropName, | |
in EXCEPINFO * pExcepInfo | |
); | |
} | |
//const GUID IID_IPropertyBag = IPropertyBag.iid; | |
interface IPropertyBag : IUnknown | |
{ | |
static const GUID iid = { 0x55272A00,0x42CB,0x11CE,[ 0x81,0x35,0x00,0xAA,0x00,0x4B,0xB8,0x51 ] }; | |
/+[local]+/ | |
HRESULT Read( | |
in LPCOLESTR pszPropName, | |
/+[in, out]+/ VARIANT * pVar, | |
/+[ unique]+/ /+[in]+/ IErrorLog pErrorLog | |
); | |
/+[ call_as(Read)]+/ final | |
HRESULT RemoteRead( | |
in LPCOLESTR pszPropName, | |
/+[out]+/ VARIANT * pVar, | |
/+[ unique]+/ /+[in]+/ IErrorLog pErrorLog, | |
in DWORD varType, | |
/+[in]+/ IUnknown pUnkObj | |
); | |
HRESULT Write( | |
in LPCOLESTR pszPropName, | |
in VARIANT * pVar | |
); | |
} | |
const GUID IID_IEnumMoniker = IEnumMoniker.iid; | |
interface IEnumMoniker : IUnknown | |
{ | |
static const GUID iid = { 0x00000102,0x0000,0x0000,[ 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ] }; | |
/+[local]+/ | |
HRESULT Next( | |
in ULONG celt, | |
/+[out, size_is(celt), length_is(*pceltFetched)]+/ | |
IMoniker *rgelt, | |
/+[out]+/ ULONG *pceltFetched); | |
/+[ call_as(Next)]+/ final | |
HRESULT RemoteNext( | |
in ULONG celt, | |
/+[out, size_is(celt), length_is(*pceltFetched)]+/ | |
IMoniker *rgelt, | |
/+[out]+/ ULONG *pceltFetched); | |
HRESULT Skip( | |
in ULONG celt); | |
HRESULT Reset(); | |
HRESULT Clone( | |
/+[out]+/ IEnumMoniker *ppenum); | |
} | |
const GUID IID_ISequentialStream = ISequentialStream.iid; | |
interface ISequentialStream : IUnknown | |
{ | |
static const GUID iid = { 0x0c733a30,0x2a1c,0x11ce,[ 0xad,0xe5,0x00,0xaa,0x00,0x44,0x77,0x3d ] }; | |
/+[local]+/ | |
HRESULT Read( | |
/+[out, size_is(cb), length_is(*pcbRead)]+/ | |
void *pv, | |
in ULONG cb, | |
/+[out]+/ ULONG *pcbRead); | |
/+[ call_as(Read)]+/ final | |
HRESULT RemoteRead( | |
/+[out, size_is(cb), length_is(*pcbRead)]+/ | |
byte *pv, | |
in ULONG cb, | |
/+[out]+/ ULONG *pcbRead); | |
/+[local]+/ | |
HRESULT Write( | |
/+[ size_is (cb)]+/ in const(void)*pv, | |
in ULONG cb, | |
/+[out]+/ ULONG *pcbWritten); | |
/+[ call_as(Write)]+/ final | |
HRESULT RemoteWrite( | |
/+[ size_is (cb)]+/ in const(byte)*pv, | |
in ULONG cb, | |
/+[out]+/ ULONG *pcbWritten); | |
} | |
const GUID IID_IStream = IStream.iid; | |
interface IStream : ISequentialStream | |
{ | |
static const GUID iid = { 0x0000000c,0x0000,0x0000,[ 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ] }; | |
/+[local]+/ | |
HRESULT Seek( | |
in LARGE_INTEGER dlibMove, | |
in DWORD dwOrigin, | |
/+[out]+/ ULARGE_INTEGER *plibNewPosition); | |
/+[ call_as(Seek)]+/ final | |
HRESULT RemoteSeek( | |
in LARGE_INTEGER dlibMove, | |
in DWORD dwOrigin, | |
/+[out]+/ ULARGE_INTEGER *plibNewPosition); | |
HRESULT SetSize( | |
in ULARGE_INTEGER libNewSize); | |
/+[local]+/ | |
HRESULT CopyTo( | |
/+[ unique]+/ /+[in]+/ IStream pstm, | |
in ULARGE_INTEGER cb, | |
/+[out]+/ ULARGE_INTEGER *pcbRead, | |
/+[out]+/ ULARGE_INTEGER *pcbWritten); | |
/+[ call_as(CopyTo)]+/ final | |
HRESULT RemoteCopyTo( | |
/+[ unique]+/ /+[in]+/ IStream pstm, | |
in ULARGE_INTEGER cb, | |
/+[out]+/ ULARGE_INTEGER *pcbRead, | |
/+[out]+/ ULARGE_INTEGER *pcbWritten); | |
HRESULT Commit( | |
in DWORD grfCommitFlags); | |
HRESULT Revert(); | |
HRESULT LockRegion( | |
in ULARGE_INTEGER libOffset, | |
in ULARGE_INTEGER cb, | |
in DWORD dwLockType); | |
HRESULT UnlockRegion( | |
in ULARGE_INTEGER libOffset, | |
in ULARGE_INTEGER cb, | |
in DWORD dwLockType); | |
HRESULT Stat( | |
/+[out]+/ STATSTG *pstatstg, | |
in DWORD grfStatFlag); | |
HRESULT Clone( | |
/+[out]+/ IStream *ppstm); | |
} | |
struct tagSTATSTG | |
{ | |
LPOLESTR pwcsName; | |
DWORD type; | |
ULARGE_INTEGER cbSize; | |
FILETIME mtime; | |
FILETIME ctime; | |
FILETIME atime; | |
DWORD grfMode; | |
DWORD grfLocksSupported; | |
CLSID clsid; | |
DWORD grfStateBits; | |
DWORD reserved; | |
} | |
alias tagSTATSTG STATSTG; | |
const GUID IID_IPersistStream = IPersistStream.iid; | |
interface IPersistStream : IPersist | |
{ | |
static const GUID iid = { 0x00000109,0x0000,0x0000,[ 0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 ] }; | |
HRESULT IsDirty | |
(); | |
HRESULT Load | |
( | |
/+[ unique]+/ /+[in]+/ IStream pStm | |
); | |
HRESULT Save | |
( | |
/+[ unique]+/ /+[in]+/ IStream pStm, | |
in BOOL fClearDirty | |
); | |
HRESULT GetSizeMax | |
( | |
/+[out]+/ ULARGE_INTEGER *pcbSize | |
); | |
} | |
const GUID IID_ICreateDevEnum = ICreateDevEnum.iid; | |
interface ICreateDevEnum : IUnknown | |
{ | |
static const GUID iid = { 0x29840822,0x5B84,0x11D0,[ 0xBD,0x3B,0x00,0xA0,0xC9,0x11,0xCE,0x86 ] }; | |
//public import sdk.port.oaidl; | |
HRESULT CreateClassEnumerator( | |
in CLSID* clsidDeviceClass, | |
IEnumMoniker * ppEnumMoniker, | |
in DWORD dwFlags); | |
} | |
const GUID IID_IAMVfwCompressDialogs = IAMVfwCompressDialogs.iid; | |
interface IAMVfwCompressDialogs : IUnknown | |
{ | |
static const GUID iid = { 0xD8D715A3,0x6E5E,0x11D0,[ 0xB3,0xF0,0x00,0xAA,0x00,0x37,0x61,0xC5 ] }; | |
// Bring up a dialog for this codec | |
HRESULT ShowDialog( | |
in int iDialog, // VfwCompressDialogs enum | |
in HWND hwnd | |
); | |
// Calls ICGetState and gives you the result | |
HRESULT GetState( | |
/+[out, size_is(*pcbState), annotation("__out_bcount_part(*pcbState, *pcbState)")]+/ LPVOID pState, | |
/+[in, out, annotation("__inout")]+/ int *pcbState | |
); | |
// Calls ICSetState | |
HRESULT SetState( | |
/+[ size_is (cbState), annotation("__in_bcount(cbState)")]+/ in LPVOID pState, | |
in int cbState | |
); | |
// Send a codec specific message | |
HRESULT SendDriverMessage( | |
in int uMsg, | |
in int dw1, | |
in int dw2 | |
); | |
} | |
const GUID IID_ISpecifyPropertyPages = ISpecifyPropertyPages.iid; | |
interface ISpecifyPropertyPages : IUnknown | |
{ | |
static const GUID iid = { 0xB196B28B,0xBAB4,0x101A,[ 0xB6,0x9C,0x00,0xAA,0x00,0x34,0x1D,0x07 ] }; | |
HRESULT GetPages( | |
/+[out]+/ CAUUID * pPages | |
); | |
} | |
struct tagCAUUID | |
{ | |
ULONG cElems; | |
/+[size_is(cElems)]+/ GUID * pElems; | |
} | |
alias tagCAUUID CAUUID; | |
const GUID IID_IAMStreamConfig = IAMStreamConfig.iid; | |
interface IAMStreamConfig : IUnknown | |
{ | |
static const GUID iid = { 0xC6E13340,0x30AC,0x11d0,[ 0xA1,0x8C,0x00,0xA0,0xC9,0x11,0x89,0x56 ] }; | |
// - only allowed when pin is not streaming, else the call will FAIL | |
// - If your output pin is not yet connected, and you can | |
// connect your output pin with this media type, you should | |
// succeed the call, and start offering it first (enumerate as format#0) | |
// from GetMediaType so that this format will be used to connect with | |
// when you do connect to somebody | |
// - if your output pin is already connected, and you can provide this | |
// type, reconnect your pin. If the other pin can't accept it, FAIL | |
// this call and leave your connection alone. | |
HRESULT SetFormat( | |
in AM_MEDIA_TYPE *pmt); | |
// the format it's connected with, or will connect with | |
// the application is responsible for calling DeleteMediaType(*ppmt); | |
HRESULT GetFormat( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ AM_MEDIA_TYPE **ppmt); | |
// how many different Stream Caps structures are there? | |
// also, how big is the stream caps structure? | |
HRESULT GetNumberOfCapabilities( | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ int *piCount, | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ int *piSize); // pSCC of GetStreamCaps needs to be this big | |
// - gets one of the pairs of {Mediatype, Caps} | |
// - return S_FALSE if iIndex is too high | |
// - the application is responsible for calling DeleteMediaType(*ppmt); | |
// - the first thing pSCC points to is a GUID saying MEDIATYPE_Video | |
// or MEDIATYPE_Audio, so you can tell if you have a pointer to a | |
// VIDEO_STREAM_CONFIG_CAPS or an AUDIO_STREAM_CONFIG_CAPS structure | |
// There could potentially be many more possibilities other than video | |
// or audio. | |
HRESULT GetStreamCaps( | |
in int iIndex, // 0 to #caps-1 | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ AM_MEDIA_TYPE **ppmt, | |
/+[out /+ AM_ANNOTATION("__out") +/]+/ BYTE *pSCC); | |
} | |
alias LONG_PTR OAEVENT; // should be a HANDLE | |
enum EvCode { EC_COMPLETE = 0x01, EC_USERABORT = 0x02, EC_ERRORABORT = 0x03 } //from evcode.h | |
const GUID IID_IMediaEvent = IMediaEvent.iid; | |
interface IMediaEvent : IDispatch | |
{ | |
static const GUID iid = { 0x56a868b6,0x0ad4,0x11ce,[ 0xb0,0x3a,0x00,0x20,0xaf,0x0b,0xa7,0x70 ] }; | |
// get back the event handle. This is manual-reset | |
// (don't - it's reset by the event mechanism) and remains set | |
// when events are queued, and reset when the queue is empty. | |
HRESULT GetEventHandle( | |
/+[out]+/ OAEVENT * hEvent); | |
// remove the next event notification from the head of the queue and | |
// return it. Waits up to msTimeout millisecs if there are no events. | |
// if a timeout occurs without any events, this method will return | |
// E_ABORT, and the value of the event code and other parameters | |
// is undefined. | |
// | |
// If this call returns successfully the caller MUST call | |
// FreeEventParams(lEventCode, lParam1, lParam2) to release | |
// resources held inside the event arguments | |
// | |
HRESULT GetEvent( | |
/+[out]+/ int * lEventCode, | |
/+[out]+/ LONG_PTR * lParam1, | |
/+[out]+/ LONG_PTR * lParam2, | |
in int msTimeout | |
); | |
// Calls GetEvent repeatedly discarding events until it finds a | |
// completion event (EC_COMPLETE, EC_ERRORABORT, or EC_USERABORT). | |
// The completion event is removed from the queue and returned | |
// in pEvCode. Note that the object is still in running mode until | |
// a Pause or Stop call is made. | |
// If the timeout occurs, *pEvCode will be 0 and E_ABORT will be | |
// returned. | |
HRESULT WaitForCompletion( | |
in int msTimeout, | |
/+[out]+/ int * pEvCode); | |
// cancels any system handling of the specified event code | |
// and ensures that the events are passed straight to the application | |
// (via GetEvent) and not handled. A good example of this is | |
// EC_REPAINT: default handling for this ensures the painting of the | |
// window and does not get posted to the app. | |
HRESULT CancelDefaultHandling( | |
in int lEvCode); | |
// restore the normal system default handling that may have been | |
// cancelled by CancelDefaultHandling(). | |
HRESULT RestoreDefaultHandling( in int lEvCode); | |
// Free any resources associated with the parameters to an event. | |
// Event parameters may be LONGs, IUnknown* or BSTR. No action | |
// is taken with LONGs. IUnknown are passed addrefed and need a | |
// Release call. BSTR are allocated by the task allocator and will be | |
// freed by calling the task allocator. | |
HRESULT FreeEventParams( | |
in int lEvCode, | |
in LONG_PTR lParam1, | |
in LONG_PTR lParam2 | |
); | |
} | |
extern(Windows) { | |
HRESULT OleCreatePropertyFrame(HWND hwndOwner, UINT x, UINT y, | |
LPCOLESTR lpszCaption, ULONG cObjects, LPUNKNOWN * ppUnk, ULONG cPages, | |
LPCLSID pPageClsID, LCID lcid, DWORD dwReserved, LPVOID pvReserved); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment