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

📄 pxgifrnd.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // Retrieve the flags    UINT32 ulFlags = 0;    UnPack32(pData, ulFlags);    // Is this packet the beginning of a new image?    BOOL bFirstInImage = FALSE;    if (ulFlags & 0x01)    {        bFirstInImage = TRUE;    }    // Comment extensions at the end of the file could mean we receive packets    // after we are finished decoding. In this case, we just return    if (m_pGIFCodec->DecompressFinished())    {        HX_RELEASE(pBuffer);        return HXR_OK;    }    // Pass the data on to the CGIFCodec    HX_RESULT retVal = m_pGIFCodec->Decompress(pBuffer->GetBuffer() + 4,                                               pBuffer->GetSize()   - 4,                                               bFirstInImage);    if (retVal != HXR_OK)    {        CopyBombImage();    }    // Release our reference to the IHXBuffer    HX_RELEASE(pBuffer);    return HXR_OK;}STDMETHODIMP CGIFRenderer::OnTimeSync(UINT32 ulTime){    MLOG_TIMING(m_pErrorMessages,              "0x%08x::OnTimeSync(%lu)\n",              this, ulTime);    HX_RESULT retVal = HXR_OK;    if (m_bFirstTimeSync || m_bPaused)    {        // Clear the first timesync flag        m_bFirstTimeSync = FALSE;        // Clear the paused flag        m_bPaused = FALSE;        // Adjust the time according to the        // offset passed in through OnPacket()        INT32  lAdjustedTime  = ((INT32) ulTime) + m_lTimeOffset;        UINT32 ulAdjustedTime = (UINT32) (lAdjustedTime >= 0 ? lAdjustedTime : 0);        // Set the current scheduler time base        if (m_pScheduler)        {            // Compute time in milliseconds            m_tSchedulerTimeBase = m_pScheduler->GetCurrentSchedulerTime();//            m_ulSchedulerTimeBase = (cTime.tv_sec * 1000) + ((cTime.tv_usec + 500) / 1000);            m_ulTimeAtSchedulerTimeBase = ulAdjustedTime;        }        // Update the display        UpdateDisplay(ulAdjustedTime);    }    return retVal;}HX_RESULT CGIFRenderer::UpdateDisplay(UINT32 ulTime){    MLOG_MISC(m_pErrorMessages,              "%lu UpdateDisplay(%lu) this=0x%08x\n",              HX_GET_BETTERTICKCOUNT(), ulTime, this);    HX_RESULT retVal = HXR_OK;    // Do we have a valid CGIFCodec?    if (m_pGIFCodec && !m_bImageBombed)    {        // Reset the damage flag        BOOL bDoDamage = FALSE;        // Compute which frame we should be on at this time        UINT32 ulFrameIndex = 0;        if (m_pGIFCodec->GetNumImages() > 1)        {            // Get the modulo time            UINT32 ulModTime   = 0;            UINT32 ulCycleTime = GetCycleTime();            if (ulCycleTime)            {                UINT32 ulIter      = ulTime / ulCycleTime;                UINT32 ulIterStart = ulIter * ulCycleTime;                ulModTime          = ulTime - ulIterStart;            }            UINT32 ulRunSum    = 0;            UINT32 ulNumFrames = m_pGIFCodec->GetNumImages();            for (UINT32 i = 0; i < ulNumFrames; i++)            {                // Get the delay for this frame                UINT32     ulFrameDelay = 0;                CGIFImage* pImage       = m_pGIFCodec->GetImage(i);                if (pImage)                {                    ulFrameDelay = pImage->GetDelayTime() * 10;                }                // Check if our time is in this frame                if (ulModTime >= ulRunSum &&                    ulModTime <  ulRunSum + ulFrameDelay)                {                    ulFrameIndex = i;                    break;                }                // Add the delay for this frame to the running sum                ulRunSum += ulFrameDelay;            }        }        // Is the frame currently in the buffer the same        // as our computed frame? If it is, then we don't        // need to update our buffer        BOOL bFinished         = FALSE;        BOOL bWouldHaveSkipped = FALSE;        if (ulFrameIndex != m_ulCurFrameIndex)        {            // Make sure we don't skip frames            UINT32 ulFrameIndexNoSkip = ulFrameIndex;            if (m_ulCurFrameIndex != 0xFFFFFFFF)            {                UINT32 ulFrameDiff = 0;                if (ulFrameIndex >= m_ulCurFrameIndex)                {                    ulFrameDiff = ulFrameIndex - m_ulCurFrameIndex;                }                else                {                    ulFrameDiff = m_pGIFCodec->GetNumImages() -                                  m_ulCurFrameIndex + ulFrameIndex;                }                if (ulFrameDiff > 1)                {                    ulFrameIndexNoSkip = m_ulCurFrameIndex + 1;                    if (ulFrameIndexNoSkip >= m_pGIFCodec->GetNumImages())                    {                        ulFrameIndexNoSkip = 0;                    }                }            }            // Enforce no skipping of frames, but set a flag if            // we did have to change the frame, so that we can            // use that to update our callback interval            if (ulFrameIndexNoSkip != ulFrameIndex)            {                // Yes, we are having to force not to skip a frame                bWouldHaveSkipped = TRUE;                ulFrameIndex      = ulFrameIndexNoSkip;            }            // Is the image we want to draw done? If it's not finished,            // we DON'T want to draw but we DO want another callback            CGIFImage* pCurImage = m_pGIFCodec->GetImage(ulFrameIndex);            if (pCurImage)            {                bFinished = pCurImage->Finished();            }            // Do we need to update?            if (bFinished)            {                // Yes, we need to update, so first we get the image                m_pGIFCodec->GetRGBImageEx((m_ulCurFrameIndex == 0xFFFFFFFF ? -1 : (INT32) m_ulCurFrameIndex),                                           ulFrameIndex,                                           m_pOutputBuffer->GetBuffer(),                                           m_pGIFCodec->GetLogicalScreenWidth(),                                           m_pGIFCodec->GetLogicalScreenHeight(),                                           m_ulPadWidth,                                           m_ulBytesPerPixel,                                           m_bRowsInverted,                                           m_bRGBOrdering,                                           m_ulBackgroundColor,                                           (m_ulMediaOpacity == 255 ? FALSE : TRUE),                                           m_ulMediaOpacity,                                           m_bMediaChromaKeySpecified,                                           m_ulMediaChromaKey,                                           m_ulMediaChromaKeyTolerance,                                           m_ulMediaChromaKeyOpacity);                // XXXMEH - do dumb assignment for now. We should later check                // chroma key to find if any colors were actually encountered.                if (m_ulBackgroundOpacity < 255 ||                    m_ulMediaOpacity < 255      ||                    m_bMediaChromaKeySpecified)                {                    m_bUsesAlphaChannel = TRUE;                }                // Set the damage flag                bDoDamage = TRUE;                // We need to damage the rect. If we are bltting off                // of HX_SURFACE_UPDATE2, then we should damage the                // rect of both the current frame and the previous frame.                // If we are still bltting off of HX_SURFACE_UPDATE, then                // we need to damage the whole logical screen area.                if (m_bCanBltSubRects)                {                    // Damage the rect of the previous frame                    DamageFrameRect(m_ulCurFrameIndex);                    // Damage the rect of the current frame                    DamageFrameRect(ulFrameIndex);                    // Force a redraw                    if (m_pMISUSSite)                    {                        m_pMISUSSite->ForceRedraw();                    }                }                else                {                    // Damage entire site area                    if (m_pMISUSSite)                    {                        // Get the size of the site                        HXxSize cSize = {0, 0};                        m_pMISUSSite->GetSize(cSize);                        // Get the damage rect                        HXxRect cRect = {0, 0, cSize.cx, cSize.cy};                        MLOG_MISC(m_pErrorMessages,                                  "%lu     Damaging entire logical screen: "                                  "(%ld,%ld,%ld,%ld) (%ld x %ld)\n",                                  HX_GET_BETTERTICKCOUNT(),                                  cRect.left,  cRect.top,                                  cRect.right, cRect.bottom,                                  HXxRECT_WIDTH(cRect),                                  HXxRECT_HEIGHT(cRect));                        m_pMISUSSite->DamageRect(cRect);                        m_pMISUSSite->ForceRedraw();                    }                }                // Check if we just completed a loop. If the frame                // index that we just drew into the buffer is LOWER                // than the frame index that USED to be there, then                // we will assume we just wrapped around                if ((m_ulCurFrameIndex           == 0xFFFFFFFF &&                     m_pGIFCodec->GetNumImages() == 1) ||                    (m_ulCurFrameIndex           != 0xFFFFFFFF &&                     ulFrameIndex                <  m_ulCurFrameIndex))                {                    m_ulLoopsDone++;                }                // Update the current frame index                m_ulCurFrameIndex = ulFrameIndex;            }        }        // Do we need to schedule another callback?        if (m_bSiteAttached &&                                        // only schedule another callback if site is attached            m_pCallback    &&                                         // can't do it without a callback object            (m_bPreserveMediaRepeat ||             (!m_bPreserveMediaRepeat && m_ulLoopsDone == 0)) &&            ((bFinished == FALSE)               ||                    // GIF isn't finished yet            (m_pGIFCodec->GetLoopCount() == 0) ||                     // GIF says to loop infinitely             (m_pGIFCodec->GetLoopCount() > 0 &&                      // GIF says to loop a finite number of              m_ulLoopsDone < m_pGIFCodec->GetLoopCount())))          //   times and we're not finished        {            // If we just drew the image, then don't schedule a callback until            // the delay time from now. If we didn't draw, then schedule one            // kCallbackInterval milliseconds from now            BOOL       bRelative     = TRUE;            UINT32     ulTimeFromNow = kCallbackInterval;            HXTimeval cTime         = {0, 0};            // Was the frame finished?            if (bFinished)            {                // Did we draw and would have skipped a frame?                if (bDoDamage && bWouldHaveSkipped)                {                    // Schedule a short relative callback                    bRelative     = TRUE;                    ulTimeFromNow = kMinCallbackInterval;                }                else                {                    // Get the time that the next frame would display                    UINT32 ulNextFrameTime = GetNextFrameTime(ulTime);                    // If the difference is small enough, then schedule                    // a short relative callback. Otherwise schedule                    // an absolute callback                    if (ulNextFrameTime - ulTime > kMinCallbackInterval)                    {                        // Get the time difference between the next frame                        // time and the time at the scheduler time base                        UINT32 ulDiff = 0;                        if (ulNextFrameTime >= m_ulTimeAtSchedulerTimeBase)                        {                            ulDiff = ulNextFrameTime - m_ulTimeAtSchedulerTimeBase;                        }                        else                        {                            ulDiff = 0xFFFFFFFF - m_ulTimeAtSchedulerTimeBase + ulNextFrameTime;                        }                        // Compute the difference in seconds and microseconds                        HXTimeval cDiff = {0, 0};                        cDiff.tv_sec  = ulDiff / 1000;                        cDiff.tv_usec = (ulDiff - (cDiff.tv_sec * 1000)) * 1000;                        // Add this difference to the scheduler time base                        cTime.tv_sec  = m_tSchedulerTimeBase.tv_sec  + cDiff.tv_sec;                        cTime.tv_usec = m_tSchedulerTimeBase.tv_usec + cDiff.tv_usec;                        // Wrap the usec if necessary                        if (cTime.tv_usec >= 1000000)                        {                            cTime.tv_usec -= 1000000;                            cTime.tv_sec  += 1;                        }                        // Clear the relative flag                        bRelative = FALSE;                    }                    else                    {                        bRelative     = TRUE;                        ulTimeFromNow = kMinCallbackInterval;                    }                }            }            else            {                // Frame had not completed decoding - schedule a                // relative callback                bRelative     = TRUE;                ulTimeFromNow = kNotFinishedInterval;            }            // Schedule the next callback            if (bRelative)            {                m_pCallback->ScheduleRelativeCallback(ulTimeFromNow);            }            else            {                m_pCallback->ScheduleAbsoluteCallback(cTime);            }        }    }    return retVal;}STDMETHODIMP CGIFRenderer::OnPreSeek(UINT32 ulTimeBefore, UINT32 ulTimeAfter){    MLOG_MISC(m_pErrorMessages,              "0x%08x::OnPreSeek(%lu,%lu)\n",              this, ulTimeBefore, ulTimeAfter);    // Set the ignore packets flag    m_bIgnorePackets = TRUE;    return HXR_OK;}STDMETHODIMP CGIFRenderer::OnPostSeek(UINT32 ulTimeBefore, UINT32 ulTimeAfter){    MLOG_MISC(m_pErrorMessages,              "0x%08x::OnPostSeek(%lu,%lu)\n",              this, ulTimeBefore, ulTimeAfter);    HX_RESULT retVal = HXR_OK;    if (m_pStreamHeaderBuffer && !m_bImageBombed)    {        // Determine if the seek-to time is past our ending time.        // We only need to blow away everything if we are going to        // be getting packets all over again. That will happen only        // if the seek-to time is < our end time.        if (ulTimeAfter < m_ulEndTime)        {            // We are going to start receiving packets all over again, so            // we need to blow away the CGIFCodec class and start over            // again. We will need to reinit it with the stream header            // buffer.            //            // Delete the old CGIFCodec            HX_DELETE(m_pGIFCodec);            // Create a new one            m_pGIFCodec = new CGIFCodec();            if (m_pGIFCodec)            {                // Get the stream header pointer                BYTE* pData = m_pStreamHeaderBuffer->GetBuffer() + m_ulStreamHeaderOffset;                // Initialize the CGIFCodec for decompression                retVal = m_pGIFCodec->InitDecompress(m_pStreamHeaderBuffer->GetBuffer() + m_ulStreamHeaderOffset,                                                     m_pStreamHeaderBuffer->GetSize()   - m_ulStreamHeaderOffset);                if (SUCCEEDED(retVal))                {                    // Initialize the rendering members                    m_ulCurImg           = 0;                    m_ulCurImgRenderTime = 0;                    m_ulCurDelayTime     = 0;                    m_lLastImg           = -1;                    // Initialize the loop done count                    m_ulLoopsDone        = 0;                    // Clear the ignore packets flag                    m_bIgnorePackets     = FALSE;                }            }            else            {                retVal = HXR_OUTOFMEMORY;            }        }    }

⌨️ 快捷键说明

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