* #27232: jni: added pjproject checkout as regular git content

We will remove it once the next release of pjsip (with Android support)
comes out and is merged into SFLphone.
diff --git a/jni/pjproject-android/.svn/pristine/e6/e6401d0dd9e6001ae1fbabccb90811b5a221459e.svn-base b/jni/pjproject-android/.svn/pristine/e6/e6401d0dd9e6001ae1fbabccb90811b5a221459e.svn-base
new file mode 100644
index 0000000..7e4719c
--- /dev/null
+++ b/jni/pjproject-android/.svn/pristine/e6/e6401d0dd9e6001ae1fbabccb90811b5a221459e.svn-base
@@ -0,0 +1,923 @@
+//------------------------------------------------------------------------------

+// File: CtlUtil.h

+//

+// Desc: DirectShow base classes.

+//

+// Copyright (c) 1992-2001 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(__out UINT * pctinfo);

+

+    STDMETHODIMP GetTypeInfo(

+      REFIID riid,

+      UINT itinfo,

+      LCID lcid,

+      __deref_out ITypeInfo ** pptinfo);

+

+    STDMETHODIMP GetIDsOfNames(

+      REFIID riid,

+      __in_ecount(cNames) LPOLESTR * rgszNames,

+      UINT cNames,

+      LCID lcid,

+      __out_ecount(cNames) 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, __deref_out void **ppv);

+

+    /* IDispatch methods */

+    STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);

+

+    STDMETHODIMP GetTypeInfo(

+      UINT itinfo,

+      LCID lcid,

+      __deref_out ITypeInfo ** pptinfo);

+

+    STDMETHODIMP GetIDsOfNames(

+      REFIID riid,

+      __in_ecount(cNames) LPOLESTR * rgszNames,

+      UINT cNames,

+      LCID lcid,

+      __out_ecount(cNames) DISPID * rgdispid);

+

+    STDMETHODIMP Invoke(

+      DISPID dispidMember,

+      REFIID riid,

+      LCID lcid,

+      WORD wFlags,

+      __in DISPPARAMS * pdispparams,

+      __out_opt VARIANT * pvarResult,

+      __out_opt EXCEPINFO * pexcepinfo,

+      __out_opt UINT * puArgErr);

+};

+

+

+class AM_NOVTABLE CMediaEvent :

+    public IMediaEventEx,

+    public CUnknown

+{

+    CBaseDispatch m_basedisp;

+

+public:

+

+    CMediaEvent(__in_opt LPCTSTR, __in_opt LPUNKNOWN);

+

+    DECLARE_IUNKNOWN

+

+    // override this to publicise our interfaces

+    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);

+

+    /* IDispatch methods */

+    STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);

+

+    STDMETHODIMP GetTypeInfo(

+      UINT itinfo,

+      LCID lcid,

+      __deref_out ITypeInfo ** pptinfo);

+

+    STDMETHODIMP GetIDsOfNames(

+      REFIID riid,

+      __in_ecount(cNames) LPOLESTR * rgszNames,

+      UINT cNames,

+      LCID lcid,

+      __out_ecount(cNames) DISPID * rgdispid);

+

+    STDMETHODIMP Invoke(

+      DISPID dispidMember,

+      REFIID riid,

+      LCID lcid,

+      WORD wFlags,

+      __in DISPPARAMS * pdispparams,

+      __out_opt VARIANT * pvarResult,

+      __out_opt EXCEPINFO * pexcepinfo,

+      __out_opt UINT * puArgErr);

+};

+

+

+class AM_NOVTABLE CMediaPosition :

+    public IMediaPosition,

+    public CUnknown

+{

+    CBaseDispatch m_basedisp;

+

+

+public:

+

+    CMediaPosition(__in_opt LPCTSTR, __in_opt LPUNKNOWN);

+    CMediaPosition(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT *phr);

+

+    DECLARE_IUNKNOWN

+

+    // override this to publicise our interfaces

+    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);

+

+    /* IDispatch methods */

+    STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);

+

+    STDMETHODIMP GetTypeInfo(

+      UINT itinfo,

+      LCID lcid,

+      __deref_out ITypeInfo ** pptinfo);

+

