//------------------------------------------------------------------------------
// File: QEdit.idl
//
// Copyright (c) 1992 - 2002, Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------------------------


import "oaidl.idl";
import "ocidl.idl";
import "dxtrans.idl";
import "amstream.idl";
import "msxml.idl";

//
// forward declare
//
interface IAMTimelineGroup;
interface IAMTimelineObj;
interface IAMTimelineEffect;
interface IAMTimelineTrans;
interface IAMTimelineSrc;
interface IAMTimeline;
interface IAMErrorLog;
interface ISampleGrabber;
interface IPropertySetter;

// used by DEXTER_VALUE's dwInterp var
typedef enum
{
    DEXTERF_JUMP,
    DEXTERF_INTERPOLATE
} DEXTERF;

// used to set values on the property setter
typedef struct
{
    BSTR Name;
    DISPID dispID;
    LONG nValues;
} DEXTER_PARAM;

// used to set values on the property setter
typedef struct
{
    VARIANT v;
    REFERENCE_TIME rt;
    DWORD dwInterp;    // one of the DEXTERF_ flags
} DEXTER_VALUE;

// used by bMethod directly below
enum
{
    DEXTER_AUDIO_JUMP,
    DEXTER_AUDIO_INTERPOLATE
};

// used to set volumes on the mixer and mixer pins
typedef struct
{
    REFERENCE_TIME        rtEnd;        //end Time
    double                dLevel;    //end Volume Level
    BOOL                bMethod;    //jump or interpolate
} DEXTER_AUDIO_VOLUMEENVELOPE ;

// used in IAMTimeline::Get(Set)InsertMode
enum
{
    TIMELINE_INSERT_MODE_INSERT = 1,
    TIMELINE_INSERT_MODE_OVERLAY = 2
};

//
// define what main 'things' can be put into the timeline tree.
// these values are used quite a bit with timeline access
// (bitmap mask flags)
typedef enum
{
    TIMELINE_MAJOR_TYPE_COMPOSITE = 1,
    TIMELINE_MAJOR_TYPE_TRACK = 2,
    TIMELINE_MAJOR_TYPE_SOURCE = 4,
    TIMELINE_MAJOR_TYPE_TRANSITION = 8,
    TIMELINE_MAJOR_TYPE_EFFECT = 16,
    TIMELINE_MAJOR_TYPE_GROUP = 128
} TIMELINE_MAJOR_TYPE;

// used in various IAMTimelineXXX "search" functions. Look in this
// file for "SearchDirection" to see where it's used. I didn't want
// to use an enum as an interface param type, so I used a long. 
typedef enum
{
    DEXTERF_BOUNDING = -1,        // finds any source whose start <= Time and stop > Time
    DEXTERF_EXACTLY_AT = 0,        // finds any source that starts exactly at Time
    DEXTERF_FORWARDS = 1        // finds any source that starts at or after Time
} DEXTERF_TRACK_SEARCH_FLAGS;

// right now, the media type in the group contains enough information about
// how we want to recompress. This might not be enough information in the 
// future, so we define a structure we can get and set to the group. 
//
typedef struct _SCompFmt0
{
    long nFormatId;
    AM_MEDIA_TYPE MediaType;
} SCompFmt0;

// used in IAMTimelineSrc::Get(Set)StretchMode
// 
enum
{
    RESIZEF_STRETCH,
    RESIZEF_CROP,
    RESIZEF_PRESERVEASPECTRATIO,
    RESIZEF_PRESERVEASPECTRATIO_NOLETTERBOX
};

// used in IRenderEngine::SetDynamicReconnectLevel
// (bitmap mask flags)
enum
{
    CONNECTF_DYNAMIC_NONE = 0x00000000,
    CONNECTF_DYNAMIC_SOURCES = 0x00000001,
    CONNECTF_DYNAMIC_EFFECTS = 0x00000002
};

// used in
// IMediaLocator::FindMediaFile
// IRenderEngine::SetSourceNameValidation
// IAMTimeline::ValidateSourceNames
// (bitmap mask flags)
enum
{
    SFN_VALIDATEF_CHECK        = 0x00000001,   // do a check. Without this set, no check will be done.
    SFN_VALIDATEF_POPUP        = 0x00000002,   // should UI popup show if not found
    SFN_VALIDATEF_TELLME       = 0x00000004,   // warn user about replaced files
    SFN_VALIDATEF_REPLACE      = 0x00000008,   // should it replace names in the tldb if found
    SFN_VALIDATEF_USELOCAL     = 0x000000010,  // use local media preferrably over networked media
    SFN_VALIDATEF_NOFIND       = 0x000000020,  // never find filenames, always use UI popup to find.,
                                               // when used, _POPUP must be used as well
    SFN_VALIDATEF_IGNOREMUTED  = 0x000000040,  // ignore muted files in the tldb
    SFN_VALIDATEF_END
};

// key transitions types
enum
{
    DXTKEY_RGB,        
    DXTKEY_NONRED,         
    DXTKEY_LUMINANCE,      
    DXTKEY_ALPHA,          
    DXTKEY_HUE
};


////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// New Property setting Interfaces
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////

// interface for objects which can save/load IDispatch-able properties
[
    object,
    uuid(AE9472BD-B0C3-11D2-8D24-00A0C9441E20),
    helpstring("IPropertySetter Interface"),
    pointer_default(unique)
]
interface IPropertySetter : IUnknown // IPersist?
{
    // for loading and saving through XML
    HRESULT LoadXML([in] IUnknown * pxml);
    // !!! doesn't work HRESULT LoadXML([in] IXMLElement * pxml);
    HRESULT PrintXML([out] char *pszXML, [in] int cbXML, [out] int *pcbPrinted,[in] int indent);
         
    // for cloning a portion of the props when splitting the object
    //AUTOMATE
    HRESULT CloneProps([out] IPropertySetter **ppSetter,
            [in] REFERENCE_TIME rtStart,
            [in] REFERENCE_TIME rtStop);

    // for loading and saving programmatically
    // caller must call this in pre-sorted order, this time must be > all
    // previous times
    //AUTOMATE
    HRESULT AddProp([in] DEXTER_PARAM Param,
            [in] DEXTER_VALUE *paValue);
    //AUTOMATE
    HRESULT GetProps([out] LONG *pcParams,
             [out] DEXTER_PARAM **paParam,
            [out] DEXTER_VALUE **paValue);
    // after calling GetProps, you must call FreeProps to free resources
    //AUTOMATE
    HRESULT FreeProps([in] LONG cParams,
            [in] DEXTER_PARAM *paParam,
            [in] DEXTER_VALUE *paValue);
    // to empty to property setter, so you can start over again
    HRESULT ClearProps();

    // for persisting
    HRESULT SaveToBlob([out] LONG *pcSize, [out] BYTE **ppb);
    HRESULT LoadFromBlob([in] LONG cSize, [in] BYTE *pb);

    // to program the object that supports IDispatch with the props
    // call with rtNow == -1 to set Static Props when your object instantiates
    // errors will be logged, if a log is provided
    //AUTOMATE
    HRESULT SetProps([in] IUnknown *pTarget,
            [in] REFERENCE_TIME rtNow);

    // unicode version
    HRESULT PrintXMLW([out] WCHAR *pszXML, [in] int cchXML, [out] int *pcchPrinted,[in] int indent);
};

// supported by our DxtCompositor class, this allows us to draw whatever comes in
// upon only a portion of the output bitmap

[
    object,
    uuid(BB44391E-6ABD-422f-9E2E-385C9DFF51FC),
    dual,
    helpstring("IDxtCompositor Interface"),
    pointer_default(unique)
]
interface IDxtCompositor : IDXEffect
{
    [propget, id(1), helpstring("property OffsetX")] HRESULT OffsetX([out, retval] long *pVal);
    [propput, id(1), helpstring("property OffsetX")] HRESULT OffsetX([in] long newVal);
    [propget, id(2), helpstring("property OffsetY")] HRESULT OffsetY([out, retval] long *pVal);
    [propput, id(2), helpstring("property OffsetY")] HRESULT OffsetY([in] long newVal);
    [propget, id(3), helpstring("property Width")] HRESULT Width([out, retval] long *pVal);
    [propput, id(3), helpstring("property Width")] HRESULT Width([in] long newVal);
    [propget, id(4), helpstring("property Height")] HRESULT Height([out, retval] long *pVal);
    [propput, id(4), helpstring("property Height")] HRESULT Height([in] long newVal);

    [propget, id(5), helpstring("property SrcOffsetX")] HRESULT SrcOffsetX([out, retval] long *pVal);
    [propput, id(5), helpstring("property SrcOffsetX")] HRESULT SrcOffsetX([in] long newVal);
    [propget, id(6), helpstring("property SrcOffsetY")] HRESULT SrcOffsetY([out, retval] long *pVal);
    [propput, id(6), helpstring("property SrcOffsetY")] HRESULT SrcOffsetY([in] long newVal);
    [propget, id(7), helpstring("property SrcWidth")] HRESULT SrcWidth([out, retval] long *pVal);
    [propput, id(7), helpstring("property SrcWidth")] HRESULT SrcWidth([in] long newVal);
    [propget, id(8), helpstring("property SrcHeight")] HRESULT SrcHeight([out, retval] long *pVal);
    [propput, id(8), helpstring("property SrcHeight")] HRESULT SrcHeight([in] long newVal);
};

[
    object,
    uuid(4EE9EAD9-DA4D-43d0-9383-06B90C08B12B),
    dual,
    helpstring("IDxtAlphaSetter Interface"),
    pointer_default(unique)
]
interface IDxtAlphaSetter : IDXEffect
{
    // set the alpha to a particular number
    [propget, id(1), helpstring("property Alpha")] HRESULT Alpha([out, retval] long *pVal);
    [propput, id(1), helpstring("property Alpha")] HRESULT Alpha([in] long newVal);

    // set the alpha to a percentage of it's full value
    [propget, id(2), helpstring("property AlphaRamp")] HRESULT AlphaRamp([out, retval] double *pVal);
    [propput, id(2), helpstring("property AlphaRamp")] HRESULT AlphaRamp([in] double newVal);
};

// Supported by our JPEG DXT, that can do any wipe based on a bitmap
//

[
    object,
    uuid(DE75D011-7A65-11D2-8CEA-00A0C9441E20),
    dual,
    helpstring("IDxtJpeg Interface"),
    pointer_default(unique)
]
interface IDxtJpeg : IDXEffect
{
    [propget, id(1), helpstring("property MaskNum")] HRESULT MaskNum([out, retval] long *);
    [propput, id(1), helpstring("property MaskNum")] HRESULT MaskNum([in] long);
    [propget, id(2), helpstring("property MaskName")] HRESULT MaskName([out, retval] BSTR *pVal);
    [propput, id(2), helpstring("property MaskName")] HRESULT MaskName([in] BSTR newVal);
    [propget, id(3), helpstring("property ScaleX")] HRESULT ScaleX([out, retval] double *);
    [propput, id(3), helpstring("property ScaleX")] HRESULT ScaleX([in] double);
    [propget, id(4), helpstring("property ScaleY")] HRESULT ScaleY([out, retval] double *);
    [propput, id(4), helpstring("property ScaleY")] HRESULT ScaleY([in] double);
    [propget, id(5), helpstring("property OffsetX")] HRESULT OffsetX([out, retval] long *);
    [propput, id(5), helpstring("property OffsetX")] HRESULT OffsetX([in] long);
    [propget, id(6), helpstring("property OffsetY")] HRESULT OffsetY([out, retval] long *);
    [propput, id(6), helpstring("property OffsetY")] HRESULT OffsetY([in] long);
    [propget, id(7), helpstring("property ReplicateX")] HRESULT ReplicateX([out, retval] long *pVal);
    [propput, id(7), helpstring("property ReplicateX")] HRESULT ReplicateX([in] long newVal);
    [propget, id(8), helpstring("property ReplicateY")] HRESULT ReplicateY([out, retval] long *pVal);
    [propput, id(8), helpstring("property ReplicateY")] HRESULT ReplicateY([in] long newVal);
    [propget, id(9), helpstring("property BorderColor")] HRESULT BorderColor([out, retval] long *pVal);
    [propput, id(9), helpstring("property BorderColor")] HRESULT BorderColor([in] long newVal);
    [propget, id(10), helpstring("property BorderWidth")] HRESULT BorderWidth([out, retval] long *pVal);
    [propput, id(10), helpstring("property BorderWidth")] HRESULT BorderWidth([in] long newVal);
    [propget, id(11), helpstring("property BorderSoftness")] HRESULT BorderSoftness([out, retval] long *pVal);
    [propput, id(11), helpstring("property BorderSoftness")] HRESULT BorderSoftness([in] long newVal);
    HRESULT ApplyChanges();
    HRESULT LoadDefSettings();
};

    // key
    [
        object,
        uuid(3255de56-38fb-4901-b980-94b438010d7b),
        dual,
        helpstring("IDxtKey Interface"),
        pointer_default(unique)
    ]
    interface IDxtKey : IDXEffect
    {
        [propget, id(1), helpstring("property KeyType")]    HRESULT KeyType([out, retval] int *);
        [propput, id(1), helpstring("property Keytype")]    HRESULT KeyType([in] int);
        [propget, id(2), helpstring("property Hue")]   HRESULT Hue([out, retval] int *);
        [propput, id(2), helpstring("property Hue")]   HRESULT Hue([in] int );
        [propget, id(3), helpstring("property Luminance")]   HRESULT Luminance([out, retval] int *);
        [propput, id(3), helpstring("property Luminance")]   HRESULT Luminance([in] int );
        [propget, id(4), helpstring("property RGB")]    HRESULT RGB([out, retval] DWORD *);
        [propput, id(4), helpstring("property RGB")]    HRESULT RGB([in] DWORD );
        [propget, id(5), helpstring("property Similarity")]  HRESULT Similarity([out,retval] int * );
        [propput, id(5), helpstring("property Similarity")]  HRESULT Similarity([in] int );
        [propget, id(6), helpstring("property Invert")]    HRESULT Invert([out, retval] BOOL *);
        [propput, id(6), helpstring("property Invert")]    HRESULT Invert([in] BOOL);
    };

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // This little COM interface will look 'around' for the closest 
    // path match for a given file. If the file already exists, then
    // this interface should hardly do anything. If it's not found,
    // it will go look for it and if successful, return S_FALSE. If it
    // cannot find the file, it will call the hook, if set and return
    // it's return code. if the hook is not set, it is in a type of
    // error condition. The Dexter-provided MediaLocator will bring up
    // a dialog box asking you to browse for your file. Other COM
    // objects may do something else.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(288581E0-66CE-11d2-918F-00C0DF10D434),
    odl,
    helpstring("IMediaLocator Interface"),
    pointer_default(unique)
]
interface IMediaLocator : IUnknown
{
    // same flags as used by IRenderEngine's SetSourceNameValidation
    HRESULT FindMediaFile( BSTR Input, BSTR FilterString, BSTR * pOutput, long Flags );
    HRESULT AddFoundLocation( BSTR DirectoryName );
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // This object provides caching of duration and stream type
    // information for files that would produce a directshow source
    // filter. It takes too long to figure this out in DShow right
    // now, so this is one way around it. The way it works is that
    // you first fill out the Filename property, then call and
    // ask how many streams it has, or, set the CurrentStream prop
    // and then ask for the per-stream properties, StreamType or
    // StreamLength. They both reference the CurrentStream prop that
    // you set. I also allowed you (for convenience) to just give
    // it a IUnknown Filter that represents an IBaseFilter source
    // filter that is NOT currently in a graph. It will use that
    // instead. When using this, though, you will not get cached
    // values. The cached values are stored in the system's ini file
    // called DCBC2A70-70D8-4459-BFFA-E0D61DEA3FDF.INI. Nice, huh? :-)
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(65BD0710-24D2-4ff7-9324-ED2E5D3ABAFA),
    odl,
    helpstring("IMediaDet Interface"),
    pointer_default(unique)
]
interface IMediaDet : IUnknown
{
    [propget, id(1), helpstring("property Filter")] HRESULT Filter([out, retval] IUnknown* *pVal);
    [propput, id(1), helpstring("property Filter")] HRESULT Filter([in] IUnknown* newVal);
    [propget, id(2), helpstring("property OutputStreams")] HRESULT OutputStreams([out, retval] long *pVal);
    [propget, id(3), helpstring("property CurrentStream")] HRESULT CurrentStream([out, retval] long *pVal);
    [propput, id(3), helpstring("property CurrentStream")] HRESULT CurrentStream([in] long newVal);
    [propget, id(4), helpstring("property StreamType")] HRESULT StreamType([out, retval] GUID *pVal);
    [propget, id(5), helpstring("property StreamTypeB")] HRESULT StreamTypeB([out, retval] BSTR *pVal);
    [propget, id(6), helpstring("property StreamLength")] HRESULT StreamLength([out, retval] double *pVal);
    [propget, id(7), helpstring("property Filename")] HRESULT Filename([out, retval] BSTR *pVal);
    [propput, id(7), helpstring("property Filename")] HRESULT Filename([in] BSTR newVal);
    [id(8), helpstring("method GetBitmapBits")] HRESULT GetBitmapBits(double StreamTime, long * pBufferSize, char * pBuffer, long Width, long Height);
    [id(9), helpstring("method WriteBitmapBits")] HRESULT WriteBitmapBits(double StreamTime, long Width, long Height, BSTR Filename );
    [propget, id(10), helpstring("property StreamMediaType")] HRESULT StreamMediaType([out, retval] AM_MEDIA_TYPE * pVal);
    [id(11), helpstring("method GetSampleGrabber")] HRESULT GetSampleGrabber( [out] ISampleGrabber ** ppVal );
    [propget, id(12), helpstring("property FrameRate")] HRESULT FrameRate([out, retval] double *pVal);
    [id(13), helpstring("method EnterBitmapGrabMode")] HRESULT EnterBitmapGrabMode( double SeekTime  );
};


// useless interface, don't use it!

[
    object,
    uuid(AE9472BE-B0C3-11D2-8D24-00A0C9441E20),
    odl,
    helpstring("IGrfCache Interface"),
    pointer_default(unique)
]
interface IGrfCache : IDispatch
{
    [id(1), helpstring("method AddFilter")] 
    HRESULT AddFilter(
        IGrfCache * ChainedCache,
        LONGLONG ID, 
        const IBaseFilter * pFilter, 
        LPCWSTR pName);

    [id(2), helpstring("method ConnectPins")] 
    HRESULT ConnectPins(
        IGrfCache * ChainedCache,
        LONGLONG PinID1, 
        const IPin * pPin1, 
        LONGLONG PinID2, 
        const IPin * pPin2);

    [id(3), helpstring("method SetGraph")] 
    HRESULT SetGraph(const IGraphBuilder * pGraph);

    [id(4), helpstring("method DoConnectionsNow")] 
    HRESULT DoConnectionsNow();
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // The RenderEngin builds a graph from the timeline and gives
    // you some simple positional commands.
    // explained methods:
    // SetTimelineObject - tell the render engine who to parse
    // ConnectEverything - build up a graph based on the timeline
    // ScrapIt - throw away graph and everything
    // GetFilterGraph - get the graph that's built up, if any
    // SetFilterGraph - allows you to preset the graph that's built up.
    //      cannot call this if there already is a graph.

    // !!! the following methods are unused/not implemented

    // SetInterestRange - discard COM objects and memory outside of this
    //      range, if possible. Used for scrubbing on a long timeline and
    //      freeing up resources
    // SetRenderRange - pretend like a portion of the timeline IS the timeline
    //      and don't connect anything in the graph outside of that range.
    // Commit - allocate what's necessary and get prepared to run
    // Decommit - free anything possible
    // GetCaps - find out some info about the render engine
    // DoSmartRecompression - connect compressed sources if 
    //      possible
    // in the graph, this will RenderPin( ) on every switcher 
    //      rendering pin.
    // SetSourceNameValidation - allows you to set some flags which
    // determine how source files are found, if they need to be found.
    //      FilterString is a list of extensions to find for the media
    //      files (see OPENFILENAME filters)
    //      pOverride is a media locator you would like to use instead
    //      of the built in one
    //      The flags are defined in the struct immediately below.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(6BEE3A81-66C9-11d2-918F-00C0DF10D434),
    odl,
    helpstring("IRenderEngine Interface"),
    pointer_default(unique)
]
interface IRenderEngine : IUnknown
{
    HRESULT SetTimelineObject( IAMTimeline * pTimeline );
    HRESULT GetTimelineObject( [out] IAMTimeline ** ppTimeline );
    HRESULT GetFilterGraph( [out] IGraphBuilder ** ppFG );
    HRESULT SetFilterGraph( IGraphBuilder * pFG );
    HRESULT SetInterestRange( REFERENCE_TIME Start, REFERENCE_TIME Stop );
    HRESULT SetInterestRange2( double Start, double Stop );
    HRESULT SetRenderRange( REFERENCE_TIME Start, REFERENCE_TIME Stop );
    HRESULT SetRenderRange2( double Start, double Stop );
    HRESULT GetGroupOutputPin( long Group, [out] IPin ** ppRenderPin );
    HRESULT ScrapIt( );
    HRESULT RenderOutputPins( );
    HRESULT GetVendorString( [out,retval] BSTR * pVendorID );
    HRESULT ConnectFrontEnd( );
    HRESULT SetSourceConnectCallback( IGrfCache * pCallback );
    HRESULT SetDynamicReconnectLevel( long Level );
    HRESULT DoSmartRecompression( );
    HRESULT UseInSmartRecompressionGraph( );

    HRESULT SetSourceNameValidation( BSTR FilterString, IMediaLocator * pOverride, LONG Flags );

    // not implemented yet
    HRESULT Commit( );
    HRESULT Decommit( );
    HRESULT GetCaps( long Index, long * pReturn );
};

[
    object,
    uuid(6BEE3A82-66C9-11d2-918F-00C0DF10D434),
    odl,
    helpstring("IRenderEngine2 Interface"),
    pointer_default(unique)
]
interface IRenderEngine2 : IUnknown
{
    HRESULT SetResizerGUID( GUID ResizerGuid );
}

// used for the smart render engine when it needs to find a compressor
[
    object,
    uuid(F03FA8DE-879A-4d59-9B2C-26BB1CF83461),
    odl,
    helpstring("IFindCompressorCB Interface"),
    pointer_default(unique)
]
interface IFindCompressorCB : IUnknown
{
    HRESULT GetCompressor( AM_MEDIA_TYPE * pType, AM_MEDIA_TYPE * pCompType, [out] IBaseFilter ** ppFilter );
}

