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

📄 winsurf2.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    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())            {                // Restore overlay                if (HX_OVERLAY_BLT != m_nBltMode)                {                    ForceGDIMode(FALSE);                }                // If no src rect is specified, use surface                if (!pItem->rcDst.right && !pItem->rcDst.bottom)                {                    m_pSite->GetSize(rcSize);                    pItem->rcDst.right = rcSize.cx;                    pItem->rcDst.bottom = rcSize.cy;                }                SetLastScale(&pItem->rcSrc, &pItem->rcDst);                double dScaleX = m_scaleFactorX,                       dScaleY = m_scaleFactorY;                // Setup new src and dest rects....                _ConstructRects( pItem->rcSrc,                                 pItem->rcDst,                                 FALSE,                                 nNumRects,                                 &m_paSrcRects,                                 &m_paDestRects);                if (nNumRects != 1)                {                    HXxPoint screenOffset = m_pSite->GetScreenOffset();                    if (!m_paSrcRects)                        m_paSrcRects = (HXxRect*)malloc(sizeof(HXxRect));                    if (!m_paDestRects)                        m_paDestRects = (HXxRect*)malloc(sizeof(HXxRect));;                    m_paSrcRects[0] = pItem->rcSrc;                    m_paDestRects[0] = pItem->rcDst;                    m_paSrcRects[0].left += screenOffset.x;                    m_paSrcRects[0].top += screenOffset.y;                    m_paSrcRects[0].right += screenOffset.x;                    m_paSrcRects[0].bottom += screenOffset.y;                }                if (m_paSrcRects && m_paDestRects)                {                    ForceUpdateOverlay(&m_paDestRects[0], &m_paSrcRects[0], HX_OVER_SHOW|HX_OVER_KEYDEST, TRUE);                }                if (m_bNeedColorKeyFilled)                {                    m_bDisableFillColorKey = FALSE;                    _FillColorKey();                }                // Alpha blended images are drawn before the video so the scaling gets messed up on                // static images.  Force a redraw to correct the problem.                if ((dScaleX != m_scaleFactorX || dScaleY != m_scaleFactorY) && m_pSite->IsFullScreen())

⌨️ 快捷键说明

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