summaryrefslogtreecommitdiffstats
path: root/thirdparties/win32/include/directshow/ctlutil.h
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparties/win32/include/directshow/ctlutil.h')
-rw-r--r--thirdparties/win32/include/directshow/ctlutil.h920
1 files changed, 920 insertions, 0 deletions
diff --git a/thirdparties/win32/include/directshow/ctlutil.h b/thirdparties/win32/include/directshow/ctlutil.h
new file mode 100644
index 0000000..89b6ff2
--- /dev/null
+++ b/thirdparties/win32/include/directshow/ctlutil.h
@@ -0,0 +1,920 @@
+//------------------------------------------------------------------------------
+// File: CtlUtil.h
+//
+// Desc: DirectShow base classes.
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//------------------------------------------------------------------------------
+
+
+// Base classes implementing IDispatch parsing for the basic control dual
+// interfaces. Derive from these and implement just the custom method and
+// property methods. We also implement CPosPassThru that can be used by
+// renderers and transforms to pass by IMediaPosition and IMediaSeeking
+
+#ifndef __CTLUTIL__
+#define __CTLUTIL__
+
+// OLE Automation has different ideas of TRUE and FALSE
+
+#define OATRUE (-1)
+#define OAFALSE (0)
+
+
+// It's possible that we could replace this class with CreateStdDispatch
+
+class CBaseDispatch
+{
+ ITypeInfo * m_pti;
+
+public:
+
+ CBaseDispatch() : m_pti(NULL) {}
+ ~CBaseDispatch();
+
+ /* IDispatch methods */
+ STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
+
+ STDMETHODIMP GetTypeInfo(
+ REFIID riid,
+ UINT itinfo,
+ LCID lcid,
+ ITypeInfo ** pptinfo);
+
+ STDMETHODIMP GetIDsOfNames(
+ REFIID riid,
+ OLECHAR ** rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID * rgdispid);
+};
+
+
+class AM_NOVTABLE CMediaControl :
+ public IMediaControl,
+ public CUnknown
+{
+ CBaseDispatch m_basedisp;
+
+public:
+
+ CMediaControl(const TCHAR *, LPUNKNOWN);
+
+ DECLARE_IUNKNOWN
+
+ // override this to publicise our interfaces
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+ /* IDispatch methods */
+ STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
+
+ STDMETHODIMP GetTypeInfo(
+ UINT itinfo,
+ LCID lcid,
+ ITypeInfo ** pptinfo);
+
+ STDMETHODIMP GetIDsOfNames(
+ REFIID riid,
+ OLECHAR ** rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID * rgdispid);
+
+ STDMETHODIMP Invoke(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS * pdispparams,
+ VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo,
+ UINT * puArgErr);
+};
+
+
+class AM_NOVTABLE CMediaEvent :
+ public IMediaEventEx,
+ public CUnknown
+{
+ CBaseDispatch m_basedisp;
+
+public:
+
+ CMediaEvent(const TCHAR *, LPUNKNOWN);
+
+ DECLARE_IUNKNOWN
+
+ // override this to publicise our interfaces
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+ /* IDispatch methods */
+ STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
+
+ STDMETHODIMP GetTypeInfo(
+ UINT itinfo,
+ LCID lcid,
+ ITypeInfo ** pptinfo);
+
+ STDMETHODIMP GetIDsOfNames(
+ REFIID riid,
+ OLECHAR ** rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID * rgdispid);
+
+ STDMETHODIMP Invoke(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS * pdispparams,
+ VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo,
+ UINT * puArgErr);
+};
+
+
+class AM_NOVTABLE CMediaPosition :
+ public IMediaPosition,
+ public CUnknown
+{
+ CBaseDispatch m_basedisp;
+
+
+public:
+
+ CMediaPosition(const TCHAR *, LPUNKNOWN);
+ CMediaPosition(const TCHAR *, LPUNKNOWN, HRESULT *phr);
+
+ DECLARE_IUNKNOWN
+
+ // override this to publicise our interfaces
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+ /* IDispatch methods */
+ STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
+
+ STDMETHODIMP GetTypeInfo(
+ UINT itinfo,
+ LCID lcid,
+ ITypeInfo ** pptinfo);
+
+ STDMETHODIMP GetIDsOfNames(
+ REFIID riid,
+ OLECHAR ** rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID * rgdispid);
+
+ STDMETHODIMP Invoke(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS * pdispparams,
+ VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo,
+ UINT * puArgErr);
+
+};
+
+
+// OA-compatibility means that we must use double as the RefTime value,
+// and REFERENCE_TIME (essentially a LONGLONG) within filters.
+// this class converts between the two
+
+class COARefTime : public CRefTime {
+public:
+
+ COARefTime() {
+ };
+
+ COARefTime(CRefTime t)
+ : CRefTime(t)
+ {
+ };
+
+ COARefTime(REFERENCE_TIME t)
+ : CRefTime(t)
+ {
+ };
+
+ COARefTime(double d) {
+ m_time = (LONGLONG) (d * 10000000);
+ };
+
+ operator double() {
+ return double(m_time) / 10000000;
+ };
+
+ operator REFERENCE_TIME() {
+ return m_time;
+ };
+
+ COARefTime& operator=(const double& rd) {
+ m_time = (LONGLONG) (rd * 10000000);
+ return *this;
+ }
+
+ COARefTime& operator=(const REFERENCE_TIME& rt) {
+ m_time = rt;
+ return *this;
+ }
+
+ inline BOOL operator==(const COARefTime& rt)
+ {
+ return m_time == rt.m_time;
+ };
+
+ inline BOOL operator!=(const COARefTime& rt)
+ {
+ return m_time != rt.m_time;
+ };
+
+ inline BOOL operator < (const COARefTime& rt)
+ {
+ return m_time < rt.m_time;
+ };
+
+ inline BOOL operator > (const COARefTime& rt)
+ {
+ return m_time > rt.m_time;
+ };
+
+ inline BOOL operator >= (const COARefTime& rt)
+ {
+ return m_time >= rt.m_time;
+ };
+
+ inline BOOL operator <= (const COARefTime& rt)
+ {
+ return m_time <= rt.m_time;
+ };
+
+ inline COARefTime operator+(const COARefTime& rt)
+ {
+ return COARefTime(m_time + rt.m_time);
+ };
+
+ inline COARefTime operator-(const COARefTime& rt)
+ {
+ return COARefTime(m_time - rt.m_time);
+ };
+
+ inline COARefTime operator*(LONG l)
+ {
+ return COARefTime(m_time * l);
+ };
+
+ inline COARefTime operator/(LONG l)
+ {
+ return COARefTime(m_time / l);
+ };
+
+private:
+ // Prevent bugs from constructing from LONG (which gets
+ // converted to double and then multiplied by 10000000
+ COARefTime(LONG);
+ //--operator=(LONG);
+ (LONG) operator=(LONG);
+};
+
+
+// A utility class that handles IMediaPosition and IMediaSeeking on behalf
+// of single-input pin renderers, or transform filters.
+//
+// Renderers will expose this from the filter; transform filters will
+// expose it from the output pin and not the renderer.
+//
+// Create one of these, giving it your IPin* for your input pin, and delegate
+// all IMediaPosition methods to it. It will query the input pin for
+// IMediaPosition and respond appropriately.
+//
+// Call ForceRefresh if the pin connection changes.
+//
+// This class no longer caches the upstream IMediaPosition or IMediaSeeking
+// it acquires it on each method call. This means ForceRefresh is not needed.
+// The method is kept for source compatibility and to minimise the changes
+// if we need to put it back later for performance reasons.
+
+class CPosPassThru : public IMediaSeeking, public CMediaPosition
+{
+ IPin *m_pPin;
+
+ HRESULT GetPeer(IMediaPosition **ppMP);
+ HRESULT GetPeerSeeking(IMediaSeeking **ppMS);
+
+public:
+
+ CPosPassThru(const TCHAR *, LPUNKNOWN, HRESULT*, IPin *);
+ DECLARE_IUNKNOWN
+
+ HRESULT ForceRefresh() {
+ return S_OK;
+ };
+
+ // override to return an accurate current position
+ virtual HRESULT GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime) {
+ return E_FAIL;
+ }
+
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv);
+
+ // IMediaSeeking methods
+ STDMETHODIMP GetCapabilities( DWORD * pCapabilities );
+ STDMETHODIMP CheckCapabilities( DWORD * pCapabilities );
+ STDMETHODIMP SetTimeFormat(const GUID * pFormat);
+ STDMETHODIMP GetTimeFormat(GUID *pFormat);
+ STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat);
+ STDMETHODIMP IsFormatSupported( const GUID * pFormat);
+ STDMETHODIMP QueryPreferredFormat( GUID *pFormat);
+ STDMETHODIMP ConvertTimeFormat(LONGLONG * pTarget, const GUID * pTargetFormat,
+ LONGLONG Source, const GUID * pSourceFormat );
+ STDMETHODIMP SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags
+ , LONGLONG * pStop, DWORD StopFlags );
+
+ STDMETHODIMP GetPositions( LONGLONG * pCurrent, LONGLONG * pStop );
+ STDMETHODIMP GetCurrentPosition( LONGLONG * pCurrent );
+ STDMETHODIMP GetStopPosition( LONGLONG * pStop );
+ STDMETHODIMP SetRate( double dRate);
+ STDMETHODIMP GetRate( double * pdRate);
+ STDMETHODIMP GetDuration( LONGLONG *pDuration);
+ STDMETHODIMP GetAvailable( LONGLONG *pEarliest, LONGLONG *pLatest );
+ STDMETHODIMP GetPreroll( LONGLONG *pllPreroll );
+
+ // IMediaPosition properties
+ STDMETHODIMP get_Duration(REFTIME * plength);
+ STDMETHODIMP put_CurrentPosition(REFTIME llTime);
+ STDMETHODIMP get_StopTime(REFTIME * pllTime);
+ STDMETHODIMP put_StopTime(REFTIME llTime);
+ STDMETHODIMP get_PrerollTime(REFTIME * pllTime);
+ STDMETHODIMP put_PrerollTime(REFTIME llTime);
+ STDMETHODIMP get_Rate(double * pdRate);
+ STDMETHODIMP put_Rate(double dRate);
+ STDMETHODIMP get_CurrentPosition(REFTIME * pllTime);
+ STDMETHODIMP CanSeekForward(LONG *pCanSeekForward);
+ STDMETHODIMP CanSeekBackward(LONG *pCanSeekBackward);
+
+private:
+ HRESULT GetSeekingLongLong( HRESULT (__stdcall IMediaSeeking::*pMethod)( LONGLONG * ),
+ LONGLONG * pll );
+};
+
+
+// Adds the ability to return a current position
+
+class CRendererPosPassThru : public CPosPassThru
+{
+ CCritSec m_PositionLock; // Locks access to our position
+ LONGLONG m_StartMedia; // Start media time last seen
+ LONGLONG m_EndMedia; // And likewise the end media
+ BOOL m_bReset; // Have media times been set
+
+public:
+
+ // Used to help with passing media times through graph
+
+ CRendererPosPassThru(const TCHAR *, LPUNKNOWN, HRESULT*, IPin *);
+ HRESULT RegisterMediaTime(IMediaSample *pMediaSample);
+ HRESULT RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime);
+ HRESULT GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime);
+ HRESULT ResetMediaTime();
+ HRESULT EOS();
+};
+
+STDAPI CreatePosPassThru(
+ LPUNKNOWN pAgg,
+ BOOL bRenderer,
+ IPin *pPin,
+ IUnknown **ppPassThru
+);
+
+// A class that handles the IDispatch part of IBasicAudio and leaves the
+// properties and methods themselves pure virtual.
+
+class AM_NOVTABLE CBasicAudio : public IBasicAudio, public CUnknown
+{
+ CBaseDispatch m_basedisp;
+
+public:
+
+ CBasicAudio(const TCHAR *, LPUNKNOWN);
+
+ DECLARE_IUNKNOWN
+
+ // override this to publicise our interfaces
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+ /* IDispatch methods */
+ STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
+
+ STDMETHODIMP GetTypeInfo(
+ UINT itinfo,
+ LCID lcid,
+ ITypeInfo ** pptinfo);
+
+ STDMETHODIMP GetIDsOfNames(
+ REFIID riid,
+ OLECHAR ** rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID * rgdispid);
+
+ STDMETHODIMP Invoke(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS * pdispparams,
+ VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo,
+ UINT * puArgErr);
+};
+
+
+// A class that handles the IDispatch part of IBasicVideo and leaves the
+// properties and methods themselves pure virtual.
+
+class AM_NOVTABLE CBaseBasicVideo : public IBasicVideo2, public CUnknown
+{
+ CBaseDispatch m_basedisp;
+
+public:
+
+ CBaseBasicVideo(const TCHAR *, LPUNKNOWN);
+
+ DECLARE_IUNKNOWN
+
+ // override this to publicise our interfaces
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+ /* IDispatch methods */
+ STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
+
+ STDMETHODIMP GetTypeInfo(
+ UINT itinfo,
+ LCID lcid,
+ ITypeInfo ** pptinfo);
+
+ STDMETHODIMP GetIDsOfNames(
+ REFIID riid,
+ OLECHAR ** rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID * rgdispid);
+
+ STDMETHODIMP Invoke(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS * pdispparams,
+ VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo,
+ UINT * puArgErr);
+
+ STDMETHODIMP GetPreferredAspectRatio(
+ long *plAspectX,
+ long *plAspectY)
+ {
+ return E_NOTIMPL;
+ }
+};
+
+
+// A class that handles the IDispatch part of IVideoWindow and leaves the
+// properties and methods themselves pure virtual.
+
+class AM_NOVTABLE CBaseVideoWindow : public IVideoWindow, public CUnknown
+{
+ CBaseDispatch m_basedisp;
+
+public:
+
+ CBaseVideoWindow(const TCHAR *, LPUNKNOWN);
+
+ DECLARE_IUNKNOWN
+
+ // override this to publicise our interfaces
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+ /* IDispatch methods */
+ STDMETHODIMP GetTypeInfoCount(UINT * pctinfo);
+
+ STDMETHODIMP GetTypeInfo(
+ UINT itinfo,
+ LCID lcid,
+ ITypeInfo ** pptinfo);
+
+ STDMETHODIMP GetIDsOfNames(
+ REFIID riid,
+ OLECHAR ** rgszNames,
+ UINT cNames,
+ LCID lcid,
+ DISPID * rgdispid);
+
+ STDMETHODIMP Invoke(
+ DISPID dispidMember,
+ REFIID riid,
+ LCID lcid,
+ WORD wFlags,
+ DISPPARAMS * pdispparams,
+ VARIANT * pvarResult,
+ EXCEPINFO * pexcepinfo,
+ UINT * puArgErr);
+};
+
+
+// abstract class to help source filters with their implementation
+// of IMediaPosition. Derive from this and set the duration (and stop
+// position). Also override NotifyChange to do something when the properties
+// change.
+
+class AM_NOVTABLE CSourcePosition : public CMediaPosition
+{
+
+public:
+ CSourcePosition(const TCHAR *, LPUNKNOWN, HRESULT*, CCritSec *);
+
+ // IMediaPosition methods
+ STDMETHODIMP get_Duration(REFTIME * plength);
+ STDMETHODIMP put_CurrentPosition(REFTIME llTime);
+ STDMETHODIMP get_StopTime(REFTIME * pllTime);
+ STDMETHODIMP put_StopTime(REFTIME llTime);
+ STDMETHODIMP get_PrerollTime(REFTIME * pllTime);
+ STDMETHODIMP put_PrerollTime(REFTIME llTime);
+ STDMETHODIMP get_Rate(double * pdRate);
+ STDMETHODIMP put_Rate(double dRate);
+ STDMETHODIMP CanSeekForward(LONG *pCanSeekForward);
+ STDMETHODIMP CanSeekBackward(LONG *pCanSeekBackward);
+
+ // override if you can return the data you are actually working on
+ STDMETHODIMP get_CurrentPosition(REFTIME * pllTime) {
+ return E_NOTIMPL;
+ };
+
+protected:
+
+ // we call this to notify changes. Override to handle them
+ virtual HRESULT ChangeStart() PURE;
+ virtual HRESULT ChangeStop() PURE;
+ virtual HRESULT ChangeRate() PURE;
+
+ COARefTime m_Duration;
+ COARefTime m_Start;
+ COARefTime m_Stop;
+ double m_Rate;
+
+ CCritSec * m_pLock;
+};
+
+class AM_NOVTABLE CSourceSeeking :
+ public IMediaSeeking,
+ public CUnknown
+{
+
+public:
+
+ DECLARE_IUNKNOWN;
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+ // IMediaSeeking methods
+
+ STDMETHODIMP IsFormatSupported(const GUID * pFormat);
+ STDMETHODIMP QueryPreferredFormat(GUID *pFormat);
+ STDMETHODIMP SetTimeFormat(const GUID * pFormat);
+ STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat);
+ STDMETHODIMP GetTimeFormat(GUID *pFormat);
+ STDMETHODIMP GetDuration(LONGLONG *pDuration);
+ STDMETHODIMP GetStopPosition(LONGLONG *pStop);
+ STDMETHODIMP GetCurrentPosition(LONGLONG *pCurrent);
+ STDMETHODIMP GetCapabilities( DWORD * pCapabilities );
+ STDMETHODIMP CheckCapabilities( DWORD * pCapabilities );
+ STDMETHODIMP ConvertTimeFormat( LONGLONG * pTarget, const GUID * pTargetFormat,
+ LONGLONG Source, const GUID * pSourceFormat );
+
+ STDMETHODIMP SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags
+ , LONGLONG * pStop, DWORD StopFlags );
+
+ STDMETHODIMP GetPositions( LONGLONG * pCurrent, LONGLONG * pStop );
+
+ STDMETHODIMP GetAvailable( LONGLONG * pEarliest, LONGLONG * pLatest );
+ STDMETHODIMP SetRate( double dRate);
+ STDMETHODIMP GetRate( double * pdRate);
+ STDMETHODIMP GetPreroll(LONGLONG *pPreroll);
+
+
+protected:
+
+ // ctor
+ CSourceSeeking(const TCHAR *, LPUNKNOWN, HRESULT*, CCritSec *);
+
+ // we call this to notify changes. Override to handle them
+ virtual HRESULT ChangeStart() PURE;
+ virtual HRESULT ChangeStop() PURE;
+ virtual HRESULT ChangeRate() PURE;
+
+ CRefTime m_rtDuration; // length of stream
+ CRefTime m_rtStart; // source will start here
+ CRefTime m_rtStop; // source will stop here
+ double m_dRateSeeking;
+
+ // seeking capabilities
+ DWORD m_dwSeekingCaps;
+
+ CCritSec * m_pLock;
+};
+
+
+// Base classes supporting Deferred commands.
+
+// Deferred commands are queued by calls to methods on the IQueueCommand
+// interface, exposed by the filtergraph and by some filters. A successful
+// call to one of these methods will return an IDeferredCommand interface
+// representing the queued command.
+//
+// A CDeferredCommand object represents a single deferred command, and exposes
+// the IDeferredCommand interface as well as other methods permitting time
+// checks and actual execution. It contains a reference to the CCommandQueue
+// object on which it is queued.
+//
+// CCommandQueue is a base class providing a queue of CDeferredCommand
+// objects, and methods to add, remove, check status and invoke the queued
+// commands. A CCommandQueue object would be part of an object that
+// implemented IQueueCommand.
+
+class CCmdQueue;
+
+// take a copy of the params and store them. Release any allocated
+// memory in destructor
+
+class CDispParams : public DISPPARAMS
+{
+public:
+ CDispParams(UINT nArgs, VARIANT* pArgs, HRESULT *phr = NULL);
+ ~CDispParams();
+};
+
+
+// CDeferredCommand lifetime is controlled by refcounts. Caller of
+// InvokeAt.. gets a refcounted interface pointer, and the CCmdQueue
+// object also holds a refcount on us. Calling Cancel or Invoke takes
+// us off the CCmdQueue and thus reduces the refcount by 1. Once taken
+// off the queue we cannot be put back on the queue.
+
+class CDeferredCommand
+ : public CUnknown,
+ public IDeferredCommand
+{
+public:
+
+ CDeferredCommand(
+ CCmdQueue * pQ,
+ LPUNKNOWN pUnk, // aggregation outer unk
+ HRESULT * phr,
+ LPUNKNOWN pUnkExecutor, // object that will execute this cmd
+ REFTIME time,
+ GUID* iid,
+ long dispidMethod,
+ short wFlags,
+ long cArgs,
+ VARIANT* pDispParams,
+ VARIANT* pvarResult,
+ short* puArgErr,
+ BOOL bStream
+ );
+
+ DECLARE_IUNKNOWN
+
+ // override this to publicise our interfaces
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+
+ // IDeferredCommand methods
+ STDMETHODIMP Cancel();
+ STDMETHODIMP Confidence(
+ LONG* pConfidence);
+ STDMETHODIMP Postpone(
+ REFTIME newtime);
+ STDMETHODIMP GetHResult(
+ HRESULT* phrResult);
+
+ // other public methods
+
+ HRESULT Invoke();
+
+ // access methods
+
+ // returns TRUE if streamtime, FALSE if presentation time
+ BOOL IsStreamTime() {
+ return m_bStream;
+ };
+
+ CRefTime GetTime() {
+ return m_time;
+ };
+
+ REFIID GetIID() {
+ return *m_iid;
+ };
+
+ long GetMethod() {
+ return m_dispidMethod;
+ };
+
+ short GetFlags() {
+ return m_wFlags;
+ };
+
+ DISPPARAMS* GetParams() {
+ return &m_DispParams;
+ };
+
+ VARIANT* GetResult() {
+ return m_pvarResult;
+ };
+
+protected:
+
+ CCmdQueue* m_pQueue;
+
+ // pUnk for the interface that we will execute the command on
+ LPUNKNOWN m_pUnk;
+
+ // stored command data
+ REFERENCE_TIME m_time;
+ GUID* m_iid;
+ long m_dispidMethod;
+ short m_wFlags;
+ VARIANT* m_pvarResult;
+ BOOL m_bStream;
+ CDispParams m_DispParams;
+ DISPID m_DispId; // For get and put
+
+ // we use this for ITypeInfo access
+ CBaseDispatch m_Dispatch;
+
+ // save retval here
+ HRESULT m_hrResult;
+};
+
+
+// a list of CDeferredCommand objects. this is a base class providing
+// the basics of access to the list. If you want to use CDeferredCommand
+// objects then your queue needs to be derived from this class.
+
+class AM_NOVTABLE CCmdQueue
+{
+public:
+ CCmdQueue();
+ virtual ~CCmdQueue();
+
+ // returns a new CDeferredCommand object that will be initialised with
+ // the parameters and will be added to the queue during construction.
+ // returns S_OK if successfully created otherwise an error and
+ // no object has been queued.
+ virtual HRESULT New(
+ CDeferredCommand **ppCmd,
+ LPUNKNOWN pUnk,
+ REFTIME time,
+ GUID* iid,
+ long dispidMethod,
+ short wFlags,
+ long cArgs,
+ VARIANT* pDispParams,
+ VARIANT* pvarResult,
+ short* puArgErr,
+ BOOL bStream
+ );
+
+ // called by the CDeferredCommand object to add and remove itself
+ // from the queue
+ virtual HRESULT Insert(CDeferredCommand* pCmd);
+ virtual HRESULT Remove(CDeferredCommand* pCmd);
+
+ // Command-Due Checking
+ //
+ // There are two schemes of synchronisation: coarse and accurate. In
+ // coarse mode, you wait till the time arrives and then execute the cmd.
+ // In accurate mode, you wait until you are processing the sample that
+ // will appear at the time, and then execute the command. It's up to the
+ // filter which one it will implement. The filtergraph will always
+ // implement coarse mode for commands queued at the filtergraph.
+ //
+ // If you want coarse sync, you probably want to wait until there is a
+ // command due, and then execute it. You can do this by calling
+ // GetDueCommand. If you have several things to wait for, get the
+ // event handle from GetDueHandle() and when this is signalled then call
+ // GetDueCommand. Stream time will only advance between calls to Run and
+ // EndRun. Note that to avoid an extra thread there is no guarantee that
+ // if the handle is set there will be a command ready. Each time the
+ // event is signalled, call GetDueCommand (probably with a 0 timeout);
+ // This may return E_ABORT.
+ //
+ // If you want accurate sync, you must call GetCommandDueFor, passing
+ // as a parameter the stream time of the samples you are about to process.
+ // This will return:
+ // -- a stream-time command due at or before that stream time
+ // -- a presentation-time command due at or before the
+ // time that stream time will be presented (only between Run
+ // and EndRun calls, since outside of this, the mapping from
+ // stream time to presentation time is not known.
+ // -- any presentation-time command due now.
+ // This means that if you want accurate synchronisation on samples that
+ // might be processed during Paused mode, you need to use
+ // stream-time commands.
+ //
+ // In all cases, commands remain queued until Invoked or Cancelled. The
+ // setting and resetting of the event handle is managed entirely by this
+ // queue object.
+
+ // set the clock used for timing
+ virtual HRESULT SetSyncSource(IReferenceClock*);
+
+ // switch to run mode. Streamtime to Presentation time mapping known.
+ virtual HRESULT Run(REFERENCE_TIME tStreamTimeOffset);
+
+ // switch to Stopped or Paused mode. Time mapping not known.
+ virtual HRESULT EndRun();
+
+ // return a pointer to the next due command. Blocks for msTimeout
+ // milliseconds until there is a due command.
+ // Stream-time commands will only become due between Run and Endrun calls.
+ // The command remains queued until invoked or cancelled.
+ // Returns E_ABORT if timeout occurs, otherwise S_OK (or other error).
+ // Returns an AddRef-ed object
+ virtual HRESULT GetDueCommand(CDeferredCommand ** ppCmd, long msTimeout);
+
+ // return the event handle that will be signalled whenever
+ // there are deferred commands due for execution (when GetDueCommand
+ // will not block).
+ HANDLE GetDueHandle() {
+ return HANDLE(m_evDue);
+ };
+
+ // return a pointer to a command that will be due for a given time.
+ // Pass in a stream time here. The stream time offset will be passed
+ // in via the Run method.
+ // Commands remain queued until invoked or cancelled.
+ // This method will not block. It will report VFW_E_NOT_FOUND if there
+ // are no commands due yet.
+ // Returns an AddRef-ed object
+ virtual HRESULT GetCommandDueFor(REFERENCE_TIME tStream, CDeferredCommand**ppCmd);
+
+ // check if a given time is due (TRUE if it is due yet)
+ BOOL CheckTime(CRefTime time, BOOL bStream) {
+
+ // if no clock, nothing is due!
+ if (!m_pClock) {
+ return FALSE;
+ }
+
+ // stream time
+ if (bStream) {
+
+ // not valid if not running
+ if (!m_bRunning) {
+ return FALSE;
+ }
+ // add on known stream time offset to get presentation time
+ time += m_StreamTimeOffset;
+ }
+
+ CRefTime Now;
+ m_pClock->GetTime((REFERENCE_TIME*)&Now);
+ return (time <= Now);
+ };
+
+protected:
+
+ // protect access to lists etc
+ CCritSec m_Lock;
+
+ // commands queued in presentation time are stored here
+ CGenericList<CDeferredCommand> m_listPresentation;
+
+ // commands queued in stream time are stored here
+ CGenericList<CDeferredCommand> m_listStream;
+
+ // set when any commands are due
+ CAMEvent m_evDue;
+
+ // creates an advise for the earliest time required, if any
+ void SetTimeAdvise(void);
+
+ // advise id from reference clock (0 if no outstanding advise)
+ DWORD_PTR m_dwAdvise;
+
+ // advise time is for this presentation time
+ CRefTime m_tCurrentAdvise;
+
+ // the reference clock we are using (addrefed)
+ IReferenceClock* m_pClock;
+
+ // true when running
+ BOOL m_bRunning;
+
+ // contains stream time offset when m_bRunning is true
+ CRefTime m_StreamTimeOffset;
+};
+
+#endif // __CTLUTIL__
OpenPOWER on IntegriCloud