locked
HD playback with a custom TimeSource/Clock RRS feed

  • Question

  • I want to playback videos with Microsoft Media foundation with a custom clock.
     
    I am starting with the MFPlayer.zip example from msdn.
     
    The idea is to replace the clock with one that is driven by UDP packets. The videos will be silent (the audio turned off, preferably not even decoded). 
     
    I have stubbed out what I think is a clock replacement, but what I can't figure out is why my calls to GetCorrellatedTime seem to only occur at the start of playback. I expected GetCorrellatedTime to be called by the playback engine repeatedly.... but that's just not happening. So am I missing something here?   GetCorrellatedTime gets called exactly twice, then the video plays back normal speed with no return calls to my custom timesource.  

    Here's the cpp code for my timesource. Note that it doesn't do much of anything yet... it is just a stub.
     
    Any Ideas? Thanks in advance


    #include "MFPlayer.h"
    #include "TimeSource.h"
    
    
    HRESULT STDMETHODCALLTYPE UDPClock::GetClockCharacteristics( /* [out] */ __RPC__out DWORD *pdwCharacteristics)
    {
    	*pdwCharacteristics = MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ;
    	return S_OK;
    }
            
    HRESULT STDMETHODCALLTYPE UDPClock::GetCorrelatedTime( /* [in] */ DWORD dwReserved,/* [out] */ __RPC__out LONGLONG *pllClockTime,/* [out] */ __RPC__out MFTIME *phnsSystemTime)
    {
    	m_Time = GetTickCount64() * 10000000;
    	m_System_Time = GetTickCount64() * 10000000;
    
    	*pllClockTime = m_Time;
    	*phnsSystemTime = m_System_Time;
    	return S_OK;
    }
            
    HRESULT STDMETHODCALLTYPE UDPClock::GetContinuityKey( /* [out] */ __RPC__out DWORD *pdwContinuityKey)
    {
    	*pdwContinuityKey = 0;
    	return S_OK;
    }
            
    HRESULT STDMETHODCALLTYPE UDPClock::GetState( /* [in] */ DWORD dwReserved,/* [out] */ __RPC__out MFCLOCK_STATE *peClockState)
    {
    	*peClockState = MFCLOCK_STATE_RUNNING;
    	return S_OK;
    }
            
    HRESULT STDMETHODCALLTYPE UDPClock::GetProperties( /* [out] */ __RPC__out MFCLOCK_PROPERTIES *pClockProperties)
    {
    	pClockProperties->qwCorrelationRate = 100000;
    	pClockProperties->guidClockId = GUID_NULL;
    	pClockProperties->qwClockFrequency = MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ;
    	pClockProperties->dwClockTolerance = MFCLOCK_TOLERANCE_UNKNOWN;
    	pClockProperties->dwClockJitter = 1;//10000;
    	pClockProperties->dwClockFlags = MFCLOCK_RELATIONAL_FLAG_JITTER_NEVER_AHEAD;
    
    	return S_OK;
    }
    
    HRESULT STDMETHODCALLTYPE UDPClock::GetUnderlyingClock(/* [out] */ __RPC__deref_out_opt IMFClock **ppClock)
    {
    	*ppClock = this;
    	return S_OK;
    	//return this;
    	//return this->QueryInterface<IMFClock>(ppClock);
    }
    
    
    HRESULT UDPClock::QueryInterface (REFIID   riid, LPVOID * ppvObj)
    {
        // Always set out parameter to NULL, validating it first.
        if (!ppvObj)
            return E_INVALIDARG;
        *ppvObj = NULL;
    	if (riid == IID_IUnknown || riid == IID_IMFClock || riid == IID_IMFPresentationClock)
    		return NOERROR;
        
        return E_NOINTERFACE;
    
    }
    //--------------------------------------------------------------------------------------------------------------------------------
    ULONG UDPClock::AddRef()
    {
        InterlockedIncrement(&m_cRef);
        return m_cRef;
    }
    //--------------------------------------------------------------------------------------------------------------------------------
    ULONG UDPClock::Release()
    {
        // Decrement the object's internal counter.
        ULONG ulRefCount = InterlockedDecrement(&m_cRef);
        if (0 == m_cRef)
        {
            delete this;
        }
        return ulRefCount;
    }
    //--------------------------------------------------------------------------------------------------------------------------------
    HRESULT STDMETHODCALLTYPE UDPClock::OnClockStart( /* [in] */ MFTIME hnsSystemTime,/* [in] */ LONGLONG llClockStartOffset)
    {
    	m_StartTime = hnsSystemTime;
    	m_StartOffset = llClockStartOffset;
    	return S_OK;
    }
    //--------------------------------------------------------------------------------------------------------------------------------
    HRESULT STDMETHODCALLTYPE UDPClock::OnClockStop( /* [in] */ MFTIME hnsSystemTime)
    {
    	return S_OK;
    }
    //--------------------------------------------------------------------------------------------------------------------------------
    HRESULT STDMETHODCALLTYPE UDPClock::OnClockPause( /* [in] */ MFTIME hnsSystemTime)
    {
    	return S_OK;
    }
    //--------------------------------------------------------------------------------------------------------------------------------
    HRESULT STDMETHODCALLTYPE UDPClock::OnClockRestart( /* [in] */ MFTIME hnsSystemTime)
    {
    	return S_OK;
    }
    //--------------------------------------------------------------------------------------------------------------------------------
    HRESULT STDMETHODCALLTYPE UDPClock::OnClockSetRate( /* [in] */ MFTIME hnsSystemTime,/* [in] */ float flRate)
    {
    	return S_OK;
    }
    //--------------------------------------------------------------------------------------------------------------------------------
    
    
    

    Thursday, December 20, 2012 9:19 PM