Skip to content

Instantly share code, notes, and snippets.

@thedeemon
Last active April 26, 2016 04:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thedeemon/46748f91afdbcf339f55da9b355a6b56 to your computer and use it in GitHub Desktop.
Save thedeemon/46748f91afdbcf339f55da9b355a6b56 to your computer and use it in GitHub Desktop.
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