📄 rtrender.cpp
字号:
} } pHeader->GetPropertyCString("StreamName", pStreamName); pHeader->GetPropertyCString("MimeType", pMimeType); ULONG32 ulTotalSourceFileSizeInBytes = (ULONG32)(((double)ulAvgBitRate / 8.0/*bits/byte*/) * 60.0/*seconds*/) / 1.2 /*1.2==FF's HEADER_OVERHEAD_FACTOR*/; ULONG32 ulTmp = 0; if (HXR_OK == pHeader->GetPropertyULONG32("SourceFileSize", ulTmp) && ulTmp > 0) { ulTotalSourceFileSizeInBytes = ulTmp; } RealTextRenderer::setSourceFileSize(ulTotalSourceFileSizeInBytes); ULONG32 ulMaxPlainTextBytesToBeSentByFF = (UINT32)-1; if (HXR_OK == pHeader->GetPropertyULONG32("MaxPlainTextBytesToBeSent",ulTmp) && ulTmp > 0) { ulMaxPlainTextBytesToBeSentByFF = ulTmp; } RealTextRenderer::setMaxPlainTextBytesToBeSentByFF( ulMaxPlainTextBytesToBeSentByFF); if (pMimeType) { const char* pszMimeType = (const char*)pMimeType->GetBuffer(); if (pszMimeType && 0==stricmp(pszMimeType, "text/plain") ) { RealTextRenderer::setIsTextPlainStreamMimeType(TRUE); } } //XXXEH- this seems to work even though m_ulDuration hasn't been set // yet; do we really want to do this, or wait until after it's set? m_txtWin.SetLatestSentTimeToStopRendering(m_ulDuration); ulLengthHeader = 0; if (pOpaqueData) // /This will be NULL if text/plain, which has no header. { ulLengthHeader = pOpaqueData->GetSize(); retVal = RealTextRenderer::OnHeader(pOpaqueData->GetBuffer(), ulLengthHeader); } else // /We still need to call OnHeader() to init m_txtWin properly: { char* pszPlainTextHeader = new char[32]; if (pszPlainTextHeader) { strcpy(pszPlainTextHeader, " "); /* Flawfinder: ignore */ ulLengthHeader = strlen(pszPlainTextHeader); retVal = RealTextRenderer::OnHeader(pszPlainTextHeader, ulLengthHeader); delete [] pszPlainTextHeader; } } if(ulPresentationDuration) { m_txtWin.m_ulDuration = ulPresentationDuration; } else { m_txtWin.m_ulDuration = DEFAULT_DURATION_MSEC; } //XXXXXEH-bp: make sure we know this value before we use it: if(m_txtWin.isLiveSource()) { m_txtWin.m_ulDuration = TIME_INVALID; } m_ulDuration = m_txtWin.m_ulDuration; if (RealTextRenderer::isTextPlainStreamMimeType()) { m_ulGranularity = PLAIN_TEXT_GRANULARITY; } //Adjust the granularity of time synchs based on the rate(s) of motion, // i.e., we want time synchs in concert with the scrollrate and // crawlrate, if any, so that the renderer gets enough timesyncs to draw // with the smoothest motion. For example, if the scroll rate is 20 // pixels per second and crawl rate is 0, then we want to draw every // 50 millisec so that we move the text exactly 1 pixel each draw. // If the scroll rate is 20 and the crawl rate is 30, we'd draw every // 33 milliseconds to handle the higher crawl rate: else if (!m_txtWin.getScrollRate() && !m_txtWin.getCrawlRate()) { m_ulGranularity = NO_MOTION_GRANULARITY; } else { LONG32 lHighestRate = m_txtWin.getScrollRate(); if(lHighestRate < m_txtWin.getCrawlRate()) { lHighestRate = m_txtWin.getCrawlRate(); } m_ulFrameRate = lHighestRate; if(m_ulFrameRate > MAX_ALLOWED_FRAMERATE) { //If framerate is, say 75, we want to use // 25 (which is a divisor of both 75 and 1000) // and not use 30 (which is not): if(m_ulFrameRate % MAX_SMOOTH_FRAMERATE == 0) { m_ulFrameRate = MAX_SMOOTH_FRAMERATE; } //If framerate is, say 40, we want to use // 20 (which is a divisor of both 40 and 1000) // and not use 30 (which is not): else if(m_ulFrameRate % MAX_SMOOTH_FRAMERATE_2 == 0) { m_ulFrameRate = MAX_SMOOTH_FRAMERATE_2; } else { m_ulFrameRate = MAX_ALLOWED_FRAMERATE; } } if(m_ulFrameRate < MIN_ALLOWED_FRAMERATE) { m_ulFrameRate = MIN_ALLOWED_FRAMERATE; } m_ulGranularity = (1000 / m_ulFrameRate); } m_pStream->SetGranularity(m_ulGranularity); //Since this variable is initialized to zero, we need to // re-set it to the wallclock-based timeline's "zero" if // live which equals the start time of the encoder. Fixes // PR 23344: if (m_txtWin.isLiveSource()) { m_txtWin.setTimeOfLastTimeSync(m_ulStreamStartTime); }#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK && !m_logfile) //Only create a log for the first stream. { char slashChar = '\\';#if defined(_UNIX) && (!(defined(_BEOS))) && (!(defined(_MAC_UNIX))) slashChar = '/';#endif#if defined(_MACINTOSH) || defined(_MAC_UNIX) m_logfile = fopen("rt_0.log", "w");#endif#if defined(_WINDOWS) char logfilename[32]; /* Flawfinder: ignore */ sprintf(logfilename,"c:%crt_%i.log", slashChar, /* Flawfinder: ignore */ m_pStream->GetStreamNumber()); m_logfile=fopen(logfilename,"w");#endif#if defined(_UNIX) && (!(defined(_BEOS))) && (!(defined(_MAC_UNIX))) char logfilename[32]; /* Flawfinder: ignore */ sprintf(logfilename,"/tmp/rt_%i.log", /* Flawfinder: ignore */ m_pStream->GetStreamNumber()); m_logfile=fopen(logfilename,"w");#endif if(m_logfile) { fprintf(m_logfile,"Stream number %lu\n", ulStreamNumber); fprintf(m_logfile,"Max bit rate %lu\n", ulMaxBitRate); fprintf(m_logfile,"Avg bit rate %lu\n", ulAvgBitRate); fprintf(m_logfile,"Max packet size %lu\n", ulMaxPacketSize); fprintf(m_logfile,"Avg packet size %lu\n", ulAvgPacketSize); fprintf(m_logfile,"Start time %lu ms\n", ulStartTime); fprintf(m_logfile,"Preroll %lu ms\n", ulPreroll); fprintf(m_logfile,"Duration %lu ms\n", ulPresentationDuration); fprintf(m_logfile,"Stream name length: %lu\n", pStreamName? pStreamName->GetSize():0 ); fprintf(m_logfile,"Header opaque data length: %lu\n", pOpaqueData? pOpaqueData->GetSize():0 ); if (pOpaqueData) { fprintf(m_logfile,"Header pOpaqueData: {{{%s}}}\n", pOpaqueData->GetBuffer() ); } fprintf(m_logfile, "\nSetting granularity for OnTimeSync() " "calls to: %lu\n", m_ulGranularity);//XXXXXEH-bp: make sure we know this value before we use it: if(m_txtWin.isLiveSource()) { fprintf(m_logfile,"RTLiveStartTime %lu ms\n", m_ulStreamStartTime); } fprintf(m_logfile,"RTMarkupParsingMajorVersion." "RTMarkupParsingMinorVersion " "%lu.%lu\n", m_ulRTMarkupParsingMajorVersion, m_ulRTMarkupParsingMinorVersion); fprintf(m_logfile,"REAL_TEXT_MARKUP_PARSING_MAJOR_VERSION." "REAL_TEXT_MARKUP_PARSING_MINOR_VERSION " "%lu.%lu\n", REAL_TEXT_MARKUP_PARSING_MAJOR_VERSION, REAL_TEXT_MARKUP_PARSING_MINOR_VERSION); fprintf(m_logfile,"MinRTMajorVersion.MinRTMinorVersion " "%lu.%lu\n", ulMinMajorVer, ulMinMinorVer); if(bAutoUpgradeNeeded) { fprintf(m_logfile,"\nAuto upgrade being called\n"); } if(!m_ulStreamStartTime) { //If m_ulStreamStartTime was not set yet in OnHeader, then, // if it's live, the live text encoder was using a 0-based // timeline so we're OK. This value is only really used by // live streams because it is set to 0 for non-live. This is // used as "timeZero" when calculating the amt of scroll // and/or crawl at any time in the stream: if(m_txtWin.isLiveSource()) { fprintf(m_logfile, "\n*** Live Text app is using an old," " pre-wallclock-sync rtlive library\n"); } } } }#endif#endif if(pOpaqueData) { pOpaqueData->Release(); } if(pStreamName) { pStreamName->Release(); } if(pMimeType) { pMimeType->Release(); }#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile) { fflush(m_logfile); }#endif#endif HXxSize rtxFileSpecifiedSize; rtxFileSpecifiedSize.cx = m_txtWin.getWidth(); rtxFileSpecifiedSize.cy = m_txtWin.getHeight(); m_txtWin.setVisibleWindowWidth(m_txtWin.getWidth()); m_txtWin.setVisibleWindowHeight(m_txtWin.getHeight()); // Set the initial properties if (m_pValues) { m_pValues->SetPropertyULONG32("backgroundColor", m_txtWin.getBackgroundColor()); m_pValues->SetPropertyULONG32("backgroundOpacity", m_txtWin.getBackgroundOpacity()); m_pValues->SetPropertyULONG32("mediaOpacity", m_txtWin.getMediaOpacity()); m_pValues->SetPropertyULONG32("chromaKeyTolerance", m_txtWin.getChromaKeyTolerance()); m_pValues->SetPropertyULONG32("chromaKeyOpacity", m_txtWin.getChromaKeyOpacity()); } // /This is a good time to check the user setting, if any, for text size: // /XXXEH- It's resource-intensive to do the following, so only do it // sparingly. For now, we'll just call it once, but we'll probably want // to add support for the user changing the pt size pref during playback: adjustForUserTextSizeSetting(); return hxr;}/////////////////////////////////////////////////////////////////////////// Method:// IHXRenderer::OnPacket// Purpose:// Called by client engine when a packet for this renderer is // due.//STDMETHODIMP CRealTextRenderer::OnPacket(IHXPacket* pPacket, LONG32 lTimeOffset){ ULONG32 ulLength; if (!pPacket) return HXR_OK; if (m_bInSeekMode) { return HXR_OK; } m_lTimeOffset = lTimeOffset; m_bTimeOffsetHasBeenInitialized = TRUE; HX_ASSERT(m_lTimeOffset == lTimeOffset); if (pPacket->IsLost()) { //Since live packets get resent (and we'll eventually get this lost // one), we don't want to put extraneous text in the rendering: if(!m_txtWin.isLiveSource()) { char szLostData[] ={"<FONT color=black bgcolor=red> ... </FONT>"}; OnData(szLostData, strlen(szLostData), TRUE /*=from OnPacket()*/); m_bPriorPacketWasLostOrWeJustSeeked = TRUE; }#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"CRealTextRenderer::OnPacket(): Packet was lost." " (lTimeOffset=%ld).\n", lTimeOffset ); fflush(m_logfile); }#endif#endif return HXR_OK; } if(m_bNoPacketsYetSinceLastSeek) {#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile," m_bNoPacketsYetSinceLastSeek=TRUE\n"); fflush(m_logfile); }#endif#endif m_bNoPacketsYetSinceLastSeek = FALSE; //reset() clears the TextAttributeStacks, too, but I think // that's OK because the stacks keep their m_default vals intact // and re-push them if a pop() when empty is tried: /*XXXXXEH- don't need to do this because we'll never get here if // we've exceeded the duration and m_PlayState==playing:#error: if you reactivate this code, make sure to use safe time comparison function "IsTimeAMoreRecentThanTimeB(...)" being sure to pass in the (defaultable) 3rd parameter: m_txtWin.isLiveSource(): if(ulNewTime <= m_ulDuration) */ { m_txtWin.reset(); } flush(); //clears ::ListOfPacketDataIDsReceived. //Now, just kill everything after a seek (and before any new packets // arrive) since packets are resent anyway. For code that handles // keeping around prior text, see revision 122 or earlier of this // file, in this function: m_txtWin.clear_all(); } // Release the last packet if we had one... if (m_pLastPacket) { HX_RELEASE(m_pLastPacket); } // Keep this one for later use... m_pLastPacket = pPacket; if (m_pLastPacket) { m_pLastPacket->AddRef(); IHXBuffer* pBuffer = m_pLastPacket->GetBuffer(); LONG32 lRealPacketTime = pPacket->GetTime(); if(m_txtWin.isLiveSource() && m_bNoPacketsArrivedYet) { m_ulCurFrameTime = lRealPacketTime; //set first frame time. } m_bNoPacketsArrivedYet = FALSE; UINT32 ulPktTimeInPlayerTimeIeNoOffset = pPacket->GetTime(); //Adjust the time based on the offset handling overflow // correctly: if (lTimeOffset < 0) { ulPktTimeInPlayerTimeIeNoOffset += (UINT32) (-lTimeOffset); } else { if (ulPktTimeInPlayerTimeIeNoOffset < (UINT32)lTimeOffset) { ulPktTimeInPlayerTimeIeNoOffset = 0; } else { ulPktTimeInPlayerTimeIeNoOffset -= (UINT32)lTimeOffset; } } BOOL bDoRedrawNow = FALSE; //(PR22705): Now, if we're not live, compare the packet time (in // player time) to the time of last time sync (in player time); if // the packet time is earlier, then we need to make sure a draw // occurs to include this new text: if (!m_txtWin.isLiveSource() && ulPktTimeInPlayerTimeIeNoOffset <= m_ulLastTimeSyncPlayerTimeIeNoOffset) { m_bLatePacketNotYetDrawn = TRUE; // Do the following in case we don't get a time synch between // draws, e.g., if the playback stops and then the rt window is // covered and then uncovered, we'll get a paint message but // no time sync associated with it, so we don't want to // DO_CPU_FRIENDLY_SCROLLING in this case: SetSomeonesBeginOrEndTimeWasCrossedOverSinceLastDraw(TRUE); //In case we're receiving this packet late and after our // duration has expired (and thus the draw scheduler has // quit), we should still give it a chance to draw by // forcing a redraw: if (ShouldKickStartScheduler()) { if (m_pMISUSSite) { m_ulTimeOfPriorDraw = m_ulTimeOfCurrentDraw; m_ulTimeOfCurrentDraw = m_ulCurFrameTime; if(m_ulTimeOfCurrentDraw > m_ulDuration+m_lTimeOffset && !m_txtWin.isLiveSource()) { //Never draw at time greater than duration or
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -