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

📄 winsurf2.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                m_TimeStamps.AddSample();
#endif
            }
            else
            {
                // If we are in fallback mode, make them manually redraw
                if (m_bFallbackSurfaceCreated && HX_OVERLAY_BLT!=m_nBltMode && !m_bYUVBlending)
                {
                    // If no src rect is specified, use surface
                    if (!prSrcRect->right && !prSrcRect->bottom)
                    {
                        prSrcRect->right = m_allocatedFallbackSize.cx;
                        prSrcRect->bottom = m_allocatedFallbackSize.cy;
                    }

                    SetLastScale(prSrcRect, prDestRect);

                    _ConstructRects( *prSrcRect,
                                     *prDestRect,
                                     FALSE,
                                     nNumRects,
                                     &paSrcRects,
                                     &paDestRects);
                
                    memcpy(&m_lastSrcRect, paSrcRects, sizeof(*paSrcRects)); /* Flawfinder: ignore */

                    EnterCriticalSection(&m_csFallback);

                    for( int j=0 ; j<nNumRects ; j++ )
                    {
                        hr = WinDrawSurface_Blt(pWindraw, &m_fallbackSurface, (RECT*)&paDestRects[j], (RECT*)&paSrcRects[j]);
                    }

                    LeaveCriticalSection(&m_csFallback);
        
                    HX_VECTOR_DELETE(paSrcRects);
                    HX_VECTOR_DELETE(paDestRects);

#if !defined(_GOLD) && 0
                    m_TimeStamps.AddSample();
#endif
                }
            }
        }
    
        return hr;
    }

    if (m_bFlushing)
    {
        return HXR_COULD_NOT_DISPLAY;
    }
    
    INT32   nIndex = -1;

    // Add this frame to the list and alert the render thread
    tFrameElement *pItem = new tFrameElement;

    memset(pItem, 0, sizeof(*pItem));
    pItem->lTimeStamp = lTime;
    pItem->nBltMode = HX_OVERLAY_BLT;
    pItem->ulFlags = ulFlags;
    pItem->rcSrc = *prSrcRect;
    pItem->rcDst = *prDestRect;
    pItem->bAlpha = m_bFrameHasHWAlphaBlend;
    pItem->count  = pVidStruct->ulCount;
    pItem->bmi = m_bmi;

    // If we are in system memory mode, we must blt to hardware ourselves
    if (m_bUseSysMemSurface)
    {
        m_bUseSysMemSurface = FALSE;

        BOOL bAlphaCheck = m_bDoAlphaCheck;

        // Grab a hw buffer and convert the sys mem image to hw yuv.
        UCHAR *pScratchVidMem = NULL;
        INT32 nPitch = 0;
        HXBitmapInfoHeader bmiTemp;
        memset( &bmiTemp, 0, sizeof( bmiTemp ) );

        // We need a hw mem buffer, so disable the alpha blending check
        // that returns system mem.
        m_bDoAlphaCheck = FALSE;
    
        VideoMemStruct vs;
        memset(&vs, 0, sizeof(vs));
        GetVideoMem(&vs, HX_WAIT_FOREVER);

        pScratchVidMem = vs.pVidMem;
        nPitch = vs.lPitch;
        bmiTemp = vs.bmi;

        if (pScratchVidMem)
        {
            HXxSize srcSize = {bmiTemp.biWidth, bmiTemp.biHeight};
            SourceInputStruct input = {&m_pSysMemSurf[m_nNextSysMemBuffer].pBuffer,
                                       &m_nSysMemSurfPitch, 1};
                            
            ColorConvert(m_nSysMemSurfID,
                         &m_allocatedSysMemSurfSize,
                         prSrcRect,
                         &input,
                         bmiTemp.biCompression,
                         pScratchVidMem, 
                         &srcSize,
                         prDestRect,
                         nPitch);
        
            ReleaseSurface(&vs, FALSE);
        }
    
        m_bDoAlphaCheck = bAlphaCheck;

        if (!pScratchVidMem)
            goto FAILURE;
    
        pItem->nIndex = m_nNextSysMemBuffer;
        if (++m_nNextSysMemBuffer == m_nSysMemSurfCount)
            m_nNextSysMemBuffer = 0;
    }

    // Alpha blend if necessary
    if (pVidStruct->pAlphaList && pVidStruct->ulCount)
    {
        HXxSize size = {pVidStruct->bmi.biWidth, pVidStruct->bmi.biHeight};
        
        YuvAlphaBlend(pVidStruct->pAlphaList,
                      pVidStruct->ulCount,
                      pVidStruct->pVidMem,
                      pVidStruct->bmi.biCompression,
                      pVidStruct->lPitch,
                      &size);
    }

    // If our last lock was not using overlay, use our offscreen blt
    if (m_bScratchSurface)
    {
        if (!m_fallbackSurface.dd.lpDDSurface)
            goto FAILURE;

        pItem->nBltMode = HX_BLT_YUV_STRETCH;
        pItem->pAlphaList = pVidStruct->pAlphaList;

        ResetEvent(m_hFallbackEmpty);
    }
    // Our last lock was using gdi
    else if (m_bGDISurface)
    {
        pItem->nBltMode = HX_BASIC_BLT;
        pItem->pAlphaList = pVidStruct->pAlphaList;
        pItem->nIndex = m_nNextGdiSurface;
    }
    else
    {
        // Advance the overlay surface list
        int nNewIndex = nIndex;

        if (!m_surface.dd.lpDDSurface)
            goto FAILURE;

        CWinBaseRootSurface *pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();

        if (!pSurface)
            goto FAILURE;

        WINDRAW *pWindraw = pSurface->GetWinDraw();

        if (HXR_OK != WinDraw_AdvanceSurface (pWindraw, &m_surface, nNewIndex))
            goto FAILURE;

        pItem->nIndex = nNewIndex;
        pItem->nBltMode = HX_OVERLAY_BLT;
    }
    
    // Increase the mutex lock count so another thread does not lock
    // it before we queue this frame or prevent us from drawing immediately.
    WaitForSingleObject(m_hSurfaceMutex, INFINITE);

    // We delete the alphalist in DisplayFrame in yuv_stretch mode.
    ReleaseSurface(pVidStruct, FALSE, (pItem->nBltMode!=HX_BLT_YUV_STRETCH));

    // Immediate display...don't queue
    if (ulFlags & HX_MODE_IMMEDIATE)
    {
        HRESULT hr;
        tFrameElement lastItem;

        for (int i=0; i<5; i++)
        {
            pItem->dwDDFlags = DDFLIP_WAIT;

            lastItem = *pItem;
            hr = DisplayFrame(pItem);

            // Need to try again
            if (DDERR_WASSTILLDRAWING == hr)
            {
                *pItem = lastItem;
                WaitForSingleObject(m_hAbort, 10);
            }
            // Probably can not async flip, so turn it off
            else if (DDERR_INVALIDPARAMS == hr && m_bUseVBlankFlip)
            {
                *pItem = lastItem;
                m_bUseVBlankFlip = FALSE;
            }
            else
            {
                // Abort this overaly surface on a failure
                if (DD_OK != hr && pItem->nBltMode == HX_OVERLAY_BLT)
                {
                    CWinBaseRootSurface *pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
                    if (!pSurface)
                        goto FAILURE;

                    WINDRAW *pWindraw = pSurface->GetWinDraw();
                
                    WinDraw_DisplaySurface(pWindraw, &m_surface, pItem->dwDDFlags, pItem->nIndex, TRUE);
                }
                
                break;
            }
        } 

        ReleaseMutex(m_hSurfaceMutex);
        delete pItem;
        
#if !defined(_GOLD) && 0
        m_TimeStamps.AddSample();
#endif
        return HXR_OK;
    }

    EnterCriticalSection(&m_csList);
    m_pListOfFrames->AddTail((void*)pItem);
    LeaveCriticalSection(&m_csList);

    ReleaseSemaphore(m_hFrameSem, 1, NULL);
    ReleaseMutex(m_hSurfaceMutex);

#if !defined(_GOLD) && 0
    m_TimeStamps.AddSample();
#endif
    return HXR_OK;

  FAILURE:
    delete pItem;

    return HXR_FAIL;

}

STDMETHODIMP_(void) CWinSurface2::Flush()
{
    m_bFlushing = TRUE;

    //This needs to be before the wait on m_hSurfaceMutex because if
    //you hit stop before we start blt'ing frames you could be waiting
    //a long time before it wakes up. At least in the case for live
    //streams where we don't have the server/ff seek back to the
    //nearest keyframe and send data. Some streams have keyframes
    //every 10seconds or so.
    PulseEvent(m_hAbort);

    WaitForSingleObject(m_hSurfaceMutex, INFINITE);
 
    CWinBaseRootSurface *pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
    WINDRAW *pWindraw = pSurface->GetWinDraw();
    
    // Cancel and pending frames
    WinDraw_CacelPendingDisplay (pWindraw, &m_surface);
    PulseEvent(m_hForceRender);

    Sleep(5);

    // Wait until our queue count reaches 0
    int nCount = m_pListOfFrames->GetCount();

    while (nCount)
    {
        WinDraw_CacelPendingDisplay (pWindraw, &m_surface);
        PulseEvent(m_hAbort);
        PulseEvent(m_hForceRender);

        Sleep(5);

        nCount = m_pListOfFrames->GetCount();
    }
    
    ResetBufferTimes(0);
    ReleaseMutex(m_hSurfaceMutex);

    m_bFlushing = FALSE;
}

void CWinSurface2::ResetBufferTimes(INT32 nTime)
{
    // Reset all buffer times
    if (m_surface.dwBackBufferCount)
    {
        for (UINT32 i=0; i<m_surface.dwBackBufferCount+1; i++)
            m_surface.dd.lpChain[i].dTimeAvailable = nTime;
    }
}

STDMETHODIMP CWinSurface2::PresentIfReady()
{
    HX_RESULT hr = E_FAIL;

    if (!m_pTimeLine | m_bIngnorePresentIfReady)
        return hr;

    UINT32 ulTime = 0;
    if (HXR_TIMELINE_SUSPENDED != m_pTimeLine->GetTimeLineValue(ulTime))
    {
        if (((m_nLastDisplayTime > 0) && (m_nLastDisplayTime - (INT32)ulTime < 0)))
        {
            #ifdef LOG_JITTER_DATA
            FILE *fp = fopen(JITTER_LOG_FILE, "a+");
            if (fp)
            {
                fprintf(fp, "PresentIfReady Interrupt clock %ld last display %ld\n", ulTime, m_nLastDisplayTime);
                fclose(fp);
            }

            #endif
            
            PulseEvent(m_hForceRender);
            Sleep(0);

#ifdef _DEBUG
            //OutputDebugString("PresentIfReady Interrupt\n");
#endif

            hr = HXR_OK;
        }
    }
    
    return hr;
}

HX_RESULT CWinSurface2::DisplayFrame(tFrameElement* pItem)
{
    HRESULT hr = HXR_OK,
            hrTimeLine = HXR_OK;
    HXxSize rcSize = {0,0};

    int     nNumRects   = 0;
    BOOL    bSub1x = FALSE;

    m_pSite->_TLSLock(); 

    CWinBaseRootSurface *pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();

    if (!pSurface)
    {
        m_pSite->_TLSUnlock(); 
        return HXR_FAIL;
    }

    WINDRAW *pWindraw = pSurface->GetWinDraw();

    // Ensure our site is visible before displaying
    BOOL    bVisibleSite = (!HXEmptyRegion(m_pSite->m_Region)|| pItem->count || pItem->bAlpha)
                           && m_pSite->IsSiteVisible()
                           && !m_pSite->_FadeTransitionActive();

    if (pItem->nBltMode == HX_OVERLAY_BLT)
    {
        // If no src rect is specified, use surface
        if (!pItem->rcSrc.right && !pItem->rcSrc.bottom)
        {
            pItem->rcSrc.right = m_surfaceSize.cx;
            pItem->rcSrc.bottom = m_surfaceSize.cy;
        }

        // Put the frame on the screen
        int nIndex = pItem->nIndex-1;
        if (nIndex < 0)
            nIndex = m_nBackBufferCount;

        if (pItem->dwDDFlags & DDFLIP_WAIT == DDFLIP_WAIT)
        {
            // Immediate mode blits have no calculated timaAvailable; use 
            // the current time:
            pItem->dTimeAvailable = GetMSTickDouble32();
        }

        m_surface.dd.lpChain[nIndex].dTimeAvailable = pItem->dTimeAvailable;
        m_surface.dd.lpChain[pItem->nIndex].dTimeAvailable = 0;

        hr = WinDraw_DisplaySurface(pWindraw, &m_surface, pItem->dwDDFlags, pItem->nIndex, m_bFlushing);

#ifdef LOG_JITTER_DATA
        UINT32 ulTimeAfter = 0;
        m_pTimeLine->GetTimeLineValue(ulTimeAfter);

        FILE *fp = fopen(JITTER_LOG_FILE, "a+");
        if (fp)
        {
            UINT32 dwScanLine = 0;
            WinDraw2_GetScanLine(pWindraw, &dwScanLine);
        
            fprintf(fp, "Calling flip: scan line %ld clock after %ld ts %ld jitter %ld\n\n", dwScanLine, ulTimeAfter, pItem->lTimeStamp, (INT32)(pItem->lTimeStamp-ulTimeAfter));
            fclose(fp);
        }
#endif //LOG_JITTER_DATA

        if (DD_OK == hr && bVisibleSite)
        {
            m_nLastBltMode = HX_OVERLAY_BLT;

            // Make sure we are painting colorkey in fullscreen mode.
            // We will fix this when fillcolor key is fixed.
            if (m_pSite->m_pTopLevelSite &&
                m_pSite->m_pTopLevelSite->m_bInFullScreen)
            {
                if (++m_ulFillColoryKeyCount < 15)
                    memset(&m_rcLast, 0, sizeof(m_rcLast));
            }
            else
                m_ulFillColoryKeyCount = 0;

            if (!IsShrinking() || _AllowsOverlayShrinking())
            {
          

⌨️ 快捷键说明

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