📄 rtrender.cpp
字号:
// we might scroll too far...etc.:#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile) { if(m_txtWin.getDebugFlags()& RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile, " -setting m_ulTimeOfCurrentDraw" " to m_ulDuration(%lu) +" " m_lTimeOffset(%lu)=%lu\n", m_ulDuration, m_lTimeOffset, m_ulDuration + m_lTimeOffset); } fflush(m_logfile); }#endif#endif m_ulTimeOfCurrentDraw = m_ulDuration + m_lTimeOffset; } bDoRedrawNow = TRUE; } } }#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"CRealTextRenderer::OnPacket()..." " Got Packet of stream %i of " "size %ld of time %ld " "(m_ulLastTimeSyncPlayerTimeIeNoOffset=%ld," "lTimeOffset=%ld, " "m_bLatePacketNotYetDrawn=%sE).\n{{{%s}}}\n", pPacket->GetStreamNumber(),pBuffer->GetSize(), lRealPacketTime, m_ulLastTimeSyncPlayerTimeIeNoOffset, lTimeOffset, m_bLatePacketNotYetDrawn?"TRU":"FALS", pBuffer->GetBuffer() ); fflush(m_logfile); }#endif#endif ulLength = pBuffer->GetSize(); { //Flush the Font, Bold, Italics, Underline, Strikethrough, // and indentAmt stacks because the packet header tells // us what's in them for the packet's text: m_txtWin.flushFontStacks(); m_txtWin.flushTickerStacks(); m_txtWin.flushBIUSandBlinkStacks(); m_txtWin.flushIndentAmtStack(); RealTextRenderer::OnData(pBuffer->GetBuffer(), ulLength, TRUE /*=from OnPacket()*/); pBuffer->Release(); } // /Fixes PR 39718: // when a packet arrives right after a seek but prior to other // streams' buffering completion, the rt window was being cleared // and the new data here was not being drawn so the user would // see blank rt windows during seek buffering. Moving the redraw // request to after "OnData" call, above, makes sure the new text // gets drawn prior to the long wait for other streams' buffering: if (bDoRedrawNow) { // Redraw our data by damaging the whole window: CHXxRect rect( m_txtWin.getUpperLeftX(), m_txtWin.getUpperLeftY(), (m_txtWin.getUpperLeftX()) + m_txtWin.getWindowWidth(), (m_txtWin.getUpperLeftY()) + m_txtWin.getWindowHeight()); m_pMISUSSite->DamageRect(rect); m_pMISUSSite->ForceRedraw(); } } m_bPriorPacketWasLostOrWeJustSeeked = FALSE; 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 CRealTextRenderer::OnTimeSync(ULONG32 ulTime){#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) ULONG32 ulPrevTime = m_ulLastTime;#endif#endif UINT32 ulAdjustedTime = 0; //Note: m_lTimeOffset is the offset passed in by the most-recent // OnPacket() call: if(m_lTimeOffset<0 && ulTime<(UINT32)(-m_lTimeOffset)) { ulAdjustedTime = 0; } else { ulAdjustedTime = ulTime + m_lTimeOffset; } // /Next, we need to adjust for any pausing period that may have happened // relative to the main timeline: ulAdjustedTime += m_lCumulativeUpdatedTimeOffset; if (m_PlayState != Playing) { // we just started playback m_PlayState = Playing; m_ulLastTimeSyncWorkTime = 0; m_ulLastTime = 0; m_ulLastTimeSyncPlayerTimeIeNoOffset = 0L;#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile," switching to \"Playing\" at time %lu " "in OnTimeSync()...\n", HX_GET_BETTERTICKCOUNT()); fflush(m_logfile); }#endif#endif } //Keep track of how long this OnTimeSync() call takes to process so we // don't hog the CPU if it takes too long: m_ulTimeAtPriorTimeSyncEntrance = HX_GET_BETTERTICKCOUNT(); if(0 == m_ulTimeAtPriorTimeSyncExit) //first time here: { m_ulTimeAtPriorTimeSyncExit = m_ulTimeAtPriorTimeSyncEntrance; } ULONG32 ulTimeUsedUpByAllOthers = m_ulTimeAtPriorTimeSyncEntrance - m_ulTimeAtPriorTimeSyncExit; ULONG32 ulTimeAllowedForThisRendering = //We'll skip this draw if other processes are using too much CPU, // but let's not be TOO accomodating, i.e., only if others used // 2 * m_ulGranularity or more do we force a skip of this: (2 * m_ulGranularity) - ulTimeUsedUpByAllOthers; if((2 * m_ulGranularity) < ulTimeUsedUpByAllOthers) { ulTimeAllowedForThisRendering = 0L; } // Keep track of time of last rendering: m_ulLastTime = ulAdjustedTime; //Also, keep track of last time sync time (without offset since we may // not have the valid offset yet) in case we later get a packet that // should have arrived before this time sync and needs to be drawn // (related to PR 22705): m_ulLastTimeSyncPlayerTimeIeNoOffset = ulTime; TextWindow* pTW = GetTextWindow(); if(pTW) { pTW->setTimeOfLastTimeSync(ulAdjustedTime); }#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"OnTimeSync() at: %lu, " "adjusted to: %lu, m_lTimeOffset=%ld\n", ulTime, ulAdjustedTime, m_lTimeOffset); fprintf(m_logfile," (Adjusted) Time since last time sync: %ld\n", ulAdjustedTime-ulPrevTime); fprintf(m_logfile," last work time is: %lu\n", m_ulLastTimeSyncWorkTime); fflush(m_logfile); }#endif#endif //Don't need to use safe time compare "IsTimeAMoreRecentThanTimeB()" // if live because of the "|| m_txtWin.isLiveSource()" which moots it: if((ulAdjustedTime <= m_ulDuration+m_lTimeOffset || m_txtWin.isLiveSource() || //Helps fix for PR 22048 and 22705; if first timeSync() is later // than our duration, draw anyway as if we're at the duration: m_bIsFirstTimeSynch ) && ShouldKickStartScheduler()) { //Jump start the drawing scheduler:#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile," Jump starting the drawing scheduler.\n"); fflush(m_logfile); }#endif#endif m_pMutex->Lock(); SchedulerCallback(); m_pMutex->Unlock(); } //[We used to check if ulTime was greater than duration, here; if it was // then we would set the play state to Stopped, but the SchedulerCallback // above might not be finished, yet, on the draw thread and it would end up // not drawing when it saw that the state was Stopped. This check got moved // to inside SchedulerCallback(), right after it has done the draw.] //NOTE: Drawing is now done inside the ::SchedulerCallback() code. m_ulTimeAtPriorTimeSyncExit = HX_GET_BETTERTICKCOUNT(); m_ulLastTimeSyncWorkTime = m_ulTimeAtPriorTimeSyncExit - m_ulTimeAtPriorTimeSyncEntrance; return HXR_OK;}/////////////////////////////////////////////////////////////////////////// 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 CRealTextRenderer::OnPreSeek(ULONG32 ulOldTime, ULONG32 ulNewTime){ m_pMutex->Lock(); m_bInSeekMode = TRUE; m_bEndStreamJustOccurred = FALSE; m_PlayState = Seeking; m_ulLastSeekedToTime = ulNewTime; LOG((m_logfile,"\nCRealTextRenderer::OnPreSeek(): " "setting m_PlayState to Seeking\n")); //Set this to the new time we're seeking to rather than TIME_INVALID // so, in the case where we're seeking past our duration, the next // Draw() won't call OnPaint with TIME_INVALID and thus OnPaint won't // re-paint the background but skip the foreground (text) painting // thinking erroneously that we're drawing prior to any packets arriving: if(m_bTimeOffsetHasBeenInitialized) { m_ulTimeOfCurrentDraw = ulNewTime + m_lTimeOffset; } else { m_ulTimeOfCurrentDraw = 0L; } //The following are done both here and in the "PreSeek" code in // SchedulerCallback() (draw thread) so that, in the case where we // seek beyond the end of the stream, we still reset the following even // though SchedulerCallback() never gets called again: m_ulTimeOfPriorDraw = TIME_INVALID; m_ulTimeOfLastNonScrollWindowDraw = TIME_INVALID; //Fixes seeking to a spot past end of rt stream (to where stream is // frozen) and a covering/uncovering of the window results in a draw // that is done at a time past the duration, thus scrolling moving // text out of the window: if(m_ulTimeOfCurrentDraw > m_ulDuration + m_lTimeOffset) { m_ulTimeOfCurrentDraw = m_ulDuration + m_lTimeOffset; } m_ulCurFrameTime = (ulNewTime < m_ulDuration? ulNewTime:m_ulDuration) + m_lTimeOffset; if(m_lTimeOffset < 0L && ulNewTime < (ULONG32)(-m_lTimeOffset)) { m_ulCurFrameTime = 0L; } if(!m_bTimeOffsetHasBeenInitialized) { m_ulCurFrameTime = 0L; } //We have to set this here so that hyperlink-mouse-hit-test code will // work even after a seek beyond our duration: //XXXEH1208- do I want to add m_lTimeOffset to m_ulDuration here? m_txtWin.setTimeOfLastTimeSync(ulNewTime > m_ulDuration? m_ulDuration:ulNewTime); m_bSeekJustFinished = TRUE;#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"OnPreSeek(oldTime:=%lu, newTime:=%lu)\n", ulOldTime, ulNewTime); }#endif#endif //Next OnTimeSync --> OnTimeSynch() will be the first post-seek one: m_bIsFirstTimeSynch = TRUE; m_pMutex->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 CRealTextRenderer::OnPostSeek(ULONG32 ulOldTime, ULONG32 ulNewTime){ m_pMutex->Lock(); m_ulCurFrameTime = ulNewTime + m_lTimeOffset; if(m_lTimeOffset < 0L && ulNewTime < (ULONG32)(-m_lTimeOffset)) { m_ulCurFrameTime = 0L; } // /Final fix for PR 95127: move this block out from the if(m_lTime...) // block above; we want to do the following code under all seek // circumstances. It turns out that it doesn't hurt to do so in cases // where it isn't needed, and it helps prevent doubling of text in cases // where this plain-text stream has an explicit durutaion (dur or end in // the SMIL) and is seeked during the time it is active (not frozen): { // /To help fix renderer bug due to rtff fix of PR 95127: // if we're seeking back to before our start time and if it's // plain text, then erase all plain text received so far // (otherwise new packets will just get appended to the old // (same) text: if (RealTextRenderer::isPlainText()) { m_ulPlainTextDataLen = 0; if (m_pPlainTextData) { delete [] m_pPlainTextData; m_pPlainTextData = NULL; } m_ulPlainTextDataBufferSize = 0; } } if(!m_bTimeOffsetHasBeenInitialized) { m_ulCurFrameTime = 0L; } m_bInSeekMode = FALSE; m_bEndStreamJustOccurred = FALSE; m_bNoPacketsYetSinceLastSeek = TRUE;#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"OnPostSeek(oldTime:=%lu, newTime:=%lu)\n", ulOldTime, ulNewTime); }#endif#endif 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 CRealTextRenderer::OnPause(ULONG32 ulTime){ m_pMutex->Lock();#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"OnPause() at %lu. " " Setting m_PlayState to Paused\n", ulTime); }#endif#endif m_PlayState = Paused; m_pMutex->Unlock(); return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXRenderer::OnBegin// Purpose:// Called by client engine to inform the renderer that a begin or// resume has just occured. The render is informed the first time // for the stream's time line after the resume.//STDMETHODIMP CRealTextRenderer::OnBegin(ULONG32 ulTime){#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"OnBegin() at %lu\n", ulTime); }#endif#endif return HXR_OK;}/////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -