//------------------------------------------------------------------------------
// File: CtlUtil.cpp
//
// 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

#include <pjmedia-videodev/config.h>

#if defined(PJMEDIA_VIDEO_DEV_HAS_DSHOW) && PJMEDIA_VIDEO_DEV_HAS_DSHOW != 0

#include <streams.h>
#include <limits.h>
#include "seekpt.h"

// 'bool' non standard reserved word
#pragma warning(disable:4237)


// --- CBaseDispatch implementation ----------
CBaseDispatch::~CBaseDispatch()
{
    if (m_pti) {
	m_pti->Release();
    }
}


// return 1 if we support GetTypeInfo

STDMETHODIMP
CBaseDispatch::GetTypeInfoCount(__out UINT * pctinfo)
{
    CheckPointer(pctinfo,E_POINTER);
    ValidateReadWritePtr(pctinfo,sizeof(UINT *));
    *pctinfo = 1;
    return S_OK;
}


typedef HRESULT (STDAPICALLTYPE *LPLOADTYPELIB)(
			    const OLECHAR FAR *szFile,
			    __deref_out ITypeLib FAR* FAR* pptlib);

typedef HRESULT (STDAPICALLTYPE *LPLOADREGTYPELIB)(REFGUID rguid,
			    WORD wVerMajor,
			    WORD wVerMinor,
			    LCID lcid,
			    __deref_out ITypeLib FAR* FAR* pptlib);

// attempt to find our type library

STDMETHODIMP
CBaseDispatch::GetTypeInfo(
  REFIID riid,
  UINT itinfo,
  LCID lcid,
  __deref_out ITypeInfo ** pptinfo)
{
    CheckPointer(pptinfo,E_POINTER);
    ValidateReadWritePtr(pptinfo,sizeof(ITypeInfo *));
    HRESULT hr;

    *pptinfo = NULL;

    // we only support one type element
    if (0 != itinfo) {
	return TYPE_E_ELEMENTNOTFOUND;
    }

    if (NULL == pptinfo) {
	return E_POINTER;
    }

    // always look for neutral
    if (NULL == m_pti) {

	LPLOADTYPELIB	    lpfnLoadTypeLib;
	LPLOADREGTYPELIB    lpfnLoadRegTypeLib;
	ITypeLib	    *ptlib;
	HINSTANCE	    hInst;

	static const char  szTypeLib[]	  = "LoadTypeLib";
	static const char  szRegTypeLib[] = "LoadRegTypeLib";
	static const WCHAR szControl[]	  = L"control.tlb";

	//
	// Try to get the Ole32Aut.dll module handle.
	//

	hInst = LoadOLEAut32();
	if (hInst == NULL) {
	    DWORD dwError = GetLastError();
	    return AmHresultFromWin32(dwError);
	}
	lpfnLoadRegTypeLib = (LPLOADREGTYPELIB)GetProcAddress(hInst,
							      szRegTypeLib);
	if (lpfnLoadRegTypeLib == NULL) {
	    DWORD dwError = GetLastError();
	    return AmHresultFromWin32(dwError);
	}

	hr = (*lpfnLoadRegTypeLib)(LIBID_QuartzTypeLib, 1, 0, // version 1.0
				   lcid, &ptlib);

	if (FAILED(hr)) {

	    // attempt to load directly - this will fill the
	    // registry in if it finds it

	    lpfnLoadTypeLib = (LPLOADTYPELIB)GetProcAddress(hInst, szTypeLib);
	    if (lpfnLoadTypeLib == NULL) {
		DWORD dwError = GetLastError();
		return AmHresultFromWin32(dwError);
	    }

	    hr = (*lpfnLoadTypeLib)(szControl, &ptlib);
	    if (FAILED(hr)) {
		return hr;
	    }
	}

	hr = ptlib->GetTypeInfoOfGuid(
		    riid,
		    &m_pti);

	ptlib->Release();

	if (FAILED(hr)) {
	    return hr;
	}
    }

    *pptinfo = m_pti;
    m_pti->AddRef();
    return S_OK;
}


STDMETHODIMP
CBaseDispatch::GetIDsOfNames(
  REFIID riid,
  __in_ecount(cNames) LPOLESTR * rgszNames,
  UINT cNames,
  LCID lcid,
  __out_ecount(cNames) DISPID * rgdispid)
{
    // although the IDispatch riid is dead, we use this to pass from
    // the interface implementation class to us the iid we are talking about.

    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(riid, 0, lcid, &pti);

    if (SUCCEEDED(hr)) {
	hr = pti->GetIDsOfNames(rgszNames, cNames, rgdispid);

	pti->Release();
    }
    return hr;
}


// --- CMediaControl implementation ---------

CMediaControl::CMediaControl(const TCHAR * name,LPUNKNOWN pUnk) :
    CUnknown(name, pUnk)
{
}

// expose our interfaces IMediaControl and IUnknown

STDMETHODIMP
CMediaControl::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IMediaControl) {
	return GetInterface( (IMediaControl *) this, ppv);
    } else {
	return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


// return 1 if we support GetTypeInfo

STDMETHODIMP
CMediaControl::GetTypeInfoCount(__out UINT * pctinfo)
{
    return m_basedisp.GetTypeInfoCount(pctinfo);
}


// attempt to find our type library

STDMETHODIMP
CMediaControl::GetTypeInfo(
  UINT itinfo,
  LCID lcid,
  __deref_out ITypeInfo ** pptinfo)
{
    return m_basedisp.GetTypeInfo(
		IID_IMediaControl,
		itinfo,
		lcid,
		pptinfo);
}


STDMETHODIMP
CMediaControl::GetIDsOfNames(
  REFIID riid,
  __in_ecount(cNames) LPOLESTR * rgszNames,
  UINT cNames,
  LCID lcid,
  __out_ecount(cNames) DISPID * rgdispid)
{
    return m_basedisp.GetIDsOfNames(
			IID_IMediaControl,
			rgszNames,
			cNames,
			lcid,
			rgdispid);
}


STDMETHODIMP
CMediaControl::Invoke(
  DISPID dispidMember,
  REFIID riid,
  LCID lcid,
  WORD wFlags,
  __in DISPPARAMS * pdispparams,
  __out_opt VARIANT * pvarResult,
  __out_opt EXCEPINFO * pexcepinfo,
  __out_opt UINT * puArgErr)
{
    // this parameter is a dead leftover from an earlier interface
    if (IID_NULL != riid) {
	return DISP_E_UNKNOWNINTERFACE;
    }

    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(0, lcid, &pti);

    if (FAILED(hr)) {
	return hr;
    }

    hr = pti->Invoke(
	    (IMediaControl *)this,
	    dispidMember,
	    wFlags,
	    pdispparams,
	    pvarResult,
	    pexcepinfo,
	    puArgErr);

    pti->Release();
    return hr;
}


// --- CMediaEvent implementation ----------


CMediaEvent::CMediaEvent(__in_opt LPCTSTR name,__in_opt LPUNKNOWN pUnk) :
    CUnknown(name, pUnk)
{
}


// expose our interfaces IMediaEvent and IUnknown

STDMETHODIMP
CMediaEvent::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IMediaEvent || riid == IID_IMediaEventEx) {
	return GetInterface( (IMediaEventEx *) this, ppv);
    } else {
	return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


// return 1 if we support GetTypeInfo

STDMETHODIMP
CMediaEvent::GetTypeInfoCount(__out UINT * pctinfo)
{
    return m_basedisp.GetTypeInfoCount(pctinfo);
}


// attempt to find our type library

STDMETHODIMP
CMediaEvent::GetTypeInfo(
  UINT itinfo,
  LCID lcid,
  __deref_out ITypeInfo ** pptinfo)
{
    return m_basedisp.GetTypeInfo(
		IID_IMediaEvent,
		itinfo,
		lcid,
		pptinfo);
}


STDMETHODIMP
CMediaEvent::GetIDsOfNames(
  REFIID riid,
  __in_ecount(cNames) LPOLESTR * rgszNames,
  UINT cNames,
  LCID lcid,
  __out_ecount(cNames) DISPID * rgdispid)
{
    return m_basedisp.GetIDsOfNames(
			IID_IMediaEvent,
			rgszNames,
			cNames,
			lcid,
			rgdispid);
}


STDMETHODIMP
CMediaEvent::Invoke(
  DISPID dispidMember,
  REFIID riid,
  LCID lcid,
  WORD wFlags,
  __in DISPPARAMS * pdispparams,
  __out_opt VARIANT * pvarResult,
  __out_opt EXCEPINFO * pexcepinfo,
  __out_opt UINT * puArgErr)
{
    // this parameter is a dead leftover from an earlier interface
    if (IID_NULL != riid) {
	return DISP_E_UNKNOWNINTERFACE;
    }

    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(0, lcid, &pti);

    if (FAILED(hr)) {
	return hr;
    }

    hr = pti->Invoke(
	    (IMediaEvent *)this,
	    dispidMember,
	    wFlags,
	    pdispparams,
	    pvarResult,
	    pexcepinfo,
	    puArgErr);

    pti->Release();
    return hr;
}


// --- CMediaPosition implementation ----------


CMediaPosition::CMediaPosition(__in_opt LPCTSTR name,__in_opt LPUNKNOWN pUnk) :
    CUnknown(name, pUnk)
{
}

CMediaPosition::CMediaPosition(__in_opt LPCTSTR name,
                               __in_opt LPUNKNOWN pUnk,
                               __inout HRESULT * phr) :
    CUnknown(name, pUnk)
{
    UNREFERENCED_PARAMETER(phr);
}


// expose our interfaces IMediaPosition and IUnknown

STDMETHODIMP
CMediaPosition::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IMediaPosition) {
	return GetInterface( (IMediaPosition *) this, ppv);
    } else {
	return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


// return 1 if we support GetTypeInfo

STDMETHODIMP
CMediaPosition::GetTypeInfoCount(__out UINT * pctinfo)
{
    return m_basedisp.GetTypeInfoCount(pctinfo);
}


// attempt to find our type library

STDMETHODIMP
CMediaPosition::GetTypeInfo(
  UINT itinfo,
  LCID lcid,
  __deref_out ITypeInfo ** pptinfo)
{
    return m_basedisp.GetTypeInfo(
		IID_IMediaPosition,
		itinfo,
		lcid,
		pptinfo);
}


STDMETHODIMP
CMediaPosition::GetIDsOfNames(
  REFIID riid,
  __in_ecount(cNames) LPOLESTR * rgszNames,
  UINT cNames,
  LCID lcid,
  __out_ecount(cNames) DISPID * rgdispid)
{
    return m_basedisp.GetIDsOfNames(
			IID_IMediaPosition,
			rgszNames,
			cNames,
			lcid,
			rgdispid);
}


STDMETHODIMP
CMediaPosition::Invoke(
  DISPID dispidMember,
  REFIID riid,
  LCID lcid,
  WORD wFlags,
  __in DISPPARAMS * pdispparams,
  __out_opt VARIANT * pvarResult,
  __out_opt EXCEPINFO * pexcepinfo,
  __out_opt UINT * puArgErr)
{
    // this parameter is a dead leftover from an earlier interface
    if (IID_NULL != riid) {
	return DISP_E_UNKNOWNINTERFACE;
    }

    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(0, lcid, &pti);

    if (FAILED(hr)) {
	return hr;
    }

    hr = pti->Invoke(
	    (IMediaPosition *)this,
	    dispidMember,
	    wFlags,
	    pdispparams,
	    pvarResult,
	    pexcepinfo,
	    puArgErr);

    pti->Release();
    return hr;
}


// --- IMediaPosition and IMediaSeeking pass through class ----------


CPosPassThru::CPosPassThru(__in_opt LPCTSTR pName,
			   __in_opt LPUNKNOWN pUnk,
			   __inout HRESULT *phr,
			   IPin *pPin) :
    CMediaPosition(pName,pUnk),
    m_pPin(pPin)
{
    if (pPin == NULL) {
	*phr = E_POINTER;
	return;
    }
}


// Expose our IMediaSeeking and IMediaPosition interfaces

STDMETHODIMP
CPosPassThru::NonDelegatingQueryInterface(REFIID riid,__deref_out void **ppv)
{
    CheckPointer(ppv,E_POINTER);
    *ppv = NULL;

    if (riid == IID_IMediaSeeking) {
	return GetInterface( static_cast<IMediaSeeking *>(this), ppv);
    }
    return CMediaPosition::NonDelegatingQueryInterface(riid,ppv);
}


// Return the IMediaPosition interface from our peer

HRESULT
CPosPassThru::GetPeer(IMediaPosition ** ppMP)
{
    *ppMP = NULL;

    IPin *pConnected;
    HRESULT hr = m_pPin->ConnectedTo(&pConnected);
    if (FAILED(hr)) {
	return E_NOTIMPL;
    }
    IMediaPosition * pMP;
    hr = pConnected->QueryInterface(IID_IMediaPosition, (void **) &pMP);
    pConnected->Release();
    if (FAILED(hr)) {
	return E_NOTIMPL;
    }

    *ppMP = pMP;
    return S_OK;
}


// Return the IMediaSeeking interface from our peer

HRESULT
CPosPassThru::GetPeerSeeking(__deref_out IMediaSeeking ** ppMS)
{
    *ppMS = NULL;

    IPin *pConnected;
    HRESULT hr = m_pPin->ConnectedTo(&pConnected);
    if (FAILED(hr)) {
	return E_NOTIMPL;
    }
    IMediaSeeking * pMS;
    hr = pConnected->QueryInterface(IID_IMediaSeeking, (void **) &pMS);
    pConnected->Release();
    if (FAILED(hr)) {
	return E_NOTIMPL;
    }

    *ppMS = pMS;
    return S_OK;
}


// --- IMediaSeeking methods ----------


STDMETHODIMP
CPosPassThru::GetCapabilities(__out DWORD * pCaps)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->GetCapabilities(pCaps);
    pMS->Release();
    return hr;
}

STDMETHODIMP
CPosPassThru::CheckCapabilities(__inout DWORD * pCaps)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->CheckCapabilities(pCaps);
    pMS->Release();
    return hr;
}

STDMETHODIMP
CPosPassThru::IsFormatSupported(const GUID * pFormat)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->IsFormatSupported(pFormat);
    pMS->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::QueryPreferredFormat(__out GUID *pFormat)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->QueryPreferredFormat(pFormat);
    pMS->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::SetTimeFormat(const GUID * pFormat)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->SetTimeFormat(pFormat);
    pMS->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::GetTimeFormat(__out GUID *pFormat)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->GetTimeFormat(pFormat);
    pMS->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::IsUsingTimeFormat(const GUID * pFormat)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->IsUsingTimeFormat(pFormat);
    pMS->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::ConvertTimeFormat(__out LONGLONG * pTarget, 
                                __in_opt const GUID * pTargetFormat,
				LONGLONG Source, 
                                __in_opt const GUID * pSourceFormat )
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat );
    pMS->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::SetPositions( __inout_opt LONGLONG * pCurrent, 
                            DWORD CurrentFlags, 
                            __inout_opt LONGLONG * pStop, 
                            DWORD StopFlags )
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->SetPositions(pCurrent, CurrentFlags, pStop, StopFlags );
    pMS->Release();
    return hr;
}

STDMETHODIMP
CPosPassThru::GetPositions(__out_opt LONGLONG *pCurrent, __out_opt LONGLONG * pStop)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->GetPositions(pCurrent,pStop);
    pMS->Release();
    return hr;
}

HRESULT
CPosPassThru::GetSeekingLongLong
( HRESULT (__stdcall IMediaSeeking::*pMethod)( __out LONGLONG * )
, LONGLONG * pll
)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (SUCCEEDED(hr))
    {
	hr = (pMS->*pMethod)(pll);
	pMS->Release();
    }
    return hr;
}

// If we don't have a current position then ask upstream

STDMETHODIMP
CPosPassThru::GetCurrentPosition(__out LONGLONG *pCurrent)
{
    // Can we report the current position
    HRESULT hr = GetMediaTime(pCurrent,NULL);
    if (SUCCEEDED(hr)) hr = NOERROR;
    else hr = GetSeekingLongLong( &IMediaSeeking::GetCurrentPosition, pCurrent );
    return hr;
}


STDMETHODIMP
CPosPassThru::GetStopPosition(__out LONGLONG *pStop)
{
    return GetSeekingLongLong( &IMediaSeeking::GetStopPosition, pStop );;
}

STDMETHODIMP
CPosPassThru::GetDuration(__out LONGLONG *pDuration)
{
    return GetSeekingLongLong( &IMediaSeeking::GetDuration, pDuration );;
}


STDMETHODIMP
CPosPassThru::GetPreroll(__out LONGLONG *pllPreroll)
{
    return GetSeekingLongLong( &IMediaSeeking::GetPreroll, pllPreroll );;
}


STDMETHODIMP
CPosPassThru::GetAvailable( __out_opt LONGLONG *pEarliest, __out_opt LONGLONG *pLatest )
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMS->GetAvailable( pEarliest, pLatest );
    pMS->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::GetRate(__out double * pdRate)
{
    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMS->GetRate(pdRate);
    pMS->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::SetRate(double dRate)
{
    if (0.0 == dRate) {
		return E_INVALIDARG;
    }

    IMediaSeeking* pMS;
    HRESULT hr = GetPeerSeeking(&pMS);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMS->SetRate(dRate);
    pMS->Release();
    return hr;
}




// --- IMediaPosition methods ----------


STDMETHODIMP
CPosPassThru::get_Duration(__out REFTIME * plength)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }

    hr = pMP->get_Duration(plength);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::get_CurrentPosition(__out REFTIME * pllTime)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->get_CurrentPosition(pllTime);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::put_CurrentPosition(REFTIME llTime)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->put_CurrentPosition(llTime);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::get_StopTime(__out REFTIME * pllTime)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->get_StopTime(pllTime);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::put_StopTime(REFTIME llTime)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->put_StopTime(llTime);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::get_PrerollTime(__out REFTIME * pllTime)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->get_PrerollTime(pllTime);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::put_PrerollTime(REFTIME llTime)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->put_PrerollTime(llTime);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::get_Rate(__out double * pdRate)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->get_Rate(pdRate);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::put_Rate(double dRate)
{
    if (0.0 == dRate) {
		return E_INVALIDARG;
    }

    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->put_Rate(dRate);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::CanSeekForward(__out LONG *pCanSeekForward)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->CanSeekForward(pCanSeekForward);
    pMP->Release();
    return hr;
}


STDMETHODIMP
CPosPassThru::CanSeekBackward(__out LONG *pCanSeekBackward)
{
    IMediaPosition* pMP;
    HRESULT hr = GetPeer(&pMP);
    if (FAILED(hr)) {
	return hr;
    }
    hr = pMP->CanSeekBackward(pCanSeekBackward);
    pMP->Release();
    return hr;
}


// --- Implements the CRendererPosPassThru class ----------


// Media times (eg current frame, field, sample etc) are passed through the
// filtergraph in media samples. When a renderer gets a sample with media
// times in it, it will call one of the RegisterMediaTime methods we expose
// (one takes an IMediaSample, the other takes the media times direct). We
// store the media times internally and return them in GetCurrentPosition.

CRendererPosPassThru::CRendererPosPassThru(__in_opt LPCTSTR pName,
					   __in_opt LPUNKNOWN pUnk,
					   __inout HRESULT *phr,
					   IPin *pPin) :
    CPosPassThru(pName,pUnk,phr,pPin),
    m_StartMedia(0),
    m_EndMedia(0),
    m_bReset(TRUE)
{
}


// Sets the media times the object should report

HRESULT
CRendererPosPassThru::RegisterMediaTime(IMediaSample *pMediaSample)
{
    ASSERT(pMediaSample);
    LONGLONG StartMedia;
    LONGLONG EndMedia;

    CAutoLock cAutoLock(&m_PositionLock);

    // Get the media times from the sample

    HRESULT hr = pMediaSample->GetTime(&StartMedia,&EndMedia);
    if (FAILED(hr))
    {
	ASSERT(hr == VFW_E_SAMPLE_TIME_NOT_SET);
	return hr;
    }

    m_StartMedia = StartMedia;
    m_EndMedia = EndMedia;
    m_bReset = FALSE;
    return NOERROR;
}


// Sets the media times the object should report

HRESULT
CRendererPosPassThru::RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime)
{
    CAutoLock cAutoLock(&m_PositionLock);
    m_StartMedia = StartTime;
    m_EndMedia = EndTime;
    m_bReset = FALSE;
    return NOERROR;
}


// Return the current media times registered in the object

HRESULT
CRendererPosPassThru::GetMediaTime(__out LONGLONG *pStartTime, __out_opt LONGLONG *pEndTime)
{
    ASSERT(pStartTime);

    CAutoLock cAutoLock(&m_PositionLock);
    if (m_bReset == TRUE) {
	return E_FAIL;
    }

    // We don't have to return the end time

    HRESULT hr = ConvertTimeFormat( pStartTime, 0, m_StartMedia, &TIME_FORMAT_MEDIA_TIME );
    if (pEndTime && SUCCEEDED(hr)) {
	hr = ConvertTimeFormat( pEndTime, 0, m_EndMedia, &TIME_FORMAT_MEDIA_TIME );
    }
    return hr;
}


// Resets the media times we hold

HRESULT
CRendererPosPassThru::ResetMediaTime()
{
    CAutoLock cAutoLock(&m_PositionLock);
    m_StartMedia = 0;
    m_EndMedia = 0;
    m_bReset = TRUE;
    return NOERROR;
}

// Intended to be called by the owing filter during EOS processing so
// that the media times can be adjusted to the stop time.  This ensures
// that the GetCurrentPosition will actully get to the stop position.
HRESULT
CRendererPosPassThru::EOS()
{
    HRESULT hr;

    if ( m_bReset == TRUE ) hr = E_FAIL;
    else
    {
	LONGLONG llStop;
	if SUCCEEDED(hr=GetStopPosition(&llStop))
	{
	    CAutoLock cAutoLock(&m_PositionLock);
	    m_StartMedia =
	    m_EndMedia	 = llStop;
	}
    }
    return hr;
}

// -- CSourceSeeking implementation ------------

CSourceSeeking::CSourceSeeking(
    __in_opt LPCTSTR pName,
    __in_opt LPUNKNOWN pUnk,
    __inout HRESULT* phr,
    __in CCritSec * pLock) :
        CUnknown(pName, pUnk),
        m_pLock(pLock),
        m_rtStart((long)0)
{
    m_rtStop = _I64_MAX / 2;
    m_rtDuration = m_rtStop;
    m_dRateSeeking = 1.0;

    m_dwSeekingCaps = AM_SEEKING_CanSeekForwards
        | AM_SEEKING_CanSeekBackwards
        | AM_SEEKING_CanSeekAbsolute
        | AM_SEEKING_CanGetStopPos
        | AM_SEEKING_CanGetDuration;
}

HRESULT CSourceSeeking::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    if(riid == IID_IMediaSeeking) {
        CheckPointer(ppv, E_POINTER);
        return GetInterface(static_cast<IMediaSeeking *>(this), ppv);
    }
    else {
        return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


HRESULT CSourceSeeking::IsFormatSupported(const GUID * pFormat)
{
    CheckPointer(pFormat, E_POINTER);
    // only seeking in time (REFERENCE_TIME units) is supported
    return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
}

HRESULT CSourceSeeking::QueryPreferredFormat(__out GUID *pFormat)
{
    CheckPointer(pFormat, E_POINTER);
    *pFormat = TIME_FORMAT_MEDIA_TIME;
    return S_OK;
}

HRESULT CSourceSeeking::SetTimeFormat(const GUID * pFormat)
{
    CheckPointer(pFormat, E_POINTER);

    // nothing to set; just check that it's TIME_FORMAT_TIME
    return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : E_INVALIDARG;
}

HRESULT CSourceSeeking::IsUsingTimeFormat(const GUID * pFormat)
{
    CheckPointer(pFormat, E_POINTER);
    return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE;
}

HRESULT CSourceSeeking::GetTimeFormat(__out GUID *pFormat)
{
    CheckPointer(pFormat, E_POINTER);
    *pFormat = TIME_FORMAT_MEDIA_TIME;
    return S_OK;
}

HRESULT CSourceSeeking::GetDuration(__out LONGLONG *pDuration)
{
    CheckPointer(pDuration, E_POINTER);
    CAutoLock lock(m_pLock);
    *pDuration = m_rtDuration;
    return S_OK;
}

HRESULT CSourceSeeking::GetStopPosition(__out LONGLONG *pStop)
{
    CheckPointer(pStop, E_POINTER);
    CAutoLock lock(m_pLock);
    *pStop = m_rtStop;
    return S_OK;
}

HRESULT CSourceSeeking::GetCurrentPosition(__out LONGLONG *pCurrent)
{
    // GetCurrentPosition is typically supported only in renderers and
    // not in source filters.
    return E_NOTIMPL;
}

HRESULT CSourceSeeking::GetCapabilities( __out DWORD * pCapabilities )
{
    CheckPointer(pCapabilities, E_POINTER);
    *pCapabilities = m_dwSeekingCaps;
    return S_OK;
}

HRESULT CSourceSeeking::CheckCapabilities( __inout DWORD * pCapabilities )
{
    CheckPointer(pCapabilities, E_POINTER);

    // make sure all requested capabilities are in our mask
    return (~m_dwSeekingCaps & *pCapabilities) ? S_FALSE : S_OK;
}

HRESULT CSourceSeeking::ConvertTimeFormat( __out LONGLONG * pTarget, 
                                           __in_opt const GUID * pTargetFormat,
                                           LONGLONG Source, 
                                           __in_opt const GUID * pSourceFormat )
{
    CheckPointer(pTarget, E_POINTER);
    // format guids can be null to indicate current format

    // since we only support TIME_FORMAT_MEDIA_TIME, we don't really
    // offer any conversions.
    if(pTargetFormat == 0 || *pTargetFormat == TIME_FORMAT_MEDIA_TIME)
    {
        if(pSourceFormat == 0 || *pSourceFormat == TIME_FORMAT_MEDIA_TIME)
        {
            *pTarget = Source;
            return S_OK;
        }
    }

    return E_INVALIDARG;
}


HRESULT CSourceSeeking::SetPositions( __inout_opt LONGLONG * pCurrent,  
                                      DWORD CurrentFlags, 
                                      __inout_opt LONGLONG * pStop,  
                                      DWORD StopFlags )
{
    DWORD StopPosBits = StopFlags & AM_SEEKING_PositioningBitsMask;
    DWORD StartPosBits = CurrentFlags & AM_SEEKING_PositioningBitsMask;

    if(StopFlags) {
        CheckPointer(pStop, E_POINTER);

        // accept only relative, incremental, or absolute positioning
        if(StopPosBits != StopFlags) {
            return E_INVALIDARG;
        }
    }

    if(CurrentFlags) {
        CheckPointer(pCurrent, E_POINTER);
        if(StartPosBits != AM_SEEKING_AbsolutePositioning &&
           StartPosBits != AM_SEEKING_RelativePositioning) {
            return E_INVALIDARG;
        }
    }


    // scope for autolock
    {
        CAutoLock lock(m_pLock);

        // set start position
        if(StartPosBits == AM_SEEKING_AbsolutePositioning)
        {
            m_rtStart = *pCurrent;
        }
        else if(StartPosBits == AM_SEEKING_RelativePositioning)
        {
            m_rtStart += *pCurrent;
        }

        // set stop position
        if(StopPosBits == AM_SEEKING_AbsolutePositioning)
        {
            m_rtStop = *pStop;
        }
        else if(StopPosBits == AM_SEEKING_IncrementalPositioning)
        {
            m_rtStop = m_rtStart + *pStop;
        }
        else if(StopPosBits == AM_SEEKING_RelativePositioning)
        {
            m_rtStop = m_rtStop + *pStop;
        }
    }


    HRESULT hr = S_OK;
    if(SUCCEEDED(hr) && StopPosBits) {
        hr = ChangeStop();
    }
    if(StartPosBits) {
        hr = ChangeStart();
    }

    return hr;
}


HRESULT CSourceSeeking::GetPositions( __out_opt LONGLONG * pCurrent, __out_opt LONGLONG * pStop )
{
    if(pCurrent) {
        *pCurrent = m_rtStart;
    }
    if(pStop) {
        *pStop = m_rtStop;
    }

    return S_OK;;
}


HRESULT CSourceSeeking::GetAvailable( __out_opt LONGLONG * pEarliest, __out_opt LONGLONG * pLatest )
{
    if(pEarliest) {
        *pEarliest = 0;
    }
    if(pLatest) {
        CAutoLock lock(m_pLock);
        *pLatest = m_rtDuration;
    }
    return S_OK;
}

HRESULT CSourceSeeking::SetRate( double dRate)
{
    {
        CAutoLock lock(m_pLock);
        m_dRateSeeking = dRate;
    }
    return ChangeRate();
}

HRESULT CSourceSeeking::GetRate( __out double * pdRate)
{
    CheckPointer(pdRate, E_POINTER);
    CAutoLock lock(m_pLock);
    *pdRate = m_dRateSeeking;
    return S_OK;
}

HRESULT CSourceSeeking::GetPreroll(__out LONGLONG *pPreroll)
{
    CheckPointer(pPreroll, E_POINTER);
    *pPreroll = 0;
    return S_OK;
}





// --- CSourcePosition implementation ----------


CSourcePosition::CSourcePosition(__in_opt LPCTSTR pName,
				 __in_opt LPUNKNOWN pUnk,
				 __inout HRESULT* phr,
				 __in CCritSec * pLock) :
    CMediaPosition(pName, pUnk),
    m_pLock(pLock),
    m_Start(CRefTime((LONGLONG)0))
{
    m_Stop = _I64_MAX;
    m_Rate = 1.0;
}


STDMETHODIMP
CSourcePosition::get_Duration(__out REFTIME * plength)
{
    CheckPointer(plength,E_POINTER);
    ValidateReadWritePtr(plength,sizeof(REFTIME));
    CAutoLock lock(m_pLock);

    *plength = m_Duration;
    return S_OK;
}


STDMETHODIMP
CSourcePosition::put_CurrentPosition(REFTIME llTime)
{
    m_pLock->Lock();
    m_Start = llTime;
    m_pLock->Unlock();

    return ChangeStart();
}


STDMETHODIMP
CSourcePosition::get_StopTime(__out REFTIME * pllTime)
{
    CheckPointer(pllTime,E_POINTER);
    ValidateReadWritePtr(pllTime,sizeof(REFTIME));
    CAutoLock lock(m_pLock);

    *pllTime = m_Stop;
    return S_OK;
}


STDMETHODIMP
CSourcePosition::put_StopTime(REFTIME llTime)
{
    m_pLock->Lock();
    m_Stop = llTime;
    m_pLock->Unlock();

    return ChangeStop();
}


STDMETHODIMP
CSourcePosition::get_PrerollTime(__out REFTIME * pllTime)
{
    CheckPointer(pllTime,E_POINTER);
    ValidateReadWritePtr(pllTime,sizeof(REFTIME));
    return E_NOTIMPL;
}


STDMETHODIMP
CSourcePosition::put_PrerollTime(REFTIME llTime)
{
    return E_NOTIMPL;
}


STDMETHODIMP
CSourcePosition::get_Rate(__out double * pdRate)
{
    CheckPointer(pdRate,E_POINTER);
    ValidateReadWritePtr(pdRate,sizeof(double));
    CAutoLock lock(m_pLock);

    *pdRate = m_Rate;
    return S_OK;
}


STDMETHODIMP
CSourcePosition::put_Rate(double dRate)
{
    m_pLock->Lock();
    m_Rate = dRate;
    m_pLock->Unlock();

    return ChangeRate();
}


// By default we can seek forwards

STDMETHODIMP
CSourcePosition::CanSeekForward(__out LONG *pCanSeekForward)
{
    CheckPointer(pCanSeekForward,E_POINTER);
    *pCanSeekForward = OATRUE;
    return S_OK;
}


// By default we can seek backwards

STDMETHODIMP
CSourcePosition::CanSeekBackward(__out LONG *pCanSeekBackward)
{
    CheckPointer(pCanSeekBackward,E_POINTER);
    *pCanSeekBackward = OATRUE;
    return S_OK;
}


// --- Implementation of CBasicAudio class ----------


CBasicAudio::CBasicAudio(__in_opt LPCTSTR pName,__in_opt LPUNKNOWN punk) :
    CUnknown(pName, punk)
{
}

// overriden to publicise our interfaces

STDMETHODIMP
CBasicAudio::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IBasicAudio) {
	return GetInterface( (IBasicAudio *) this, ppv);
    } else {
	return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


STDMETHODIMP
CBasicAudio::GetTypeInfoCount(__out UINT * pctinfo)
{
    return m_basedisp.GetTypeInfoCount(pctinfo);
}


STDMETHODIMP
CBasicAudio::GetTypeInfo(
  UINT itinfo,
  LCID lcid,
  __deref_out ITypeInfo ** pptinfo)
{
    return m_basedisp.GetTypeInfo(
		IID_IBasicAudio,
		itinfo,
		lcid,
		pptinfo);
}


STDMETHODIMP
CBasicAudio::GetIDsOfNames(
  REFIID riid,
  __in_ecount(cNames) LPOLESTR * rgszNames,
  UINT cNames,
  LCID lcid,
  __out_ecount(cNames) DISPID * rgdispid)
{
    return m_basedisp.GetIDsOfNames(
			IID_IBasicAudio,
			rgszNames,
			cNames,
			lcid,
			rgdispid);
}


STDMETHODIMP
CBasicAudio::Invoke(
  DISPID dispidMember,
  REFIID riid,
  LCID lcid,
  WORD wFlags,
  __in DISPPARAMS * pdispparams,
  __out_opt VARIANT * pvarResult,
  __out_opt EXCEPINFO * pexcepinfo,
  __out_opt UINT * puArgErr)
{
    // this parameter is a dead leftover from an earlier interface
    if (IID_NULL != riid) {
	return DISP_E_UNKNOWNINTERFACE;
    }

    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(0, lcid, &pti);

    if (FAILED(hr)) {
	return hr;
    }

    hr = pti->Invoke(
	    (IBasicAudio *)this,
	    dispidMember,
	    wFlags,
	    pdispparams,
	    pvarResult,
	    pexcepinfo,
	    puArgErr);

    pti->Release();
    return hr;
}


// --- IVideoWindow implementation ----------

CBaseVideoWindow::CBaseVideoWindow(__in_opt LPCTSTR pName,__in_opt LPUNKNOWN punk) :
    CUnknown(pName, punk)
{
}


// overriden to publicise our interfaces

STDMETHODIMP
CBaseVideoWindow::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IVideoWindow) {
	return GetInterface( (IVideoWindow *) this, ppv);
    } else {
	return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


STDMETHODIMP
CBaseVideoWindow::GetTypeInfoCount(__out UINT * pctinfo)
{
    return m_basedisp.GetTypeInfoCount(pctinfo);
}


STDMETHODIMP
CBaseVideoWindow::GetTypeInfo(
  UINT itinfo,
  LCID lcid,
  __deref_out ITypeInfo ** pptinfo)
{
    return m_basedisp.GetTypeInfo(
		IID_IVideoWindow,
		itinfo,
		lcid,
		pptinfo);
}


STDMETHODIMP
CBaseVideoWindow::GetIDsOfNames(
  REFIID riid,
  __in_ecount(cNames) LPOLESTR * rgszNames,
  UINT cNames,
  LCID lcid,
  __out_ecount(cNames) DISPID * rgdispid)
{
    return m_basedisp.GetIDsOfNames(
			IID_IVideoWindow,
			rgszNames,
			cNames,
			lcid,
			rgdispid);
}


STDMETHODIMP
CBaseVideoWindow::Invoke(
  DISPID dispidMember,
  REFIID riid,
  LCID lcid,
  WORD wFlags,
  __in DISPPARAMS * pdispparams,
  __out_opt VARIANT * pvarResult,
  __out_opt EXCEPINFO * pexcepinfo,
  __out_opt UINT * puArgErr)
{
    // this parameter is a dead leftover from an earlier interface
    if (IID_NULL != riid) {
	return DISP_E_UNKNOWNINTERFACE;
    }

    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(0, lcid, &pti);

    if (FAILED(hr)) {
	return hr;
    }

    hr = pti->Invoke(
	    (IVideoWindow *)this,
	    dispidMember,
	    wFlags,
	    pdispparams,
	    pvarResult,
	    pexcepinfo,
	    puArgErr);

    pti->Release();
    return hr;
}


// --- IBasicVideo implementation ----------


CBaseBasicVideo::CBaseBasicVideo(__in_opt LPCTSTR pName,__in_opt LPUNKNOWN punk) :
    CUnknown(pName, punk)
{
}


// overriden to publicise our interfaces

STDMETHODIMP
CBaseBasicVideo::NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IBasicVideo || riid == IID_IBasicVideo2) {
	return GetInterface( static_cast<IBasicVideo2 *>(this), ppv);
    } else {
	return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


STDMETHODIMP
CBaseBasicVideo::GetTypeInfoCount(__out UINT * pctinfo)
{
    return m_basedisp.GetTypeInfoCount(pctinfo);
}


STDMETHODIMP
CBaseBasicVideo::GetTypeInfo(
  UINT itinfo,
  LCID lcid,
  __deref_out ITypeInfo ** pptinfo)
{
    return m_basedisp.GetTypeInfo(
		IID_IBasicVideo,
		itinfo,
		lcid,
		pptinfo);
}


STDMETHODIMP
CBaseBasicVideo::GetIDsOfNames(
  REFIID riid,
  __in_ecount(cNames) LPOLESTR * rgszNames,
  UINT cNames,
  LCID lcid,
  __out_ecount(cNames) DISPID * rgdispid)
{
    return m_basedisp.GetIDsOfNames(
			IID_IBasicVideo,
			rgszNames,
			cNames,
			lcid,
			rgdispid);
}


STDMETHODIMP
CBaseBasicVideo::Invoke(
  DISPID dispidMember,
  REFIID riid,
  LCID lcid,
  WORD wFlags,
  __in DISPPARAMS * pdispparams,
  __out_opt VARIANT * pvarResult,
  __out_opt EXCEPINFO * pexcepinfo,
  __out_opt UINT * puArgErr)
{
    // this parameter is a dead leftover from an earlier interface
    if (IID_NULL != riid) {
	return DISP_E_UNKNOWNINTERFACE;
    }

    ITypeInfo * pti;
    HRESULT hr = GetTypeInfo(0, lcid, &pti);

    if (FAILED(hr)) {
	return hr;
    }

    hr = pti->Invoke(
	    (IBasicVideo *)this,
	    dispidMember,
	    wFlags,
	    pdispparams,
	    pvarResult,
	    pexcepinfo,
	    puArgErr);

    pti->Release();
    return hr;
}


// --- Implementation of Deferred Commands ----------


CDispParams::CDispParams(UINT nArgs, __in_ecount(nArgs) VARIANT* pArgs, __inout_opt HRESULT *phr)
{
   cNamedArgs = 0;
   rgdispidNamedArgs = NULL;
   cArgs = nArgs;

    if (cArgs) {
	rgvarg = new VARIANT[cArgs];
        if (NULL == rgvarg) {
            cArgs = 0;
            if (phr) {
                *phr = E_OUTOFMEMORY;
            }
            return;
        }

	for (UINT i = 0; i < cArgs; i++) {

            //  Why aren't we using VariantCopy?

	    VARIANT * pDest = &rgvarg[i];
	    VARIANT * pSrc = &pArgs[i];

	    pDest->vt = pSrc->vt;
	    switch(pDest->vt) {

	    case VT_I4:
		pDest->lVal = pSrc->lVal;
		break;

	    case VT_UI1:
		pDest->bVal = pSrc->bVal;
		break;

	    case VT_I2:
		pDest->iVal = pSrc->iVal;
		break;

	    case VT_R4:
		pDest->fltVal = pSrc->fltVal;
		break;

	    case VT_R8:
		pDest->dblVal = pSrc->dblVal;
		break;

	    case VT_BOOL:
		pDest->boolVal = pSrc->boolVal;
		break;

	    case VT_ERROR:
		pDest->scode = pSrc->scode;
		break;

	    case VT_CY:
		pDest->cyVal = pSrc->cyVal;
		break;

	    case VT_DATE:
		pDest->date = pSrc->date;
		break;

	    case VT_BSTR:
		if ((PVOID)pSrc->bstrVal == NULL) {
		    pDest->bstrVal = NULL;
		} else {

		    // a BSTR is a WORD followed by a UNICODE string.
		    // the pointer points just after the WORD

		    WORD len = * (WORD*) (pSrc->bstrVal - (sizeof(WORD) / sizeof(OLECHAR)));
		    OLECHAR* pch = new OLECHAR[len + (sizeof(WORD)/sizeof(OLECHAR))];
                    if (pch) {
        		WORD *pui = (WORD*)pch;
        		*pui = len;
         	        pDest->bstrVal = pch + (sizeof(WORD)/sizeof(OLECHAR));
         		CopyMemory(pDest->bstrVal, pSrc->bstrVal, len*sizeof(OLECHAR));
                    } else {
                        cArgs = i;
                        if (phr) {
                            *phr = E_OUTOFMEMORY;
                        }
                    }
		}
		break;

	    case VT_UNKNOWN:
		pDest->punkVal = pSrc->punkVal;
		pDest->punkVal->AddRef();
		break;

	    case VT_DISPATCH:
		pDest->pdispVal = pSrc->pdispVal;
		pDest->pdispVal->AddRef();
		break;

	    default:
		// a type we haven't got round to adding yet!
		ASSERT(0);
		break;
	    }
	}

    } else {
	rgvarg = NULL;
    }

}


CDispParams::~CDispParams()
{
    for (UINT i = 0; i < cArgs; i++) {
	switch(rgvarg[i].vt) {
        case VT_BSTR:
            //  Explicitly cast BSTR to PVOID to tell code scanning tools we really mean to test the pointer
	    if ((PVOID)rgvarg[i].bstrVal != NULL) {
		OLECHAR * pch = rgvarg[i].bstrVal - (sizeof(WORD)/sizeof(OLECHAR));
		delete pch;
	    }
	    break;

	case VT_UNKNOWN:
	    rgvarg[i].punkVal->Release();
	    break;

	case VT_DISPATCH:
	    rgvarg[i].pdispVal->Release();
	    break;
	}
    }
    delete[] rgvarg;
}


// lifetime is controlled by refcounts (see defer.h)

CDeferredCommand::CDeferredCommand(
    __inout CCmdQueue * pQ,
    __in_opt LPUNKNOWN	pUnk,
    __inout HRESULT *	phr,
    __in LPUNKNOWN	pUnkExecutor,
    REFTIME	time,
    __in GUID*	iid,
    long	dispidMethod,
    short	wFlags,
    long	nArgs,
    __in_ecount(nArgs) VARIANT*	pDispParams,
    __out VARIANT*	pvarResult,
    __out short*	puArgErr,
    BOOL	bStream
    ) :
	CUnknown(NAME("DeferredCommand"), pUnk),
	m_pQueue(pQ),
	m_pUnk(pUnkExecutor),
	m_iid(iid),
	m_dispidMethod(dispidMethod),
	m_wFlags(wFlags),
	m_DispParams(nArgs, pDispParams, phr),
	m_pvarResult(pvarResult),
	m_bStream(bStream),
	m_hrResult(E_ABORT)

{
    // convert REFTIME to REFERENCE_TIME
    COARefTime convertor(time);
    m_time = convertor;

    // no check of time validity - it's ok to queue a command that's
    // already late

    // check iid is supportable on pUnk by QueryInterface for it
    IUnknown * pInterface;
    HRESULT hr = m_pUnk->QueryInterface(GetIID(), (void**) &pInterface);
    if (FAILED(hr)) {
	*phr = hr;
	return;
    }
    pInterface->Release();


    // !!! check dispidMethod and param/return types using typelib
    ITypeInfo *pti;
    hr = m_Dispatch.GetTypeInfo(*iid, 0, 0, &pti);
    if (FAILED(hr)) {
	*phr = hr;
	return;
    }
    // !!! some sort of ITypeInfo validity check here
    pti->Release();


    // Fix up the dispid for put and get
    if (wFlags == DISPATCH_PROPERTYPUT) {
        m_DispParams.cNamedArgs = 1;
        m_DispId = DISPID_PROPERTYPUT;
        m_DispParams.rgdispidNamedArgs = &m_DispId;
    }

    // all checks ok - add to queue
    hr = pQ->Insert(this);
    if (FAILED(hr)) {
	*phr = hr;
    }
}


// refcounts are held by caller of InvokeAt... and by list. So if
// we get here, we can't be on the list

#if 0
CDeferredCommand::~CDeferredCommand()
{
    // this assert is invalid since if the queue is deleted while we are
    // still on the queue, we will have been removed by the queue and this
    // m_pQueue will not have been modified.
    // ASSERT(m_pQueue == NULL);

    // we don't hold a ref count on pUnk, which is the object that should
    // execute the command.
    // This is because there would otherwise be a circular refcount problem
    // since pUnk probably owns the CmdQueue object that has a refcount
    // on us.
    // The lifetime of pUnk is guaranteed by it being part of, or lifetime
    // controlled by, our parent object. As long as we are on the list, pUnk
    // must be valid. Once we are off the list, we do not use pUnk.

}
#endif


// overriden to publicise our interfaces

STDMETHODIMP
CDeferredCommand::NonDelegatingQueryInterface(REFIID riid, __out void **ppv)
{
    ValidateReadWritePtr(ppv,sizeof(PVOID));
    if (riid == IID_IDeferredCommand) {
	return GetInterface( (IDeferredCommand *) this, ppv);
    } else {
	return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}


// remove from q. this will reduce the refcount by one (since the q
// holds a count) but can't make us go away since he must have a
// refcount in order to call this method.

STDMETHODIMP
CDeferredCommand::Cancel()
{
    if (m_pQueue == NULL) {
	return VFW_E_ALREADY_CANCELLED;
    }

    HRESULT hr = m_pQueue->Remove(this);
    if (FAILED(hr)) {
	return hr;
    }

    m_pQueue = NULL;
    return S_OK;
}


STDMETHODIMP
CDeferredCommand::Confidence(__out LONG* pConfidence)
{
    return E_NOTIMPL;
}


STDMETHODIMP
CDeferredCommand::GetHResult(__out HRESULT * phrResult)
{
    CheckPointer(phrResult,E_POINTER);
    ValidateReadWritePtr(phrResult,sizeof(HRESULT));

    if (m_pQueue != NULL) {
	return E_ABORT;
    }
    *phrResult = m_hrResult;
    return S_OK;
}


// set the time to be a new time (checking that it is valid) and
// then requeue

STDMETHODIMP
CDeferredCommand::Postpone(REFTIME newtime)
{

    // check that this time is not past
    // convert REFTIME to REFERENCE_TIME
    COARefTime convertor(newtime);

    // check that the time has not passed
    if (m_pQueue->CheckTime(convertor, IsStreamTime())) {
	return VFW_E_TIME_ALREADY_PASSED;
    }

    // extract from list
    HRESULT hr = m_pQueue->Remove(this);
    if (FAILED(hr)) {
	return hr;
    }

    // change time
    m_time = convertor;

    // requeue
    hr = m_pQueue->Insert(this);

    return hr;
}


HRESULT
CDeferredCommand::Invoke()
{
    // check that we are still outstanding
    if (m_pQueue == NULL) {
	return VFW_E_ALREADY_CANCELLED;
    }

    // get the type info
    ITypeInfo* pti;
    HRESULT hr = m_Dispatch.GetTypeInfo(GetIID(), 0, 0, &pti);
    if (FAILED(hr)) {
	return hr;
    }

    // qi for the expected interface and then invoke it. Note that we have to
    // treat the returned interface as IUnknown since we don't know its type.
    IUnknown* pInterface;

    hr = m_pUnk->QueryInterface(GetIID(), (void**) &pInterface);
    if (FAILED(hr)) {
	pti->Release();
	return hr;
    }

    EXCEPINFO expinfo;
    UINT uArgErr;
    m_hrResult = pti->Invoke(
	pInterface,
	GetMethod(),
	GetFlags(),
	GetParams(),
	GetResult(),
	&expinfo,
	&uArgErr);

    // release the interface we QI'd for
    pInterface->Release();
    pti->Release();


    // remove from list whether or not successful
    // or we loop indefinitely
    hr = m_pQueue->Remove(this);
    m_pQueue = NULL;
    return hr;
}



// --- CCmdQueue methods ----------


CCmdQueue::CCmdQueue(__inout_opt HRESULT *phr) :
    m_listPresentation(NAME("Presentation time command list")),
    m_listStream(NAME("Stream time command list")),
    m_evDue(TRUE, phr),    // manual reset
    m_dwAdvise(0),
    m_pClock(NULL),
    m_bRunning(FALSE)
{
}


CCmdQueue::~CCmdQueue()
{
    // empty all our lists

    // we hold a refcount on each, so traverse and Release each
    // entry then RemoveAll to empty the list
    POSITION pos = m_listPresentation.GetHeadPosition();

    while(pos) {
	CDeferredCommand* pCmd = m_listPresentation.GetNext(pos);
	pCmd->Release();
    }
    m_listPresentation.RemoveAll();

    pos = m_listStream.GetHeadPosition();

    while(pos) {
	CDeferredCommand* pCmd = m_listStream.GetNext(pos);
	pCmd->Release();
    }
    m_listStream.RemoveAll();

    if (m_pClock) {
	if (m_dwAdvise) {
	    m_pClock->Unadvise(m_dwAdvise);
	    m_dwAdvise = 0;
	}
	m_pClock->Release();
    }
}


// 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.

HRESULT
CCmdQueue::New(
    __out CDeferredCommand **ppCmd,
    __in     LPUNKNOWN	pUnk,		// this object will execute command
    REFTIME	time,
    __in GUID*	iid,
    long	dispidMethod,
    short	wFlags,
    long	cArgs,
    __in_ecount(cArgs) VARIANT*	pDispParams,
    __out VARIANT*	pvarResult,
    __out short*	puArgErr,
    BOOL	bStream
)
{
    CAutoLock lock(&m_Lock);

    HRESULT hr = S_OK;
    *ppCmd = NULL;

    CDeferredCommand* pCmd;
    pCmd = new CDeferredCommand(
		    this,
		    NULL,	    // not aggregated
		    &hr,
		    pUnk,	    // this guy will execute
		    time,
		    iid,
		    dispidMethod,
		    wFlags,
		    cArgs,
		    pDispParams,
		    pvarResult,
		    puArgErr,
		    bStream);

    if (pCmd == NULL) {
	hr = E_OUTOFMEMORY;
    } else {
	*ppCmd = pCmd;
    }
    return hr;
}


HRESULT
CCmdQueue::Insert(__in CDeferredCommand* pCmd)
{
    CAutoLock lock(&m_Lock);

    // addref the item
    pCmd->AddRef();

    CGenericList<CDeferredCommand> * pList;
    if (pCmd->IsStreamTime()) {
	pList = &m_listStream;
    } else {
	pList = &m_listPresentation;
    }
    POSITION pos = pList->GetHeadPosition();

    // seek past all items that are before us
    while (pos &&
	(pList->GetValid(pos)->GetTime() <= pCmd->GetTime())) {

	pList->GetNext(pos);
    }

    // now at end of list or in front of items that come later
    if (!pos) {
	pList->AddTail(pCmd);
    } else {
	pList->AddBefore(pos, pCmd);
    }

    SetTimeAdvise();
    return S_OK;
}


HRESULT
CCmdQueue::Remove(__in CDeferredCommand* pCmd)
{
    CAutoLock lock(&m_Lock);
    HRESULT hr = S_OK;

    CGenericList<CDeferredCommand> * pList;
    if (pCmd->IsStreamTime()) {
	pList = &m_listStream;
    } else {
	pList = &m_listPresentation;
    }
    POSITION pos = pList->GetHeadPosition();

    // traverse the list
    while (pos && (pList->GetValid(pos) != pCmd)) {
	pList->GetNext(pos);
    }

    // did we drop off the end?
    if (!pos) {
	hr = VFW_E_NOT_FOUND;
    } else {

	// found it - now take off list
	pList->Remove(pos);

	// Insert did an AddRef, so release it
	pCmd->Release();

	// check that timer request is still for earliest time
	SetTimeAdvise();
    }
    return hr;
}


// set the clock used for timing

HRESULT
CCmdQueue::SetSyncSource(__in_opt IReferenceClock* pClock)
{
    CAutoLock lock(&m_Lock);

    // addref the new clock first in case they are the same
    if (pClock) {
	pClock->AddRef();
    }

    // kill any advise on the old clock
    if (m_pClock) {
	if (m_dwAdvise) {
	    m_pClock->Unadvise(m_dwAdvise);
	    m_dwAdvise = 0;
	}
	m_pClock->Release();
    }
    m_pClock = pClock;

    // set up a new advise
    SetTimeAdvise();
    return S_OK;
}


// set up a timer event with the reference clock

void
CCmdQueue::SetTimeAdvise(void)
{
    // make sure we have a clock to use
    if (!m_pClock) {
	return;
    }

    // reset the event whenever we are requesting a new signal
    m_evDue.Reset();

    // time 0 is earliest
    CRefTime current;

    // find the earliest presentation time
    POSITION pos = m_listPresentation.GetHeadPosition();
    if (pos != NULL) {
	current = m_listPresentation.GetValid(pos)->GetTime();
    }

    // if we're running, check the stream times too
    if (m_bRunning) {

	CRefTime t;
        pos = m_listStream.GetHeadPosition();
	if (NULL != pos) {
	    t = m_listStream.GetValid(pos)->GetTime();

	    // add on stream time offset to get presentation time
	    t += m_StreamTimeOffset;

	    // is this earlier?
	    if ((current == TimeZero) || (t < current)) {
		current = t;
	    }
	}
    }

    // need to change?
    if ((current > TimeZero) && (current != m_tCurrentAdvise)) {
	if (m_dwAdvise) {
	    m_pClock->Unadvise(m_dwAdvise);
	    // reset the event whenever we are requesting a new signal
	    m_evDue.Reset();
	}

	// ask for time advice - the first two params are either
	// stream time offset and stream time or
	// presentation time and 0. we always use the latter
	HRESULT hr = m_pClock->AdviseTime(
		    (REFERENCE_TIME)current,
		    TimeZero,
		    (HEVENT) HANDLE(m_evDue),
		    &m_dwAdvise);

	ASSERT(SUCCEEDED(hr));
	m_tCurrentAdvise = current;
    }
}


// switch to run mode. Streamtime to Presentation time mapping known.

HRESULT
CCmdQueue::Run(REFERENCE_TIME tStreamTimeOffset)
{
    CAutoLock lock(&m_Lock);

    m_StreamTimeOffset = tStreamTimeOffset;
    m_bRunning = TRUE;

    // ensure advise is accurate
    SetTimeAdvise();
    return S_OK;
}


// switch to Stopped or Paused mode. Time mapping not known.

HRESULT
CCmdQueue::EndRun()
{
    CAutoLock lock(&m_Lock);

    m_bRunning = FALSE;

    // check timer setting - stream times
    SetTimeAdvise();
    return S_OK;
}


// 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'd object

HRESULT
CCmdQueue::GetDueCommand(__out CDeferredCommand ** ppCmd, long msTimeout)
{
    // loop until we timeout or find a due command
    for (;;) {

	{
	    CAutoLock lock(&m_Lock);


	    // find the earliest command
	    CDeferredCommand * pCmd = NULL;

	    // check the presentation time and the
	    // stream time list to find the earliest

            POSITION pos = m_listPresentation.GetHeadPosition();

	    if (NULL != pos) {
		pCmd = m_listPresentation.GetValid(pos);
	    }

	    if (m_bRunning) {
		pos = m_listStream.GetHeadPosition();
                if (NULL != pos) {
                    CDeferredCommand* pStrm = m_listStream.GetValid(pos);

                    CRefTime t = pStrm->GetTime() + m_StreamTimeOffset;
                    if (!pCmd || (t < pCmd->GetTime())) {
                        pCmd = pStrm;
                    }
                }
            }

	    //	if we have found one, is it due?
	    if (pCmd) {
		if (CheckTime(pCmd->GetTime(), pCmd->IsStreamTime())) {

		    // yes it's due - addref it
		    pCmd->AddRef();
		    *ppCmd = pCmd;
		    return S_OK;
		}
	    }
	}

	// block until the advise is signalled
	if (WaitForSingleObject(m_evDue, msTimeout) != WAIT_OBJECT_0) {
	    return E_ABORT;
	}
    }
}


// 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 E_ABORT if there are no
// commands due yet.
//
// returns an AddRef'd object

HRESULT
CCmdQueue::GetCommandDueFor(REFERENCE_TIME rtStream, __out CDeferredCommand**ppCmd)
{
    CAutoLock lock(&m_Lock);

    CRefTime tStream(rtStream);

    // find the earliest stream and presentation time commands
    CDeferredCommand* pStream = NULL;
    POSITION pos = m_listStream.GetHeadPosition();
    if (NULL != pos) {
	pStream = m_listStream.GetValid(pos);
    }
    CDeferredCommand* pPresent = NULL;
    pos = m_listPresentation.GetHeadPosition();
    if (NULL != pos) {
	pPresent = m_listPresentation.GetValid(pos);
    }

    // is there a presentation time that has passed already
    if (pPresent && CheckTime(pPresent->GetTime(), FALSE)) {
	pPresent->AddRef();
	*ppCmd = pPresent;
	return S_OK;
    }

    // is there a stream time command due before this stream time
    if (pStream && (pStream->GetTime() <= tStream)) {
	pStream->AddRef();
	*ppCmd = pStream;
	return S_OK;
    }

    // if we are running, we can map presentation times to
    // stream time. In this case, is there a presentation time command
    // that will be due before this stream time is presented?
    if (m_bRunning && pPresent) {

	// this stream time will appear at...
	tStream += m_StreamTimeOffset;

	// due before that?
	if (pPresent->GetTime() <= tStream) {
	    *ppCmd = pPresent;
	    return S_OK;
	}
    }

    // no commands due yet
    return VFW_E_NOT_FOUND;
}

#endif /* PJMEDIA_VIDEO_DEV_HAS_DSHOW */
