924 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			924 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								// 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__
							 |