⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vidrend.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					      ulContentVersion)))    {	UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulContentVersion);	UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulContentVersion);	ULONG32 ulThisMajorVersion = 0;	ULONG32 ulThisMinorVersion = 0;	GetContentVersion(ulThisMajorVersion, ulThisMinorVersion);	if((ulMajorVersion > ulThisMajorVersion) ||	   ((ulMinorVersion > ulThisMinorVersion) &&	    (ulMajorVersion == ulMajorVersion)))	{	    bVersionOK = FALSE;	}    }    if(!bVersionOK)    {        AddToAutoUpgradeCollection(GetUpgradeMimeType(), m_pContext);	pnr = HXR_FAIL;    }    return pnr;}///////////////////////////////////////////////////////////////////////////  Method://		IHXRenderer::OnPacket//  Purpose://		Called by client engine when a packet for this renderer is//		due.//STDMETHODIMP CVideoRenderer::OnPacket(IHXPacket* pPacket, LONG32 lTimeOffset){    m_lTimeLineOffset = lTimeOffset;#ifdef ENABLE_INPUT_TRACE    if (ulInputTraceIdx < MAX_INPUT_TRACE_ENTRIES)    {	inputTraceArray[ulInputTraceIdx++] =	    ComputeTimeAhead(pPacket->GetTime(), 0);    }#endif	// ENABLE_INPUT_TRACE    if (m_bSchedulerStartRequested)    {	StartSchedulers();    }    BOOL bQueueRet = m_pVideoFormat->Enqueue(pPacket);    if(bQueueRet == FALSE && m_pVideoFormat->GetLastError() == HXR_OUTOFMEMORY)    {        return HXR_OUTOFMEMORY;    }    // try to decode a frame    if (m_PlayState == Playing)    {	if (!IsDecoderRunning() || NULL == m_pDecoderPump)	{	    BOOL bDecRet = m_pVideoFormat->DecodeFrame();            if( bDecRet == FALSE && m_pVideoFormat->GetLastError() == HXR_OUTOFMEMORY )            {                return HXR_OUTOFMEMORY;            }	}	else	{	    m_pDecoderPump->Signal();	}    }    else    {	if (!m_bBaseTimeSet)	{	    m_pMutex->Lock();	    if (m_PlayState != Playing)	    {		m_ulBaseTime = pPacket->GetTime();	    }	    m_pMutex->Unlock();	    m_bBaseTimeSet = TRUE;	}	// If we are seeking, this is a pre-seek packet and there is	// no need to decode it	if (m_PlayState != Seeking)	{	    if (!IsDecoderRunning() || NULL == m_pDecoderPump)	    {		m_pVideoFormat->DecodeFrame();	    }	    else	    {		m_pDecoderPump->Signal();	    }	    if (m_PlayState == Buffering)	    {		if (IsBufferingComplete(pPacket))		{		    RequestBufferingEnd();		}	    }	}    }    return HXR_OK;}///////////////////////////////////////////////////////////////////////////  Method://		IHXRenderer::OnTimeSync//  Purpose://		Called by client engine to inform the renderer of the current//		time relative to the streams synchronized time-line. The//		renderer should use this time value to update its display or//		render it's stream data accordingly.//STDMETHODIMP CVideoRenderer::OnTimeSync(ULONG32 ulTime){    ULONG32 ulStreamBaseTime = HX_GET_BETTERTICKCOUNT();    ULONG32 ulBaseTime = ulTime;    BOOL bGoodSample = TRUE;    if (m_bSchedulerStartRequested)    {	StartSchedulers();    }#ifdef HELIX_FEATURE_STATS    if (((ULONG32) (ulStreamBaseTime - m_pVideoStats->GetLastSyncTime())) >=	VIDEO_STAT_INTERVAL)    {	m_pVideoStats->SyncStats(ulStreamBaseTime);    }#endif /* HELIX_FEATURE_STATS */#ifdef ENABLE_SYNC_TRACE    ULONG32 ulOrigStreamBaseTime = ulStreamBaseTime;#endif // ENABLE_SYNC_TRACE#ifdef SYNC_SMOOTHING_OLD_SCHEME    LONG32 lNewSyncDelta = (LONG32) (ulStreamBaseTime - m_lTrendSyncDelta - ulTime);    m_lTrendSyncDelta += lNewSyncDelta / ((LONG32) (m_ulSyncSmoothingDepth + 1));    ulStreamBaseTime = ulTime + m_lTrendSyncDelta;    if (m_ulSyncSmoothingDepth < m_ulSyncGoalSmoothingDepth)    {	m_ulSyncSmoothingDepth++;    }#endif	// SYNC_SMOOTHING_OLD_SCHEME#ifdef SYNC_PRE_SMOOTHING    if (m_ulSyncSmoothingDepth > 0)    {	LONG32 lStreamBaseDelta = ((LONG32) (ulStreamBaseTime - m_ulStreamBaseTime));	ULONG32 ulBaseDelta = ulBaseTime - m_ulBaseTime;	BOOL bSkipSmoothing = FALSE;	bGoodSample = ((lStreamBaseDelta <= 0) ||		       (((ULONG32) lStreamBaseDelta) <=		        (ulBaseDelta + (ulBaseDelta >> AUDIO_SKEW_POWER))) ||		       (bSkipSmoothing = ((m_ulBadSeqSampleCount++) > m_ulMaxBadSeqSamples)));	if (bSkipSmoothing)	{	    m_ulSyncSmoothingDepth = 0;	    m_fTrendSyncDelta = 0.0;	}    }#endif	// SYNC_PRE_SMOOTHING    if (bGoodSample)    {#ifdef SYNC_SMOOTHING	double fNewSyncDelta = (((double) ((ULONG32) (ulStreamBaseTime - ulTime))) -			       m_fTrendSyncDelta);	// If we have a m_fTrendSyncDelta, make sure we consider	// m_fTrendSyncDelta wrap-around in relation to fNewSyncDelta	if (m_ulSyncSmoothingDepth > 0)	{	    if (fNewSyncDelta > MAX_LONG32_AS_DOUBLE)	    {		fNewSyncDelta = MAX_ULONG32_AS_DOUBLE - fNewSyncDelta;	    }	    else if (fNewSyncDelta < MIN_LONG32_AS_DOUBLE)	    {		fNewSyncDelta += MAX_ULONG32_AS_DOUBLE;	    }	}	if (fNewSyncDelta < 0.0)	{	    // We are trying to speed up: use speed up smoothing criteria	    m_fTrendSyncDelta += (fNewSyncDelta /				  ((m_ulSyncSmoothingDepth >= m_ulSpeedupGoalSmoothingDepth) ?				   m_ulSpeedupGoalSmoothingDepth + 1 : m_ulSyncSmoothingDepth + 1));	}	else	{	    m_fTrendSyncDelta += fNewSyncDelta / (m_ulSyncSmoothingDepth + 1);	}	if (m_fTrendSyncDelta > MAX_ULONG32_AS_DOUBLE)	{	    m_fTrendSyncDelta -= MAX_ULONG32_AS_DOUBLE;	}	else if (m_fTrendSyncDelta < 0)	{	     m_fTrendSyncDelta += MAX_ULONG32_AS_DOUBLE;	}	ulStreamBaseTime = ulTime + ((ULONG32) (m_fTrendSyncDelta));	if (m_ulSyncSmoothingDepth < m_ulSyncGoalSmoothingDepth)	{	    m_ulSyncSmoothingDepth++;	}#endif	// SYNC_SMOOTHING	m_ulGoodSeqSampleCount++;	m_ulStreamBaseTime = ulStreamBaseTime;	m_ulBaseTime = ulBaseTime;	m_ulTimeNormalizationOffset = m_ulStreamBaseTime -				      m_ulBaseTime -				      m_lTimeLineOffset;	if (m_ulGoodSeqSampleCount >= MIN_GOOD_PERSISTENCE_COUNT)	{	    m_ulBadSeqSampleCount = 0;	}    }    else    {	// This is a bad sample	if (m_ulBadSeqSampleCount >= MIN_BAD_PERSISTENCE_COUNT)	{	    m_ulGoodSeqSampleCount = 0;	}    }#ifdef ENABLE_SYNC_TRACE    if (ulSyncTraceIdx < MAX_SYNC_TRACE_ENTRIES)    {	syncTraceArray[ulSyncTraceIdx][0] = m_ulBaseTime;	syncTraceArray[ulSyncTraceIdx][1] = m_ulStreamBaseTime;	syncTraceArray[ulSyncTraceIdx++][2] = ulOrigStreamBaseTime;    }#endif	// ENABLE_SYNC_TRACE    if (m_PlayState == Playing)    {	if (!IsDecoderRunning())	{	    m_pVideoFormat->DecodeFrame();	}	if (m_bBufferingNeeded)	{	    m_pMutex->Lock();	    if (m_PlayState == Playing)	    {		BeginBuffering();	    }	    m_pMutex->Unlock();	}    }    else if ((m_PlayState == PlayStarting) ||	     (m_PlayState == Buffering))    {	m_pMutex->Lock();	m_bBaseTimeSet = TRUE;	// Reset the offset to avoid race condition	// with m_ulTimeNormalizationOffset setting in OnPacket()	if (bGoodSample)	{	    m_ulTimeNormalizationOffset = m_ulStreamBaseTime -					  m_ulBaseTime -					  m_lTimeLineOffset;	}	if (m_PlayState == Buffering)	{	    EndBuffering();	    m_PlayState = PlayStarting;	}	if (m_PlayState == PlayStarting)	{	    m_PlayState = Playing;	    BltIfNeeded();	    StartSchedulers();	    if (m_pBltrPump)	    {		m_pBltrPump->Signal();	    }	}	m_pMutex->Unlock();    }    return HXR_OK;}HX_RESULT CVideoRenderer::StartSchedulers(void){    HX_RESULT retVal = HXR_OK;#ifdef HELIX_FEATURE_VIDREND_UNTIMED_DECODE    // When running the decoder as fast as possible, we dont want to start the scheduler, so short    // circuit this code. Additionally, calls such as BltIfNeeded() and ScheduleCallback() (which    // may still be called) make assumptions based on the state of our interactions with the    // scheduler, so we satisfy them by setting a pending handle representing a nonexistant callback.    if( m_bUntimedRendering )    {	m_hPendingHandle = 1;	return HXR_OK;    }#endif /* HELIX_FEATURE_VIDREND_UNTIMED_DECODE */    m_bSchedulerStartRequested = FALSE;    DisplayMutex_Lock();    if (ShouldKickStartScheduler())    {	m_bBufferingNeeded = FALSE;	ScheduleCallback(0);    }    if (SUCCEEDED(retVal) && (m_pDecoderPump == NULL))    {	CVideoPaceMaker* pVideoPaceMaker;	retVal = HXR_OUTOFMEMORY;	pVideoPaceMaker = new CVideoPaceMaker;	if (pVideoPaceMaker)	{	    retVal = pVideoPaceMaker->QueryInterface(		IID_IHXPaceMaker,		(void**) &m_pDecoderPump);	    if (SUCCEEDED(retVal))	    {		pVideoPaceMaker = NULL;		m_pDecoderPump->Start(this,		    GetDecodePriority(),		    DECODER_INTERVAL,		    m_ulDecoderPacemakerId);	    }	}	HX_DELETE(pVideoPaceMaker);    }    if (SUCCEEDED(retVal) && (m_pBltrPump == NULL) && m_bTryVideoSurface2)    {	CVideoPaceMaker* pVideoPaceMaker;	retVal = HXR_OUTOFMEMORY;	pVideoPaceMaker = new CVideoPaceMaker;	if (pVideoPaceMaker)	{	    retVal = pVideoPaceMaker->QueryInterface(		IID_IHXPaceMaker,		(void**) &m_pBltrPump);	    if (SUCCEEDED(retVal))	    {		pVideoPaceMaker = NULL;		m_pBltrPump->Start(this,		    DFLT_PRESENT_PRIORITY,		    BLTR_INTERVAL,		    m_ulBltrPacemakerId);	    }	}	HX_DELETE(pVideoPaceMaker);    }    DisplayMutex_Unlock();    return retVal;}///////////////////////////////////////////////////////////////////////////  Method://	IHXRenderer::OnPreSeek//  Purpose://	Called by client engine to inform the renderer that a seek is//	about to occur. The render is informed the last time for the//	stream's time line before the seek, as well as the first new//	time for the stream's time line after the seek will be completed.//STDMETHODIMP CVideoRenderer::OnPreSeek(ULONG32 ulOldTime, ULONG32 ulNewTime){    // Change state to stop Blts    m_pMutex->Lock();    m_PlayState = Seeking;    m_pMutex->Unlock();    // Suspend the Decoder pump    if (m_pDecoderPump)    {	m_pDecoderPump->Suspend(TRUE);	m_pDecoderPump->Signal();	m_pDecoderPump->WaitForSuspend();    }    // Wait for Blt in progress to complete and reset    // packet queues    DisplayMutex_Lock();    m_pVideoFormat->SetStartTime(ulNewTime);    m_pVideoFormat->Reset();#if defined(HELIX_FEATURE_STATS)    m_pVideoStats->ResetSequence();#endif /* HELIX_FEATURE_STATS */    m_bFirstSurfaceUpdate = TRUE;    m_bFirstFrame = TRUE;    m_bBaseTimeSet = FALSE;    DisplayMutex_Unlock();    return HXR_OK;}///////////////////////////////////////////////////////////////////////////  Method://	IHXRenderer::OnPostSeek//  Purpose://	Called by client engine to inform the renderer that a seek has//	just occured. The render is informed the last time for the//	stream's time line before the seek, as well as the first new//	time for the stream's time line after the seek.//STDMETHODIMP CVideoRenderer::OnPostSeek(ULONG32 ulOldTime, ULONG32 ulNewTime){    DisplayMutex_Lock();    // clean up the packet lists    m_pVideoFormat->SetStartTime(ulNewTime);    m_pVideoFormat->Reset();#if defined(HELIX_FEATURE_STATS)    m_pVideoStats->ResetSequence();#endif /* HELIX_FEATURE_STATS */    m_bFirstSurfaceUpdate = TRUE;    m_bFirstFrame = TRUE;    m_ulBaseTime = ulNewTime;    m_bBaseTimeSet = TRUE;    m_bVS2BufferUnavailableOnLastBlt = FALSE;    if (m_pDecoderPump)    {	m_pDecoderPump->Suspend(FALSE);	m_pDecoderPump->Signal();    }    if (m_bUseVideoSurface2 && m_pMISUSSite)    {	FlushVideoSurface2(m_pMISUSSite);    }    DisplayMutex_Unlock();    // PostSeek signals the proper packets are to start arriving    m_pMutex->Lock();    m_PlayState = PlayStarting;    m_pMutex->Unlock();    return HXR_OK;}///////////////////////////////////////////////////////////////////////////  Method://	IHXRenderer::OnPause//  Purpose://	Called by client engine to inform the renderer that a pause has//	just occured. The render is informed the last time for the//	stream's time line before the pause.//STDMETHODIMP CVideoRenderer::OnPause(ULONG32 ulTime){    m_pMutex->Lock();    m_PlayState = Paused;    m_pMutex->Unlock();    return HXR_OK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -