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

📄 timeline.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

void Timeline::Done(void)
{
    HX_RELEASE(m_pScheduler);
#if defined (_MACINTOSH)
#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
    BOOL bBetterWaitForCallbacks = FALSE;
    if ( m_uiDeferredTaskDepth > 0 )
    {
	char tmpStr[255]; /* Flawfinder: ignore */
	sprintf(tmpStr, "m_uiDeferredTaskDepth = %u;g", m_uiDeferredTaskDepth); /* Flawfinder: ignore */
//	DebugStr(c2pstr(tmpStr));
// don't spoil the timing by hitting MacsBug
	bBetterWaitForCallbacks = TRUE;
    }
#endif
    m_bIsQuitting = TRUE;
    // sit-n-spin awaiting interrupts to finish.
    for ( int i = 0; i < 50; i++ )
    {
	unsigned long dummyTix;
	Delay( 6, &dummyTix );
	if ( !m_bAnyCallbackPending )
	{
	    i = 50;
	}
    }
#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
    if ( bBetterWaitForCallbacks )
    {
	if ( m_uiDeferredTaskDepth > 0 )
	{
	    DebugStr( "\pOops! After several seconds the deferred task didn't fire off;g" );
	}
	else
	{
	    DebugStr( "\pNice... the deferred task fired off and we're good to go;g" );
	}
    }
#endif
    m_bIsQuitting = FALSE;
#endif
}

HX_RESULT Timeline::Resume(void)
{
#if defined(HELIX_CONFIG_NOSTATICS)
    TimelineMapType& m_zTimerMap =
	GlobalTimelineMapType::Get(&Timeline::m_zTimerMap);
#endif
	
    m_bPaused = FALSE;

    if (m_bIsTimerPending)
    {
	return HXR_OK;  
    }
    
    m_ulLastCallbackTime    = HX_GET_TICKCOUNT();

    // Set a timer
#if defined(_WINDOWS) || defined(_SYMBIAN)

    m_uiTimerID = HXAsyncTimer::SetTimer(m_ulGranularity, (TIMERPROC)NonMMTimerProc);
    if( m_bTimerFixup )
        m_uiTimerIDFixup = HXAsyncTimer::SetTimer(m_ulGranularity,
                                                   (TIMERPROC)NonMMTimerProc);
    
//     m_uiTimerID = SetTimer( NULL, NULL, (UINT) m_ulGranularity, 
// 			    (TIMERPROC) NonMMTimerProc );
//     if (m_bTimerFixup)
// 	m_uiTimerIDFixup = SetTimer( NULL, NULL, (UINT) m_ulGranularity, 
// 			    (TIMERPROC) NonMMTimerProc );
#elif defined(_MACINTOSH)

    if (m_bUseDeferredTasks)
    {
	OSErr	e = noErr;

	if (CLOCKSET(m_tmInfo.tmTask))
	{
	    ::RmvTime((QElemPtr) &m_tmInfo);
	    
	    m_bAnyCallbackPending = 0;
	}

	m_tmInfo.tmTask.tmAddr = m_uppTask;
	m_tmInfo.tmRefCon = (long) this;
	m_tmInfo.tmTask.tmWakeUp = 0L;
	m_tmInfo.tmTask.tmReserved = 0L;

	::InsTime((QElemPtr) &m_tmInfo);
	::PrimeTime((QElemPtr) &m_tmInfo, m_ulGranularity);	
	
	m_bAnyCallbackPending = 1;

    }
#endif

    // add this timer to the static timer map
#if defined(_WINDOWS) || defined(_SYMBIAN)
    TimerObjects*   pTimerObject    = new TimerObjects;
    if (!pTimerObject)
    {
	if (!m_bTimerFixup)
	    // This is the "old code".  Execute it just as before the
	    // timerfixup functionality was introduced.
            HXAsyncTimer::KillTimer(m_uiTimerID);
	else 
	{
	    if (m_uiTimerID)
		HXAsyncTimer::KillTimer(m_uiTimerID);
	    if (m_uiTimerIDFixup)
	        HXAsyncTimer::KillTimer(m_uiTimerIDFixup);
	}
	return HXR_OUTOFMEMORY;
    }

    pTimerObject->m_pTimeline	    = this;
    pTimerObject->m_uiTimer	    = m_uiTimerID;

    m_zTimerMap.SetAt((LONG32) m_uiTimerID, (void*) pTimerObject);
    if (m_bTimerFixup)
        m_zTimerMap.SetAt((LONG32) m_uiTimerIDFixup, (void*) pTimerObject);

#elif defined(_UNIX) || defined(_MACINTOSH) || defined(__TCS__) || defined(_OPENWAVE)
    m_zTimerMap.SetAt(this, this);
#endif

#if defined(_MACINTOSH) && defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
    if ( m_bIsTimerPending )
    {
	DebugStr( "\pTimeLine::Resume -- m_bIsTimerPending already true!;g" );
    }
#endif
    m_bIsTimerPending	= TRUE;

    return HXR_OK;
}

HX_RESULT
Timeline::Seek(ULONG32 ulSeekTime)
{
    if (!m_bPaused)
    {
	Pause();
	Resume();
    }

    return HXR_OK;
}

HX_RESULT
Timeline::SetStartTime(ULONG32 ulTime)
{
    return HXR_OK;
}

HX_RESULT
Timeline::SetGranularity(ULONG32 ulNumMillisecs)
{
    m_ulGranularity = ulNumMillisecs;
    return HXR_OK;
}

HX_RESULT
Timeline::OnTimeSync(BOOL bAtInterrupt)
{

#ifdef _MACINTOSH
    if ((InterlockedIncrement(&gTIMELINE_MUTEX) > 1) && bAtInterrupt)
    {
        InterlockedDecrement(&gTIMELINE_MUTEX);
	return HXR_OK;
    }
#endif

//{FILE* f1 = ::fopen("d:\\temp\\timeline.txt", "a+"); ::fprintf(f1, "%p: %lu \n", this, HX_GET_TICKCOUNT());::fclose(f1);}

    if (!m_bPaused)
    {
        if (m_pScheduler)
	{
	    HXScheduler* pScheduler = m_pScheduler;
	    pScheduler->AddRef();
	    pScheduler->OnTimeSync(bAtInterrupt);
	    pScheduler->Release();
	}
    }

#ifdef _MACINTOSH
    InterlockedDecrement(&gTIMELINE_MUTEX);
#endif

    return HXR_OK;
}


/*
 *  ********* WINDOWS ONLY *****************
 */
#if defined(_WINDOWS) || defined(_SYMBIAN)
/*
 *  This is a Windows Timer callback proc
 */
void CALLBACK Timeline::NonMMTimerProc( 
    void*   hwnd,	// handle of window for timer messages 
    UINT32  uMsg,	// WM_TIMER message
    UINT32  idTimer,	// timer identifier
    ULONG32 dwTime 	// current system time
)
{
#if defined(HELIX_CONFIG_NOSTATICS)
    TimelineMapType& m_zTimerMap =
	GlobalTimelineMapType::Get(&Timeline::m_zTimerMap);
#endif
	
    TimerObjects*   pTimerObject = NULL;

    if (m_zTimerMap.Lookup((LONG32) idTimer, (void*&) pTimerObject))
    {
        // MUST call this BEFORE OnTimeSync, because OnTimeSync could
        // delete the object
	KillTimerFixup(idTimer, pTimerObject);
        HX_ASSERT( pTimerObject);
        HX_ASSERT( pTimerObject->m_pTimeline );
	pTimerObject->m_pTimeline->OnTimeSync();
    }
    return;
}

void Timeline::KillTimerFixup(UINT  idTimer, struct TimerObjects*  pTimerObject)
{
#if defined(HELIX_CONFIG_NOSTATICS)
    TimelineMapType& m_zTimerMap =
	GlobalTimelineMapType::Get(&Timeline::m_zTimerMap);
#endif

    if (pTimerObject->m_pTimeline->m_bTimerFixup == FALSE)
	return;

    if (pTimerObject->m_pTimeline->m_uiTimerIDFixup == 0)
	return;

    if (pTimerObject->m_pTimeline->m_uiTimerID == 0)
	return;

    if (pTimerObject->m_pTimeline->m_uiTimerID == idTimer)
    {
	HXAsyncTimer::KillTimer(pTimerObject->m_pTimeline->m_uiTimerIDFixup);
	m_zTimerMap.RemoveKey((LONG32) pTimerObject->m_pTimeline->m_uiTimerIDFixup);
	pTimerObject->m_pTimeline->m_uiTimerIDFixup = 0;
    }
    else if (pTimerObject->m_pTimeline->m_uiTimerIDFixup == idTimer)
    {
	HXAsyncTimer::KillTimer(pTimerObject->m_pTimeline->m_uiTimerID);
	m_zTimerMap.RemoveKey((LONG32) pTimerObject->m_pTimeline->m_uiTimerID);
	pTimerObject->m_pTimeline->m_uiTimerID = 0;
    }

    return;
}
#endif

/*
 *  ********* MAC ONLY *****************
 */
#ifdef _MACINTOSH
/*
 *  This is the Mac Timer callback proc (deferred task)
 */
pascal void 
Timeline::MacTimerProc(TMInfoPtr task)
{
    HXMM_INTERRUPTON();

    /*
     *	Setup and then install a deferred task 
     */
    if (task != NULL && task->tmRefCon != NULL)
    {
	Timeline* pTheTimeline = (Timeline*)task->tmRefCon;
#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
	// m_bIsTimerPending better be true right now
	if ( !pTheTimeline->m_bIsTimerPending )
	{
	    DebugStr( "\pMacTimerProc -- m_bIsTimerPending is FALSE!;g" );
	}
#endif
	if (pTheTimeline->m_DeferredTaskStruct.dtAddr != NULL)
	{
#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
	    if ( pTheTimeline->m_uiDeferredTaskDepth > 0 )
	    {
		char tmpStr[255]; /* Flawfinder: ignore */
		sprintf(tmpStr, "m_uiDeferredTaskDepth = %u;g", pTheTimeline->m_uiDeferredTaskDepth); /* Flawfinder: ignore */
		DebugStr(c2pstr(tmpStr));
	    }
#endif
	    if ( pTheTimeline->m_bIsQuitting )
	    {
		// short-circuit and don't install deferred task
		pTheTimeline->m_bAnyCallbackPending = 0;
#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
	    	DebugStr( "\pIt's quitting so we don't install deferred task;g" );
#endif
	    }
	    else
	    {
		// now that we're running on OS X, call the "deferred task" immediately.
		// Using a deferred thread is an artifact of OS 9: using deferred time
		// because it's not quite as nasty as hard interrupt time, plus there were
		// things that assumed they could only be interrupted "once". Those should
		// now all be THREAD safe (i.e. OS X) and calling deferred time oughtn't
		// be necessary.
		Timeline::DeferredTaskProc((long)pTheTimeline);
	    }
	}
    }
    
    HXMM_INTERRUPTOFF();
}

pascal void Timeline::DeferredTaskProc(long param)
{
    HXMM_INTERRUPTON();

    Timeline* pTheTimeline = (Timeline*)param;
		     
    if (pTheTimeline)
    {
#ifdef THREADS_SUPPORTED
	if (pTheTimeline->m_pCoreMutex) pTheTimeline->m_pCoreMutex->Lock();
#endif

	pTheTimeline->m_bAnyCallbackPending = 0;
	
	if ( !pTheTimeline->m_bIsQuitting )
	{
	    pTheTimeline->InterruptTimeSync();
	}
#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
	else
	{
	    DebugStr( "\pIn DeferredTaskProc, short-circuiting because we're quitting;g" );
	}
#endif
#ifdef THREADS_SUPPORTED
	if (pTheTimeline->m_pCoreMutex) pTheTimeline->m_pCoreMutex->Unlock();
#endif
    }

#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
    if ( pTheTimeline )
    {
	if ( pTheTimeline->m_uiDeferredTaskDepth != 0 )
	{
	    char tmpStr[255]; /* Flawfinder: ignore */
	    sprintf(tmpStr, "m_uiDeferredTaskDepth = %u;g", pTheTimeline->m_uiDeferredTaskDepth); /* Flawfinder: ignore */
	    DebugStr(c2pstr(tmpStr));
	}
    }
#endif
    HXMM_INTERRUPTOFF();
}

void 
Timeline::InterruptTimeSync(void)
{ 
    if (!m_bUseDeferredTasks)
    {
    	ULONG32 ulCurTime = HX_GET_TICKCOUNT();
    	if ( ulCurTime > (m_ulLastCallbackTime + m_ulGranularity) )
    	{
	    OnTimeSync(FALSE);
    	}
    }
    else
    {
    	if (m_pInterruptState)
    	{
	    m_pInterruptState->EnterInterruptState();
	}
    
    	OnTimeSync(TRUE);
    
#if defined (_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
	if ( m_bIsQuitting )
	{
	    DebugStr( "\pIn InterruptTimeSync, about to ::PrimeTime, and we're QUITTING!;g" );
	}
#endif
    	
	if ( !m_bIsQuitting )
	{
	    ::PrimeTime((QElemPtr) &m_tmInfo, m_ulGranularity); //restart timer
	    m_bAnyCallbackPending = 1;
	}
    
    	if (m_pInterruptState)
    	{
       	    m_pInterruptState->LeaveInterruptState();
    	}
    }
} 
#endif //_MACINTOSH

/*
 *  ********* MAC & UNIX ONLY *****************
 */
#if defined(_UNIX) || defined(_MACINTOSH) || defined(__TCS__) || defined(_OPENWAVE)
void
Timeline::CallAllTimeSyncs(void)
{    
#if defined(HELIX_CONFIG_NOSTATICS)
    TimelineMapType& m_zTimerMap =
	GlobalTimelineMapType::Get(&Timeline::m_zTimerMap);
#endif

    CHXMapPtrToPtr::Iterator ndxTimeline = m_zTimerMap.Begin();
    for (; ndxTimeline != m_zTimerMap.End(); ++ndxTimeline)
    {
	Timeline* pCurrentTimeline = (Timeline*)(*ndxTimeline);
	pCurrentTimeline->OnTimeSync();
    }
}
#endif /* _UNIX || _MACINTOSH */

⌨️ 快捷键说明

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