[
    object,
    uuid(F03FA8CE-879A-4d59-9B2C-26BB1CF83461),
    odl,
    helpstring("ISmartRenderEngine Interface"),
    pointer_default(unique)
]
interface ISmartRenderEngine : IUnknown
{
    HRESULT SetGroupCompressor( long Group, IBaseFilter * pCompressor );
    HRESULT GetGroupCompressor( long Group, IBaseFilter ** pCompressor );
    HRESULT SetFindCompressorCB( IFindCompressorCB * pCallback );
}                  

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// TIMELINE TIMELINE TIMELINE TIMELINE TIMELINE TIMELINE
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Every object on the timeline supports at least this interface.
    // explained methods:
    // Get/SetStartStop - the timeline times at which this object is
    //      active. Groups and Tracks have start times of zero.
    // FixTimes - used by the render engine. Rounds the input times
    //      to the nearest FPS of the parent Group, for use in setting
    //      up the big switch.
    // GetSubObject - get the sub-object which is associated with this
    //      timeline object. Each timeline object can carry around a
    //      pointer to 'something else'. For our Render Engine, this is
    //      a pointer to a filter that gets put into a graph. 
    // NOTE: Getting the subobject will FORCE it to load if it's possible
    //      to force this. If you don't want it to do this, don't call
    //      this function.
    // SetSubObject - see GetSubObject
    // SetSubObjectGUID - instead of giving the node a pointer, you can
    //      instead give it a GUID and see if this works instead. The
    //      sub-object will attempt to be instantiated when 'necessary'
    //      which is really when it's asked for with GetSubObject./
    //      !!! a better way to do this perhaps?
    // GetSubObjectLoaded - ask if the sub-object pointer is set
    // Get/SetTimelineType - return the major type which is stored here,
    //      used by the API user and the render engine.
    // Get/SetTimelineSubType - see above
    // Get/SetUserID - get and set a number, any number
    // GetGenID - every created object has a unique number to it. Used
    //      by the render engine.
    // Get/SetUserName - a storable name, for users of the API
    // Get/SetPropertySetter - the object that will set properties for this
    //      object (it will support IPropertySetter and it is created by 
    //      CPropertySetter)
    // Get/SetUserData - gets the persistant data used by the user of
    //      the API.
    // Get/SetMuted - set whether this object should be active or not.
    //      Setting a parent of other objects off also turns off the
    //      sub-objects.
    // Get/SetLocked - set whether you can edit this object or not.
    //      Note: the timeline doesn't enforce this, it just stores
    //      a value for convenience.
    // Get/SetDirtyRange - 
    // RemoveAll - remove this object, and if in the tree already, all it's
    //        sub objects, including children
    // Remove - remove this object, and if in the tree already, all it's
    //        sub objects, but not kids
    // GetTimelineNoRef - called internally by the timeline.
    // GetGroupIBelongTo - called internally by the timeline.
    // GetEmbedDepth - find out how many tracks we are a part of
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    local,
    uuid(78530B77-61F9-11D2-8CAD-00A024580902),
    odl,
    helpstring("IAMTimelineObj Interface"),
    pointer_default(unique)
]
interface IAMTimelineObj : IUnknown
{
    [helpstring("method GetStartStop")] 
    HRESULT GetStartStop(REFERENCE_TIME * pStart, REFERENCE_TIME * pStop);
    [helpstring("method GetStartStop2")] 
    HRESULT GetStartStop2(REFTIME * pStart, REFTIME * pStop);
    [helpstring("method FixTimes")] 
    HRESULT FixTimes(REFERENCE_TIME * pStart, REFERENCE_TIME * pStop);
    [helpstring("method FixTimes2")] 
    HRESULT FixTimes2(REFTIME * pStart, REFTIME * pStop);
    [helpstring("method SetStartStop")] 
    HRESULT SetStartStop(REFERENCE_TIME Start, REFERENCE_TIME Stop);
    [helpstring("method SetStartStop2")] 
    HRESULT SetStartStop2(REFTIME Start, REFTIME Stop);
    [helpstring("method GetPropertySetter")] 
    HRESULT GetPropertySetter([out,retval] IPropertySetter* *pVal);
    [helpstring("method SetPropertySetter")] 
    HRESULT SetPropertySetter(IPropertySetter* newVal);
    [helpstring("method GetSubObject")] 
    HRESULT GetSubObject([out,retval] IUnknown* *pVal);
    [helpstring("method SetSubObject")] 
    HRESULT SetSubObject(IUnknown* newVal);
    [helpstring("method SetSubObjectGUID")] 
    HRESULT SetSubObjectGUID(GUID newVal);
    [helpstring("method SetSubObjectGUIDByBSTR")] 
    HRESULT SetSubObjectGUIDB(BSTR newVal);
    [helpstring("method GetSubObjectGUID")] 
    HRESULT GetSubObjectGUID(GUID * pVal);
    [helpstring("method GetSubObjectGUIDByBSTR")] 
    HRESULT GetSubObjectGUIDB([out,retval] BSTR * pVal);
    [helpstring("method GetSubObjectLoaded")] 
    HRESULT GetSubObjectLoaded(BOOL * pVal);
    [helpstring("method GetTimelineType")] 
    HRESULT GetTimelineType(TIMELINE_MAJOR_TYPE * pVal);
    [helpstring("method SetTimelineType")] 
    HRESULT SetTimelineType(TIMELINE_MAJOR_TYPE newVal);
    [helpstring("method GetUserID")] 
    HRESULT GetUserID(long * pVal);
    [helpstring("method SetUserID")] 
    HRESULT SetUserID(long newVal);
    [helpstring("method GetGenID")] 
    HRESULT GetGenID( long * pVal );
    [helpstring("method GetUserName")] 
    HRESULT GetUserName([out,retval] BSTR * pVal);
    [helpstring("method SetUserName")] 
    HRESULT SetUserName(BSTR newVal);
    [helpstring("method GetUserData")] 
    HRESULT GetUserData(BYTE * pData, long * pSize);
    [helpstring("method SetUserData")] 
    HRESULT SetUserData(BYTE * pData, long Size);
    [helpstring("method GetMuted")] 
    HRESULT GetMuted(BOOL * pVal);
    [helpstring("method SetMuted")] 
    HRESULT SetMuted(BOOL newVal);
    [helpstring("method GetLocked")] 
    HRESULT GetLocked(BOOL * pVal);
    [helpstring("method SetLocked")] 
    HRESULT SetLocked(BOOL newVal);
    [helpstring("method GetDirtyRange")] 
    HRESULT GetDirtyRange(REFERENCE_TIME * pStart, REFERENCE_TIME * pStop);
    [helpstring("method GetDirtyRange")] 
    HRESULT GetDirtyRange2(REFTIME * pStart, REFTIME * pStop);
    [helpstring("method SetDirtyRange")] 
    HRESULT SetDirtyRange(REFERENCE_TIME Start, REFERENCE_TIME Stop);
    [helpstring("method SetDirtyRange")] 
    HRESULT SetDirtyRange2(REFTIME Start, REFTIME Stop);
    [helpstring("method ClearDirty")] 
    HRESULT ClearDirty( );
    [helpstring("method Remove")] 
    HRESULT Remove();
    [helpstring("method RemoveAll")] 
    HRESULT RemoveAll();
    HRESULT GetTimelineNoRef( IAMTimeline ** ppResult );
    HRESULT GetGroupIBelongTo( [out] IAMTimelineGroup ** ppGroup );
    HRESULT GetEmbedDepth( long * pVal );
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Any object on the timeline that can have an effect put on it 
    // implements this interface. This includes sources, tracks, and
    // compositions.
    // explained methods:
    // EffectInsBefore - insert an effect at the given priority onto
    //      this object. The effect's times will be clipped within
    //      this object's bounds. Use -1 to specify 'at the end' for priority.
    //      You cannot have two effects at the same priority.
    // EffectSwapPriorities - swaparoo two effects. Makes undo easier to
    //      implement.
    // EffectGetCount - get how many effects are applied to this object.
    // GetEffect - get the nth effect applied to this object
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

[
    object,
    uuid(EAE58537-622E-11d2-8CAD-00A024580902),
    odl,
    helpstring("IAMTimelineEffectable Interface"),
    pointer_default(unique)
]
interface IAMTimelineEffectable : IUnknown
{
    [helpstring("method EffectInsBefore")] 
    HRESULT EffectInsBefore(IAMTimelineObj * pFX, long priority);
    [helpstring("method EffectSwapPriorities")] 
    HRESULT EffectSwapPriorities(long PriorityA, long PriorityB);
    [helpstring("method EffectGetCount")] 
    HRESULT EffectGetCount(long * pCount);
    [helpstring("method GetEffect")] 
    HRESULT GetEffect([out] IAMTimelineObj ** ppFx, long Which);
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Any effect on the timeline will support at least this interface.
    // NOTE: The Start/Stop times on this object are RELATIVE to their
    // parent's, as are all start/stop times.
    // explained methods:
    // EffectGetPriority - finds out this effect's priority related to the others.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(BCE0C264-622D-11d2-8CAD-00A024580902),
    odl,
    helpstring("IAMTimelineEffect Interface"),
    pointer_default(unique)
]
interface IAMTimelineEffect : IUnknown
{
    [helpstring("method EffectGetPriority")] 
    HRESULT EffectGetPriority(long * pVal);
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Any object on the timeline that can have a transition put on it
    // implements this interface
    // explained methods:
    // TransAdd - add a transition on this object. Multiple trans's on 
    //      the same object cannot overlap in time. Transitions' times
    //      must lie within the bounds of their parent.
    // TransGetCount - get how many transitions are applied to this
    //      object.
    // GetNextTrans - given a time, get the next transition that happens
    //      on this object after that time. On exit, the input time is
    //      set to the start time of the transition.
    // GetTransAtTime - find a transition forwards or backwards from
    //        a given spot. See DEXTERF_TRACK_SEARCH_FLAGS enum.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(378FA386-622E-11d2-8CAD-00A024580902),
    odl,
    helpstring("IAMTimelineTransable Interface"),
    pointer_default(unique)
]
interface IAMTimelineTransable : IUnknown
{
    [helpstring("method TransAdd")] 
    HRESULT TransAdd(IAMTimelineObj * pTrans);
    [helpstring("method TransGetCount")] 
    HRESULT TransGetCount(long * pCount);
    [helpstring("method GetNextTrans")] 
    HRESULT GetNextTrans([out] IAMTimelineObj ** ppTrans, REFERENCE_TIME * pInOut);
    [helpstring("method GetNextTrans2")] 
    HRESULT GetNextTrans2([out] IAMTimelineObj ** ppTrans, REFTIME * pInOut);
    [helpstring("method GetTransAtTime")] 
    HRESULT GetTransAtTime(
        [out] IAMTimelineObj ** ppObj, 
        REFERENCE_TIME Time, 
        long SearchDirection ); 
    [helpstring("method GetTransAtTime2")] 
    HRESULT GetTransAtTime2([out] IAMTimelineObj ** ppObj, REFTIME Time, long SearchDirection ); 
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Any object on the timeline that can be split into two will
    // implement this interface. Namely, source, effects, and transitions
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(A0F840A0-D590-11d2-8D55-00A0C9441E20),
    odl,
    helpstring("IAMTimelineSplittable Interface"),
    pointer_default(unique)
]
interface IAMTimelineSplittable : IUnknown
{
    HRESULT SplitAt(REFERENCE_TIME Time);
    HRESULT SplitAt2(REFTIME Time);
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Any trans on the timeline will support at least this interface.
    // NOTE: The Start/Stop times on this object are RELATIVE to their
    // parent's, as are all start/stop times.
    // explained methods:
    // GetCutPoint - get where this transition should cut from A to B
    //      if the transition were not applied.
    // GetA2B - get if this transition is to go from A->B or B->A.
    // GetBackwards - get if this transition should run backwards.
    // GetCutsOnly - force no transition, force doing a cut
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(BCE0C265-622D-11d2-8CAD-00A024580902),
    odl,
    helpstring("IAMTimelineTrans Interface"),
    pointer_default(unique)
]
interface IAMTimelineTrans : IUnknown
{
    [helpstring("method GetCutPoint")] 
    HRESULT GetCutPoint(REFERENCE_TIME * pTLTime);
    [helpstring("method GetCutPoint2")] 
    HRESULT GetCutPoint2(REFTIME * pTLTime);
    [helpstring("method SetCutPoint")] 
    HRESULT SetCutPoint(REFERENCE_TIME TLTime);
    [helpstring("method SetCutPoint2")]
    HRESULT SetCutPoint2(REFTIME TLTime);
    [helpstring("method GetSwapInputs")] 
    HRESULT GetSwapInputs( BOOL * pVal );
    [helpstring("method SetSwapInputs")] 
    HRESULT SetSwapInputs( BOOL pVal );
    [helpstring("method GetCutsOnly")] 
    HRESULT GetCutsOnly( BOOL * pVal );
    [helpstring("method SetCutsOnly")] 
    HRESULT SetCutsOnly( BOOL pVal );
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Sources represent any source media object on the timeline.
    // They extend an IAMTimelineObj to include media start and stop
    // times, a media name (which could represent darned near anything),
    // and a StreamNumber, which defines which stream out of a potential
    // many this stream represents from a source clip.
    // explained methods:
    // ModifyStopTime - like calling SetStartStop, but this method just
    //      adjusts the tail end of the clip.
    // FixMediaTimes - called by the render engine to round times to
    //      this source clip's parent group's FPS.
    // SpliceWithNext - if the next clip after this is the same source
    //      and this's stop time matches next's start time, the two
    //      will be joined.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(78530B79-61F9-11D2-8CAD-00A024580902),
    odl,
    helpstring("IAMTimelineSrc Interface"),
    pointer_default(unique)
]
interface IAMTimelineSrc : IUnknown
{
    [helpstring("method GetMediaTimes")] 
    HRESULT GetMediaTimes(REFERENCE_TIME * pStart, REFERENCE_TIME * pStop);
    [helpstring("method GetMediaTimes2")] 
    HRESULT GetMediaTimes2(REFTIME * pStart, REFTIME * pStop);
    [helpstring("method ModifyStopTime")] 
    HRESULT ModifyStopTime(REFERENCE_TIME Stop);
    [helpstring("method ModifyStopTime2")] 
    HRESULT ModifyStopTime2(REFTIME Stop);
    [helpstring("method FixMediaTimes")] 
    HRESULT FixMediaTimes(REFERENCE_TIME * pStart, REFERENCE_TIME * pStop);
    [helpstring("method FixMediaTimes2")] 
    HRESULT FixMediaTimes2(REFTIME * pStart, REFTIME * pStop);
    [helpstring("method SetMediaTimes")] 
    HRESULT SetMediaTimes(REFERENCE_TIME Start, REFERENCE_TIME Stop);
    [helpstring("method SetMediaTimes2")] 
    HRESULT SetMediaTimes2(REFTIME Start, REFTIME Stop);
    [helpstring("method SetMediaLength")] 
    HRESULT SetMediaLength(REFERENCE_TIME Length);
    [helpstring("method SetMediaLength2")] 
    HRESULT SetMediaLength2(REFTIME Length);
    [helpstring("method GetMediaLength")] 
    HRESULT GetMediaLength(REFERENCE_TIME * pLength);
    [helpstring("method GetMediaLength2")] 
    HRESULT GetMediaLength2(REFTIME * pLength);
    [helpstring("method GetMediaName")] 
    HRESULT GetMediaName([out,retval] BSTR * pVal);
    [helpstring("method SetMediaName")] 
    HRESULT SetMediaName(BSTR newVal);
    [helpstring("method SpliceWithNext")] 
    HRESULT SpliceWithNext(IAMTimelineObj * pNext);
    [helpstring("method GetStreamNumber")] 
    HRESULT GetStreamNumber(long * pVal);
    [helpstring("method SetStreamNumber")] 
    HRESULT SetStreamNumber(long Val);
    HRESULT IsNormalRate( BOOL * pVal );

    // If a source can't figure out its frames per second, this number
    // will be used (eg: Dib sequences).  AVI, MPEG, etc. will not need this
    // Use 0 fps to prevent a filename like "ski4.jpg" from using a dib seq
    [helpstring("method GetDefaultFPS")] 
    HRESULT GetDefaultFPS(double * pFPS);
    [helpstring("method SetDefaultFPS")] 
    HRESULT SetDefaultFPS(double FPS);

    // !!! This is video specific.. new interface?
    // what kind of stretching? Stretch, crop, or preserve aspect ratio?
    [helpstring("method GetStretchMode")] 
    HRESULT GetStretchMode(int * pnStretchMode);
    [helpstring("method SetStretchMode")] 
    HRESULT SetStretchMode(int nStretchMode);
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Tracks are things that can contain media in them. You can add
    // and remove sources, effects, and transitions from them. Sources
    // are added according to the current insert mode of the timeline.
    // If in OVERLAY mode, moving or adding a source to a time that's
    // already occupied by another source will wipe out any overlapping
    // portion of the underlying source. In InsertMode, everything at
    // the insert point is moved down in time to make room for the
    // new source.
    // explained methods:
    // SrcAdd - add the source to this track. The source's start/stop
    //      times must be set up first.
    // GetNextSrc - pass a time in at which you wish to find a source
    //      and it will return the first source which occurs after the 
    //      given time.
    // MoveEverythingBy - bump a bunch of objects a certain direction
    //      on the track by a given time.
    // GetSourcesCount - how many sources are on this track?
    // AreYouBlank - do you contain anything at all?
    // GetSrcAtTime - find a source at a given time. SearchDirection
    //      is which way to search. -1 = backwards, 1 = forwards
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(EAE58538-622E-11d2-8CAD-00A024580902),
    odl,
    helpstring("IAMTimelineTrack Interface"),
    pointer_default(unique)
]
interface IAMTimelineTrack : IUnknown
{
    [helpstring("method SrcAdd")] 
    HRESULT SrcAdd(IAMTimelineObj * pSource);
    [helpstring("method GetNextSrc")] 
    HRESULT GetNextSrc([out] IAMTimelineObj ** ppSrc, REFERENCE_TIME * pInOut);
    [helpstring("method GetNextSrc2")] 
    HRESULT GetNextSrc2([out] IAMTimelineObj ** ppSrc, REFTIME * pInOut);
    [helpstring("method MoveEverythingBy")] 
    HRESULT MoveEverythingBy( REFERENCE_TIME Start, REFERENCE_TIME MoveBy );
    [helpstring("method MoveEverythingBy2")] 
    HRESULT MoveEverythingBy2( REFTIME Start, REFTIME MoveBy );
    [helpstring("method GetSourcesCount")] 
    HRESULT GetSourcesCount( long * pVal );
    [helpstring("method AreYouBlank")] 
    HRESULT AreYouBlank( long * pVal );
    [helpstring("method GetSrcAtTime")] 
    HRESULT GetSrcAtTime(
        [out] IAMTimelineObj ** ppSrc, 
        REFERENCE_TIME Time, 
        long SearchDirection ); 
    [helpstring("method GetSrcAtTime2")] 
    HRESULT GetSrcAtTime2([out] IAMTimelineObj ** ppSrc, REFTIME Time, long SearchDirection ); 
    HRESULT InsertSpace( REFERENCE_TIME rtStart, REFERENCE_TIME rtEnd );
    HRESULT InsertSpace2( REFTIME rtStart, REFTIME rtEnd );
    HRESULT ZeroBetween( REFERENCE_TIME rtStart, REFERENCE_TIME rtEnd );
    HRESULT ZeroBetween2( REFTIME rtStart, REFTIME rtEnd );
    HRESULT GetNextSrcEx(IAMTimelineObj * pLast, [out] IAMTimelineObj **ppNext);
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // This virtual track interface is shared by both the compositions
    // and tracks (and groups). 
    // explained methods:
    // TrackGetPriority - used by rendering objects which need to know this.
    // SetTrackDirty - !!! not sure if this is useful.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(A8ED5F80-C2C7-11d2-8D39-00A0C9441E20),
    odl,
    helpstring("IAMTimelineVirtualTrack Interface"),
    pointer_default(unique)
]
interface IAMTimelineVirtualTrack : IUnknown
{
    [helpstring("method TrackGetPriority")] 
    HRESULT TrackGetPriority(long * pPriority);
    [helpstring("method SetTrackDirty")] 
    HRESULT SetTrackDirty( );
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Compositions are like tracks in the sense that they also
    // implement IAMVirtualTrack and you can put transitions and effects
    // on them, but they really are the SUM of those tracks that they
    // contain. They are "embedded" compositions. They should only contain
    // media of one particular type (like all video or all audio), but 
    // this is not enforced. You can add a composition to another
    // composition with VTrackInsBefore, just like you can add a track.
    // The very top composition to which all other comps and tracks belong
    // is a Group, which supports I-AMTimelineGroup as well as I-AMTimelineComp.
    // explained methods:
    // VTrackInsBefore - does NOT mean VideoTrack. Means Virtual Track.
    //      Adds a virtual track to a composition at a given priority.
    //      use -1 to mean "at the end"
    // VTrackSwapPriorities - switch two vtracks around.
    // VTrackGetCount - get how many vtracks this comp contains.
    // GetVTrack - you get the idea
    // GetCountOfType - Get the total number of these objects this comp
    //      and all it's vtracks (recursively) contains. !!! this may be dead.
    // GetRecursiveLayerOfType - given a number, returns a given track. This
    //      is done recursively. You need to pass in a pointer to the number,
    //        and it will be modified upon exit to an unknown value. DO NOT
    //      CALL THE VERSION WITH THE POINTER!
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(EAE58536-622E-11d2-8CAD-00A024580902),
    odl,
    helpstring("IAMTimelineComp Interface"),
    pointer_default(unique)
]
interface IAMTimelineComp : IUnknown
{
    [helpstring("method VTrackInsBefore")] 
    HRESULT VTrackInsBefore(IAMTimelineObj * pVirtualTrack, long Priority);
    [helpstring("method VTrackSwapPriorities")] 
    HRESULT VTrackSwapPriorities(long VirtualTrackA, long VirtualTrackB);
    [helpstring("method VTrackGetCount")] 
    HRESULT VTrackGetCount(long * pVal);
    [helpstring("method GetVTrack")] 
    HRESULT GetVTrack([out] IAMTimelineObj ** ppVirtualTrack, long Which);
    [helpstring("method GetCountOfType")] 
    HRESULT GetCountOfType(long * pVal, long * pValWithComps, TIMELINE_MAJOR_TYPE MajorType );
    [helpstring("method GetRecursiveLayerOfType")] 
    HRESULT GetRecursiveLayerOfType(
        [out] IAMTimelineObj ** ppVirtualTrack, 
        long WhichLayer, 
        TIMELINE_MAJOR_TYPE Type);
    [helpstring("method GetRecursiveLayerOfTypeI (do not call)")] 
    HRESULT GetRecursiveLayerOfTypeI(
        [out] IAMTimelineObj ** ppVirtualTrack, 
        [in,out] long * pWhichLayer, 
        TIMELINE_MAJOR_TYPE Type);
    HRESULT GetNextVTrack(IAMTimelineObj *pVirtualTrack, [out] IAMTimelineObj **ppNextVirtualTrack);
};

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // Groups represent the topmost composition in a timeline. Every
    // group should contain media of only one major type (like all video).
    // The timeline can contain multiple groups, see it's interface for
    // this. Each group has a particular "media type" that you can get/set
    // which help identify it. Each group has an associated FPS which
    // is used by the render engine in setting up the big switch. All
    // cuts on the timeline will happen rounded to this nearest FPS for
    // this particular group. Each group has a priority which enables
    // writing out multiple-stream files with 1 or more streams of the
    // same type. (Like a 2 video stream AVI file).
    // explained methods:
    // SetTimeline - this is called internally when the group is added.
    //      Do not call this.
    // GetTimeline - get the timeline this group belongs to.
    // GetPriority - get this group's priority
    // Get/SetOutputFPS - explained above
    // SetMediaTypeForVB - method for VB. Pass in 0 for video, 1 for audio
    // SetRecompFormatFromSource - set the recompress format based on the
    //  source that's loaded or set in the IAMTimelineSrc
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(9EED4F00-B8A6-11d2-8023-00C0DF10D434),
    odl,
    helpstring("IAMTimelineGroup Interface"),
    pointer_default(unique)
]
interface IAMTimelineGroup : IUnknown
{
    [helpstring("method SetTimeline")] 
    HRESULT SetTimeline( IAMTimeline * pTimeline );
    [helpstring("method GetTimeline")] 
    HRESULT GetTimeline( [out] IAMTimeline ** ppTimeline );
    [helpstring("method GetPriority")] 
    HRESULT GetPriority( long * pPriority );
    [helpstring("method GetMediaType")] 
    HRESULT GetMediaType([out] AM_MEDIA_TYPE *);
    [helpstring("method SetMediaType")] 
    HRESULT SetMediaType([in] AM_MEDIA_TYPE *);
    [helpstring("method SetOutputFPS")] 
    HRESULT SetOutputFPS(double FPS);
    [helpstring("method GetOutputFPS")] 
    HRESULT GetOutputFPS(double * pFPS);
    [helpstring("method SetGroupName")] 
    HRESULT SetGroupName( BSTR pGroupName );
    [helpstring("method GetGroupName")] 
    HRESULT GetGroupName( [out,retval] BSTR * pGroupName );
    // in preview mode, skip frames.  In authoring mode, don't
    [helpstring("method SetPreviewMode")] 
    HRESULT SetPreviewMode( BOOL fPreview );
    [helpstring("method GetPreviewMode")] 
    HRESULT GetPreviewMode( BOOL *pfPreview );
    [helpstring("method SetMediaTypeForVB")] 
    HRESULT SetMediaTypeForVB([in] long Val );
    // how many frames ahead switch can run
    [helpstring("method GetOutputBuffering")] 
    HRESULT GetOutputBuffering([out] int *pnBuffer );
    [helpstring("method SetOutputBuffering")] 
    HRESULT SetOutputBuffering([in] int nBuffer );

    HRESULT SetSmartRecompressFormat( long * pFormat );
    HRESULT GetSmartRecompressFormat( long ** ppFormat );
    HRESULT IsSmartRecompressFormatSet( BOOL * pVal );
    HRESULT IsRecompressFormatDirty( BOOL * pVal );
    HRESULT ClearRecompressFormatDirty( );
    HRESULT SetRecompFormatFromSource( IAMTimelineSrc * pSource );
};


    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // The main timeline. This is the base object you use to set
    // properties of the timeline as a whole, and to create blank
    // objects for use within the timeline. You cannot create the
    // objects using COM methods, you must go through the timeline to
    // create this. That's because certain information is set before
    // handing the object back to you. Every object created by the
    // timeline will support at LEAST IAMTimelineObj. For any timeline,
    // it can have one or more "groups" that it knows about. Each group
    // has the capability to hold a complete sub-tree containing media
    // that is all of one type. This logical seperation is used for the
    // rendering engine, but is not strictly enforced.
    // explained methods:
    // CreateEmptyNode - pass in a mid type and it will pass back
    //      an object of the type you requested.
    // AddGroup - add a created group to the tree
    // RemGroupFromList - make sure timeline no longer knows about this group.
    //        does NOT do anything to the group itself. Normally the user
    //        does not want to call this, it's called from the Group's Remove( ) method.
    // GetGroup - get a certain group
    // GetGroupCount - get how many groups
    // ClearAllGroups - clear everything
    // GetInsertMode - ask what the insert mode is, overlay or insert
    // SetInsertMode - set whether to insert or overlay
    // EnableTransitions - turn transitions on or off as a whole
    // EnableEffects - same deal.
    // SetIntererstRange - discard sub-objects outside of a given
    //      time range, to save memory/resources
    // Get/SetDefaultFPS - set the 'default' FPS for this timeline,
    //      the RenderEngine reads this information for setting itself up
    //      by default.
    // GetCountOfType - ask for how many of a given thing are in a given
    //      group. !!! this may be a useless function.
    // !!! not implemented
    // IsDirty - asks if anything in the timeline needs to be redrawn
    // GetDirtyRange - same deal
    // ValidateSourceNames - make sure the filenames in the sources
    //      really exist. Use the same enum flags as the render engine
    //      uses for SetSourceNameValidation. Source's filenames will be
    //      changed to those of the found ones in the timeline.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

[
    object,
    uuid(78530B74-61F9-11D2-8CAD-00A024580902),
    odl,
    helpstring("IAMTimeline Interface"),
    pointer_default(unique)
]
interface IAMTimeline : IUnknown
{
    [helpstring("method CreateEmptyNode")] 
    HRESULT CreateEmptyNode([out] IAMTimelineObj ** ppObj, TIMELINE_MAJOR_TYPE Type );
    HRESULT AddGroup( IAMTimelineObj * pGroup );
    HRESULT RemGroupFromList( IAMTimelineObj * pGroup );
    HRESULT GetGroup( [out] IAMTimelineObj ** ppGroup, long WhichGroup );
    HRESULT GetGroupCount( long * pCount );
    HRESULT ClearAllGroups( );
    HRESULT GetInsertMode( long * pMode );
    [helpstring("method SetInsertMode")] 
    HRESULT SetInsertMode(long Mode);
    [helpstring("method EnableTransitions")] 
    HRESULT EnableTransitions(BOOL fEnabled);
    [helpstring("method TransitionsEnabled")] 
    HRESULT TransitionsEnabled(BOOL * pfEnabled);
    [helpstring("method EnableEffects")] 
    HRESULT EnableEffects(BOOL fEnabled);
    [helpstring("method EffectsEnabled")] 
    HRESULT EffectsEnabled(BOOL * pfEnabled);
    [helpstring("method SetInterestRange")] 
    HRESULT SetInterestRange(REFERENCE_TIME Start, REFERENCE_TIME Stop);
    [helpstring("method GetDuration")] 
    HRESULT GetDuration(REFERENCE_TIME * pDuration);
    [helpstring("method GetDuration2")] 
    HRESULT GetDuration2(double * pDuration);
    [helpstring("method SetDefaultFPS")] 
    HRESULT SetDefaultFPS(double FPS);
    [helpstring("method GetDefaultFPS")] 
    HRESULT GetDefaultFPS(double * pFPS);
    [helpstring("method IsDirty")] 
    HRESULT IsDirty(BOOL * pDirty);
    [helpstring("method GetDirtyRange")] 
    HRESULT GetDirtyRange(REFERENCE_TIME * pStart, REFERENCE_TIME * pStop);
    [helpstring("method GetCountOfType")] 
    HRESULT GetCountOfType(long Group, long * pVal, long * pValWithComps, TIMELINE_MAJOR_TYPE MajorType );
    HRESULT ValidateSourceNames( long ValidateFlags, IMediaLocator * pOverride, LONG_PTR NotifyEventHandle );

    HRESULT SetDefaultTransition( GUID * pGuid );
    HRESULT GetDefaultTransition( GUID * pGuid );
    HRESULT SetDefaultEffect( GUID * pGuid );
    HRESULT GetDefaultEffect( GUID * pGuid );
    HRESULT SetDefaultTransitionB( BSTR pGuid );
    HRESULT GetDefaultTransitionB( [out,retval] BSTR * pGuid );
    HRESULT SetDefaultEffectB( BSTR pGuid );
    HRESULT GetDefaultEffectB( [out,retval] BSTR * pGuid );
};

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// XML STUFF --- XML STUFF --- XML STUFF --- XML STUFF --- XML
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Xml2Dex - converts back and forth between XML and a dexter project
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

[
    object,
    uuid(18C628ED-962A-11D2-8D08-00A0C9441E20),
    odl,
    helpstring("IXml2Dex Interface"),
    pointer_default(unique)
]
interface IXml2Dex : IDispatch
{
    [id(1), helpstring("method CreateGraphFromFile")] 
    HRESULT CreateGraphFromFile([out] IUnknown ** ppGraph, IUnknown * pTimeline, BSTR Filename);
    [id(2), helpstring("method WriteGrfFile")] 
    HRESULT WriteGrfFile(IUnknown * pGraph, BSTR FileName);
    [id(3), helpstring("method WriteXMLFile")] 
    HRESULT WriteXMLFile(IUnknown * pTimeline, BSTR FileName);
    [id(5), helpstring("method ReadXMLFile")] 
    HRESULT ReadXMLFile(IUnknown *pTimeline, BSTR XMLName);
    [id(6), helpstring("method Delete")] 
    HRESULT Delete(IUnknown *pTimeline, double dStart, double dEnd);
    [id(7), helpstring("method WriteXMLPart")] 
    HRESULT WriteXMLPart(IUnknown * pTimeline, double dStart, double dEnd, BSTR FileName);
    [id(8), helpstring("method PasteXMLFile")] 
    HRESULT PasteXMLFile(IUnknown * pTimeline, double dStart, BSTR FileName);
    [id(9), helpstring("method CopyXML")] 
    HRESULT CopyXML(IUnknown * pTimeline, double dStart, double dEnd);
    [id(10), helpstring("method PasteXML")] 
    HRESULT PasteXML(IUnknown * pTimeline, double dStart);
    [id(11), helpstring("method Reset")] 
    HRESULT Reset( );
    [id(12), helpstring("method ReadXML")] 
    HRESULT ReadXML(IUnknown *pTimeline, IUnknown *pXML);
    [id(13), helpstring("method WriteXML")] 
    HRESULT WriteXML(IUnknown *pTimeline, BSTR *pbstrXML);
};

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// USEFUL HELPER INTERFACES
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// IAMErrorLog - an interface that receives error information from
// a timeline or a render engine.
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

[
    object,
    uuid(E43E73A2-0EFA-11d3-9601-00A0C9441E20),
    odl,
    helpstring("IAMErrorLog Interface"),
    pointer_default(unique)
]
interface IAMErrorLog : IUnknown
{
    [helpstring("method LogError")] HRESULT LogError(long Severity, BSTR pErrorString, long ErrorCode, long hresult, [in] VARIANT * pExtraInfo );
};

[
    object,
    uuid(963566DA-BE21-4eaf-88E9-35704F8F52A1),
    odl,
    helpstring("IAMSetErrorLog Interface"),
    pointer_default(unique)
]
interface IAMSetErrorLog : IUnknown
{
    [propget, helpstring("property ErrorLog")] HRESULT ErrorLog([out, retval] IAMErrorLog * *pVal);
    [propput, helpstring("property ErrorLog")] HRESULT ErrorLog([in] IAMErrorLog * newVal);
};

[
    object,
    uuid(0579154A-2B53-4994-B0D0-E773148EFF85),
    local,
    helpstring("ISampleGrabberCB Interface"),
    pointer_default(unique)
]
interface ISampleGrabberCB : IUnknown
{
    HRESULT SampleCB( double SampleTime, IMediaSample * pSample );
    HRESULT BufferCB( double SampleTime, BYTE * pBuffer, long BufferLen );
}

[
    object,
    uuid(6B652FFF-11FE-4fce-92AD-0266B5D7C78F),
    local,
    helpstring("ISampleGrabber Interface"),
    pointer_default(unique)
]
interface ISampleGrabber: IUnknown
{
    // 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] long * pBufferSize, [out] long * 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, long WhichMethodToCallback );
};

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// THE LIBRARY ITSELF
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////

[
    uuid(78530B68-61F9-11D2-8CAD-00A024580902),
    version(1.0),
    helpstring("Dexter 1.0 Type Library")
]
library DexterLib
{
    importlib("stdole2.tlb");

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // resize the input video to an output size, for uniformity within DES. 
    // DES will set the output media type and probably also put_Size. By setting
    // the output media type, DES is stating the resizer must produce only that
    // media type on the output pin, unless it is succeeded by a put_Size call.
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    [
        object,
        uuid(4ada63a0-72d5-11d2-952a-0060081840bc),
        odl,
        helpstring("IResize Interface"),
        pointer_default(unique)
    ]
    interface IResize : IUnknown
    {
        HRESULT get_Size([out] int *piHeight, [out] int *piWidth, [out] long *pFlag);
        HRESULT get_InputSize([out] int *piHeight, [out] int *piWidth);
        HRESULT put_Size([in] int Height, [in] int Width, [in] long Flag);
        HRESULT get_MediaType([out] AM_MEDIA_TYPE *pmt);
        HRESULT put_MediaType([in] const AM_MEDIA_TYPE *pmt);
    };

    [
        uuid(78530B75-61F9-11D2-8CAD-00A024580902),
        helpstring("AMTimeline Class")
    ]
    coclass AMTimeline
    {
        [default] interface IAMTimeline;
        interface IPersistStream;
        interface IAMSetErrorLog;
    };

    [
        uuid(78530B78-61F9-11D2-8CAD-00A024580902),
        helpstring("IAMTimelineObj Class")
    ]
    coclass AMTimelineObj
    {
        [default] interface IAMTimelineObj;
    };

    [
        uuid(78530B7A-61F9-11D2-8CAD-00A024580902),
        helpstring("IAMTimelineSrc Class")
    ]
    coclass AMTimelineSrc
    {
        [default] interface IAMTimelineSrc;
        interface IAMTimelineObj;
        interface IAMTimelineEffectable;
        interface IAMTimelineSplittable;
    };

    [
        uuid(8F6C3C50-897B-11d2-8CFB-00A0C9441E20),
    ]
    coclass AMTimelineTrack
    {
        [default] interface IAMTimelineTrack;
        interface IAMTimelineObj;
        interface IAMTimelineEffectable;
        interface IAMTimelineTransable;
        interface IAMTimelineVirtualTrack;
        interface IAMTimelineSplittable;
    };

    [
        uuid(74D2EC80-6233-11d2-8CAD-00A024580902),
    ]
    coclass AMTimelineComp
    {
        [default] interface IAMTimelineComp;
        interface IAMTimelineObj;
        interface IAMTimelineEffectable;
        interface IAMTimelineTransable;
        interface IAMTimelineVirtualTrack;
    };

    [
        uuid(F6D371E1-B8A6-11d2-8023-00C0DF10D434),
    ]
    coclass AMTimelineGroup
    {
        [default] interface IAMTimelineGroup;
        interface IAMTimelineComp;
        interface IAMTimelineObj;
    };

    [
        uuid(74D2EC81-6233-11d2-8CAD-00A024580902),
    ]
    coclass AMTimelineTrans
    {
        [default] interface IAMTimelineTrans;
        interface IAMTimelineObj;
        interface IAMTimelineSplittable;
    };

    [
        uuid(74D2EC82-6233-11d2-8CAD-00A024580902),
    ]
        coclass AMTimelineEffect
    {
        [default] interface IAMTimelineEffect;
        interface IAMTimelineObj;
        interface IAMTimelineSplittable;
        interface IPropertyBag;
    };

    [
        uuid(64D8A8E0-80A2-11d2-8CF3-00A0C9441E20),
    ]
    coclass RenderEngine
    {
        [default] interface IRenderEngine;
        interface IRenderEngine2;
        interface IAMSetErrorLog;
    };

    [
        uuid(498B0949-BBE9-4072-98BE-6CCAEB79DC6F),
    ]
    coclass SmartRenderEngine
    {
        [default] interface IRenderEngine;
        interface ISmartRenderEngine;
        interface IAMSetErrorLog;
    };

    [
    uuid(036A9790-C153-11d2-9EF7-006008039E37),
    ]
        coclass AudMixer
    {
        [default] interface IBaseFilter;
    };

    [
        uuid(18C628EE-962A-11D2-8D08-00A0C9441E20),
        helpstring("Xml2Dex Class")
    ]
    coclass Xml2Dex
    {
        [default] interface IXml2Dex;
    };

    [
        uuid(CC1101F2-79DC-11D2-8CE6-00A0C9441E20),
        helpstring("MediaLocator Class")
    ]
    coclass MediaLocator
    {
        [default] interface IMediaLocator;
    };

    [
        uuid(ADF95821-DED7-11d2-ACBE-0080C75E246E),
        helpstring("Varying Property Holder")
    ]
    coclass PropertySetter
    {
        [default] interface IPropertySetter;
        interface IAMSetErrorLog;
    };

    [
        uuid(65BD0711-24D2-4ff7-9324-ED2E5D3ABAFA),
        helpstring("MediaDet Class")
    ]
    coclass MediaDet
    {
        [default] interface IMediaDet;
    };

    [
        uuid(C1F400A0-3F08-11d3-9F0B-006008039E37),
        helpstring("MsGrab Class")
    ]
    coclass SampleGrabber
    {
        [default] interface ISampleGrabber;
    };

    // useful for movie maker and other people
    [
        uuid(C1F400A4-3F08-11d3-9F0B-006008039E37),
        helpstring("NullRenderer Class")
    ]
    coclass NullRenderer
    {
        [default] interface IBaseFilter;
    };

    [
         uuid(BB44391D-6ABD-422f-9E2E-385C9DFF51FC),
         helpstring("DxtCompositor Class")
    ]
    coclass DxtCompositor
    {
         [default] interface IDxtCompositor;
    };

    [
         uuid(506D89AE-909A-44f7-9444-ABD575896E35),
         helpstring("DxtAlphaSetter Class")
    ]
    coclass DxtAlphaSetter
    {
         [default] interface IDxtAlphaSetter;
    };

    [
        uuid(DE75D012-7A65-11D2-8CEA-00A0C9441E20),
        helpstring("SMPTE wipe DXT")
    ]
    coclass DxtJpeg
    {
        [default] interface IDxtJpeg;
    };

    [
        uuid(0cfdd070-581a-11d2-9ee6-006008039e37),
    ]
    coclass ColorSource
    {
        [default] interface IBaseFilter;
    };

    [
        uuid(C5B19592-145E-11d3-9F04-006008039E37),
        helpstring("DxtKey Class")
    ]
    coclass DxtKey
    {
        [default] interface IDxtKey;
    };
};

// these are some error codes that we can/will return
enum
{
    E_NOTINTREE = 0x80040400,
    E_RENDER_ENGINE_IS_BROKEN = 0x80040401,
    E_MUST_INIT_RENDERER = 0x80040402,
    E_NOTDETERMINED = 0x80040403,
    E_NO_TIMELINE = 0x80040404,
    S_WARN_OUTPUTRESET = 40404
};

// These codes are given to the app in IAMErrorLog to help identify what went wrong

// Filename doesn't exist, or DShow doesn't recognize the filetype
// EXTRA - filename
cpp_quote("#define DEX_IDS_BAD_SOURCE_NAME    1400")

// Filename doesn't exist or contains unknown data
// EXTRA - filename (maybe no codec?)
cpp_quote("#define DEX_IDS_BAD_SOURCE_NAME2    1401")

// filename was required, but wasn't given
cpp_quote("#define DEX_IDS_MISSING_SOURCE_NAME    1402")

// cannot parse data provided by this source
// !!! what source?
cpp_quote("#define DEX_IDS_UNKNOWN_SOURCE    1403")

// unexpected error - some DShow component not installed correctly
cpp_quote("#define DEX_IDS_INSTALL_PROBLEM    1404")

// Source filter does not accept filenames
// !!! What source?
cpp_quote("#define DEX_IDS_NO_SOURCE_NAMES    1405")

// The group's mediatype is not supported
// EXTRA - gives you an integer group number
cpp_quote("#define DEX_IDS_BAD_MEDIATYPE    1406")

// Invalid stream number for a source
// EXTRA - gives the stream number !!! should identify which source!
cpp_quote("#define DEX_IDS_STREAM_NUMBER    1407")

// You ran out of memory
cpp_quote("#define DEX_IDS_OUTOFMEMORY        1408")

// One bitmap in a sequence was not the same type as the others
// EXTRA - gives the bitmap name
cpp_quote("#define DEX_IDS_DIBSEQ_NOTALLSAME    1409")

// Clip's mediatimes are invalid, or DibSeq too short, or a previous error caused this
// !!! Needs to give the clip name
cpp_quote("#define DEX_IDS_CLIPTOOSHORT        1410")

// Clsid of FX/Transition is not a DirectX Transform
// EXTRA - gives the CLSID
cpp_quote("#define DEX_IDS_INVALID_DXT        1411")

// Default FX/Transition Clsid is not a DirectX Transform"
// EXTRA - gives the CLSID
cpp_quote("#define DEX_IDS_INVALID_DEFAULT_DXT    1412")

// Your version of DX doesn't support 3D transforms"
// EXTRA - gives the CLSID of the 3D transform you tried to use
cpp_quote("#define DEX_IDS_NO_3D        1413")

// This DirectX Transform is not the right kind, or is broken
// EXTRA - gives the CLSID of the broken transform
cpp_quote("#define DEX_IDS_BROKEN_DXT        1414")

// No such property exists on an object
// EXTRA - gives the name of the property (if given as a string)
cpp_quote("#define DEX_IDS_NO_SUCH_PROPERTY    1415")

// Illegal value for a property
// EXTRA - gives the VARIANT value that was illegal
cpp_quote("#define DEX_IDS_ILLEGAL_PROPERTY_VAL    1416")

// Syntax error in XML file at line:
// EXTRA - gives I4 line number, if available
cpp_quote("#define DEX_IDS_INVALID_XML        1417")

// Can't find filter specified in XML by Category and Instance
// EXTRA - gives friendly name (instance)
cpp_quote("#define DEX_IDS_CANT_FIND_FILTER    1418")

// Disk error writing XML file
cpp_quote("#define DEX_IDS_DISK_WRITE_ERROR    1419")

// Clsid not a valid DShow audio effect filter
// EXTRA - gives the CLSID
cpp_quote("#define DEX_IDS_INVALID_AUDIO_FX    1420")

// Cannot find compressor for smart recompression type
cpp_quote("#define DEX_IDS_CANT_FIND_COMPRESSOR 1421")



// !!! Here go problems hooking up sources or finding codecs


// THE FOLLOWING SHOULD NEVER HAPPEN - please call me if they do

// Unexpected error in parsing the timeline
cpp_quote("#define DEX_IDS_TIMELINE_PARSE    1426")
// Unexpected error building the filtergraph
cpp_quote("#define DEX_IDS_GRAPH_ERROR        1427")
// Unexpected error with the internal grid
cpp_quote("#define DEX_IDS_GRID_ERROR        1428")
// Unexpected error getting an interface
cpp_quote("#define DEX_IDS_INTERFACE_ERROR    1429")

// these are the enumeration categories for effects
//
cpp_quote("EXTERN_GUID(CLSID_VideoEffects1Category, 0xcc7bfb42, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);")
cpp_quote("EXTERN_GUID(CLSID_VideoEffects2Category, 0xcc7bfb43, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);")
cpp_quote("EXTERN_GUID(CLSID_AudioEffects1Category, 0xcc7bfb44, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);")
cpp_quote("EXTERN_GUID(CLSID_AudioEffects2Category, 0xcc7bfb45, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);")


sdk/dx8sdk/Include/DShowIDL/qedit.idl