+    STDMETHODIMP GetIDsOfNames(

+      REFIID riid,

+      __in_ecount(cNames) LPOLESTR * rgszNames,

+      UINT cNames,

+      LCID lcid,

+      __out_ecount(cNames) DISPID * rgdispid);

+

+    STDMETHODIMP Invoke(

+      DISPID dispidMember,

+      REFIID riid,

+      LCID lcid,

+      WORD wFlags,

+      __in DISPPARAMS * pdispparams,

+      __out_opt VARIANT * pvarResult,

+      __out_opt EXCEPINFO * pexcepinfo,

+      __out_opt 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);

+    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(__deref_out IMediaPosition **ppMP);

+    HRESULT GetPeerSeeking(__deref_out IMediaSeeking **ppMS);

+

+public:

+

+    CPosPassThru(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT*, IPin *);

+    DECLARE_IUNKNOWN

+

+    HRESULT ForceRefresh() {

+        return S_OK;

+    };

+

+    // override to return an accurate current position

+    virtual HRESULT GetMediaTime(__out LONGLONG *pStartTime, __out_opt LONGLONG *pEndTime) {

+        return E_FAIL;

+    }

+

+    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,__deref_out void **ppv);

+

+    // IMediaSeeking methods

+    STDMETHODIMP GetCapabilities( __out DWORD * pCapabilities );

+    STDMETHODIMP CheckCapabilities( __inout DWORD * pCapabilities );

+    STDMETHODIMP SetTimeFormat(const GUID * pFormat);

+    STDMETHODIMP GetTimeFormat(__out GUID *pFormat);

+    STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat);

+    STDMETHODIMP IsFormatSupported( const GUID * pFormat);

+    STDMETHODIMP QueryPreferredFormat( __out GUID *pFormat);

+    STDMETHODIMP ConvertTimeFormat(__out LONGLONG * pTarget, 

+                                   __in_opt const GUID * pTargetFormat,

+                                   LONGLONG Source, 

+                                   __in_opt const GUID * pSourceFormat );

+    STDMETHODIMP SetPositions( __inout_opt LONGLONG * pCurrent, DWORD CurrentFlags

+                             , __inout_opt LONGLONG * pStop, DWORD StopFlags );

+

+    STDMETHODIMP GetPositions( __out_opt LONGLONG * pCurrent, __out_opt LONGLONG * pStop );

+    STDMETHODIMP GetCurrentPosition( __out LONGLONG * pCurrent );

+    STDMETHODIMP GetStopPosition( __out LONGLONG * pStop );

+    STDMETHODIMP SetRate( double dRate);

+    STDMETHODIMP GetRate( __out double * pdRate);

+    STDMETHODIMP GetDuration( __out LONGLONG *pDuration);

+    STDMETHODIMP GetAvailable( __out_opt LONGLONG *pEarliest, __out_opt LONGLONG *pLatest );

+    STDMETHODIMP GetPreroll( __out LONGLONG *pllPreroll );

+

+    // IMediaPosition properties

+    STDMETHODIMP get_Duration(__out REFTIME * plength);

+    STDMETHODIMP put_CurrentPosition(REFTIME llTime);

+    STDMETHODIMP get_StopTime(__out REFTIME * pllTime);

+    STDMETHODIMP put_StopTime(REFTIME llTime);

+    STDMETHODIMP get_PrerollTime(__out REFTIME * pllTime);

+    STDMETHODIMP put_PrerollTime(REFTIME llTime);

+    STDMETHODIMP get_Rate(__out double * pdRate);

+    STDMETHODIMP put_Rate(double dRate);

+    STDMETHODIMP get_CurrentPosition(__out REFTIME * pllTime);

+    STDMETHODIMP CanSeekForward(__out LONG *pCanSeekForward);

+    STDMETHODIMP CanSeekBackward(__out LONG *pCanSeekBackward);

+

+private:

+    HRESULT GetSeekingLongLong( HRESULT (__stdcall IMediaSeeking::*pMethod)( LONGLONG * ),

+                                __out 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(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT*, IPin *);

+    HRESULT RegisterMediaTime(IMediaSample *pMediaSample);

+    HRESULT RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime);

+    HRESULT GetMediaTime(__out LONGLONG *pStartTime,__out_opt LONGLONG *pEndTime);

+    HRESULT ResetMediaTime();

+    HRESULT EOS();

+};

+

+STDAPI CreatePosPassThru(

+    __in_opt LPUNKNOWN pAgg,

+    BOOL bRenderer,

+    IPin *pPin,

+    __deref_out 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(__in_opt LPCTSTR, __in_opt LPUNKNOWN);

+

+    DECLARE_IUNKNOWN

+

+    // override this to publicise our interfaces

+    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);

+

+    /* IDispatch methods */

+    STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);

+

+    STDMETHODIMP GetTypeInfo(

+      UINT itinfo,

+      LCID lcid,

+      __deref_out ITypeInfo ** pptinfo);

+

+    STDMETHODIMP GetIDsOfNames(

+      REFIID riid,

+      __in_ecount(cNames) LPOLESTR * rgszNames,

+      UINT cNames,

+      LCID lcid,

+      __out_ecount(cNames) DISPID * rgdispid);

+

+    STDMETHODIMP Invoke(

+      DISPID dispidMember,

+      REFIID riid,

+      LCID lcid,

+      WORD wFlags,

+      __in DISPPARAMS * pdispparams,

+      __out_opt VARIANT * pvarResult,

+      __out_opt EXCEPINFO * pexcepinfo,

+      __out_opt 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(__in_opt LPCTSTR, __in_opt LPUNKNOWN);

+

+    DECLARE_IUNKNOWN

+

+    // override this to publicise our interfaces

+    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);

+

+    /* IDispatch methods */

+    STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);

+

+    STDMETHODIMP GetTypeInfo(

+      UINT itinfo,

+      LCID lcid,

+      __deref_out ITypeInfo ** pptinfo);

+

+    STDMETHODIMP GetIDsOfNames(

+      REFIID riid,

+      __in_ecount(cNames) LPOLESTR * rgszNames,

+      UINT cNames,

+      LCID lcid,

+      __out_ecount(cNames) DISPID * rgdispid);

+

+    STDMETHODIMP Invoke(

+      DISPID dispidMember,

+      REFIID riid,

+      LCID lcid,

+      WORD wFlags,

+      __in DISPPARAMS * pdispparams,

+      __out_opt VARIANT * pvarResult,

+      __out_opt EXCEPINFO * pexcepinfo,

+      __out_opt UINT * puArgErr);

+

+    STDMETHODIMP GetPreferredAspectRatio(

+      __out long *plAspectX,

+      __out 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(__in_opt LPCTSTR, __in_opt LPUNKNOWN);

+

+    DECLARE_IUNKNOWN

+

+    // override this to publicise our interfaces

+    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);

+

+    /* IDispatch methods */

+    STDMETHODIMP GetTypeInfoCount(__out UINT * pctinfo);

+

+    STDMETHODIMP GetTypeInfo(

+      UINT itinfo,

+      LCID lcid,

+      __deref_out ITypeInfo ** pptinfo);

+

+    STDMETHODIMP GetIDsOfNames(

+      REFIID riid,

+      __in_ecount(cNames) LPOLESTR * rgszNames,

+      UINT cNames,

+      LCID lcid,

+      __out_ecount(cNames) DISPID * rgdispid);

+

+    STDMETHODIMP Invoke(

+      DISPID dispidMember,

+      REFIID riid,

+      LCID lcid,

+      WORD wFlags,

+      __in DISPPARAMS * pdispparams,

+      __out_opt VARIANT * pvarResult,

+      __out_opt EXCEPINFO * pexcepinfo,

+      __out_opt 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(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT*, __in CCritSec *);

+

+    // IMediaPosition methods

+    STDMETHODIMP get_Duration(__out REFTIME * plength);

+    STDMETHODIMP put_CurrentPosition(REFTIME llTime);

+    STDMETHODIMP get_StopTime(__out REFTIME * pllTime);

+    STDMETHODIMP put_StopTime(REFTIME llTime);

+    STDMETHODIMP get_PrerollTime(__out REFTIME * pllTime);

+    STDMETHODIMP put_PrerollTime(REFTIME llTime);

+    STDMETHODIMP get_Rate(__out double * pdRate);

+    STDMETHODIMP put_Rate(double dRate);

+    STDMETHODIMP CanSeekForward(__out LONG *pCanSeekForward);

+    STDMETHODIMP CanSeekBackward(__out LONG *pCanSeekBackward);

+

+    // override if you can return the data you are actually working on

+    STDMETHODIMP get_CurrentPosition(__out 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, __deref_out void **ppv);

+

+    // IMediaSeeking methods

+

+    STDMETHODIMP IsFormatSupported(const GUID * pFormat);

+    STDMETHODIMP QueryPreferredFormat(__out GUID *pFormat);

+    STDMETHODIMP SetTimeFormat(const GUID * pFormat);

+    STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat);

+    STDMETHODIMP GetTimeFormat(__out GUID *pFormat);

+    STDMETHODIMP GetDuration(__out LONGLONG *pDuration);

+    STDMETHODIMP GetStopPosition(__out LONGLONG *pStop);

+    STDMETHODIMP GetCurrentPosition(__out LONGLONG *pCurrent);

+    STDMETHODIMP GetCapabilities( __out DWORD * pCapabilities );

+    STDMETHODIMP CheckCapabilities( __inout DWORD * pCapabilities );

+    STDMETHODIMP ConvertTimeFormat( __out LONGLONG * pTarget, 

+                                    __in_opt const GUID * pTargetFormat,

+                                    LONGLONG Source, 

+                                    __in_opt const GUID * pSourceFormat );

+

+    STDMETHODIMP SetPositions( __inout_opt LONGLONG * pCurrent,  DWORD CurrentFlags

+			     , __inout_opt LONGLONG * pStop,  DWORD StopFlags );

+

+    STDMETHODIMP GetPositions( __out_opt LONGLONG * pCurrent, __out_opt LONGLONG * pStop );

+

+    STDMETHODIMP GetAvailable( __out_opt LONGLONG * pEarliest, __out_opt LONGLONG * pLatest );

+    STDMETHODIMP SetRate( double dRate);

+    STDMETHODIMP GetRate( __out double * pdRate);

+    STDMETHODIMP GetPreroll(__out LONGLONG *pPreroll);

+

+

+protected:

+

+    // ctor

+    CSourceSeeking(__in_opt LPCTSTR, __in_opt LPUNKNOWN, __inout HRESULT*, __in 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, __in_ecount(nArgs) VARIANT* pArgs, __inout_opt 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(

+        __inout CCmdQueue * pQ,

+        __in_opt LPUNKNOWN   pUnk,               // aggregation outer unk

+        __inout HRESULT *   phr,

+        __in LPUNKNOWN   pUnkExecutor,       // object that will execute this cmd

+        REFTIME     time,

+        __in GUID*       iid,

+        long        dispidMethod,

+        short       wFlags,

+        long        cArgs,

+        __in_ecount(cArgs) VARIANT*    pDispParams,

+        __out VARIANT*    pvarResult,

+        __out short*      puArgErr,

+        BOOL        bStream

+        );

+

+    DECLARE_IUNKNOWN

+

+    // override this to publicise our interfaces

+    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __out void **ppv);

+

+    // IDeferredCommand methods

+    STDMETHODIMP Cancel();

+    STDMETHODIMP Confidence(

+                    __out LONG* pConfidence);

+    STDMETHODIMP Postpone(

+                    REFTIME newtime);

+    STDMETHODIMP GetHResult(

+                    __out 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(__inout_opt HRESULT *phr = NULL);

+    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(

+        __out CDeferredCommand **ppCmd,

+        __in LPUNKNOWN   pUnk,

+        REFTIME     time,

+        __in GUID*       iid,

+        long        dispidMethod,

+        short       wFlags,

+        long        cArgs,

+        __in_ecount(cArgs) VARIANT*    pDispParams,

+        __out VARIANT*    pvarResult,

+        __out short*      puArgErr,

+        BOOL        bStream

+    );

+

+    // called by the CDeferredCommand object to add and remove itself

+    // from the queue

+    virtual HRESULT Insert(__in CDeferredCommand* pCmd);

+    virtual HRESULT Remove(__in 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(__in_opt 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(__out 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, __out 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__