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

📄 winsurf2.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
void CWinSurface2::_CreateBuffer()
{
    if (m_hRenThread)
    {
        WaitForSingleObject(m_hSurfaceMutex, INFINITE);
        EnterCriticalSection(&m_csDisplay);
    }
   
    CWinSurface::_CreateBuffer();
    BOOL bCreated = FALSE;
    
    if (m_surface.fMode & WINDRAW_DIRECTDRAW)
    {
        bCreated = (m_surface.dd.lpDDSurface != NULL);
    }
    else
    {
        bCreated = (m_surface.gdi.lpGDIBackBuffer[0] != NULL);
    }

    if (bCreated)
    {
        if (m_hRenThread)
        {
            // We create our surface, start servicing GetVidMem calls
            SetEvent(m_hReinit);
        }
    }

    if (m_hRenThread)
    {
        ReleaseMutex(m_hSurfaceMutex);
        LeaveCriticalSection(&m_csDisplay);
    }

}

HX_RESULT CWinSurface2::_CreateOverlay(BOOL bOverlay, int cid, int x, int y)
{
    if (m_hRenThread)
    {
        WaitForSingleObject(m_hSurfaceMutex, INFINITE);
        EnterCriticalSection(&m_csDisplay);
    }

    HX_RESULT hr = CWinSurface::_CreateOverlay(bOverlay, cid, x, y);

    if (HXR_OK == hr && m_hRenThread)
    {
        // We created our surface, start servicing GetVidMem calls
        SetEvent(m_hReinit);
    }

    if (m_hRenThread)
    {
        LeaveCriticalSection(&m_csDisplay);
        ReleaseMutex(m_hSurfaceMutex);
    }
        
    return hr;
}

HX_RESULT 
CWinSurface2::ByPassCompositionSurface(UCHAR*               pImageData,
                                       HXBitmapInfoHeader* pBitmapInfo,
                                       REF(HXxRect)         rDestRect,
                                       REF(HXxRect)         rSrcRect,
                                       UCHAR*               pSurface,
                                       INT32                nSurfPitch)
                                                 
{
    // Check for vidsurf2-only dest surfaces
    if (CID_I420 == GETBITMAPCOLOR( pBitmapInfo) &&
        m_pHwMemObj)
    {
        HXxSize srcSize = {pBitmapInfo->biWidth, pBitmapInfo->biHeight};
    
        UCHAR* pYUV[3] = {pImageData,
                          pYUV[0] + pBitmapInfo->biHeight*nSurfPitch,
                          pYUV[1] + pBitmapInfo->biHeight*nSurfPitch/4};
        INT32 nYUVPitch[3] = {nSurfPitch, nSurfPitch/2, nSurfPitch/2};

        SourceInputStruct input = {pYUV, nYUVPitch, 3};

        INT32 nPitch;
        UCHAR* pVidMem = 
         (UCHAR*)m_pHwMemObj->DeviceToRenderer(pImageData,
                                               nPitch,
                                               WRITE_VIDEO_TO_STRUCT);
        
        AlignRect(&rSrcRect, pBitmapInfo->biWidth, pBitmapInfo->biHeight);
        AlignRect(&rDestRect, m_surfaceSize.cx, m_surfaceSize.cy);

        HX_RESULT hr =  
            ColorConvert(MapCIDtoFourCC(GETBITMAPCOLOR(pBitmapInfo)),
                         &srcSize, &rSrcRect,
                         &input, MapCIDtoFourCC(m_nSurfaceCID), pVidMem,
                         &m_surfaceSize, &rDestRect, nSurfPitch);

        m_pHwMemObj->RendererToDevice(pVidMem);

        return hr;
    }

    return CWinSurface::ByPassCompositionSurface(pImageData,
                                                 pBitmapInfo,
                                                 rDestRect,
                                                 rSrcRect,
                                                 pSurface,
                                                 nSurfPitch);


}

void CWinSurface2::_ReleaseSurface(CBaseRootSurface* pSurface)
{
    if (m_hRenThread)
    {
        Flush();

        // Make the next GetVidMem wait on new surface creation
        WaitForSingleObject(m_hSurfaceMutex, INFINITE);

        ResetEvent(m_hReinit);

        Flush();
        EnterCriticalSection(&m_csDisplay);
    }

    WINDRAW* pWindraw = ((CWinBaseRootSurface*)pSurface)->GetWinDraw();
    DestroyFallbackSurface();
    DestroyGdiSurface();
    
    CWinSurface::_ReleaseSurface(pSurface);

    memset(&m_lastSrcRect, 0, sizeof(m_lastSrcRect));

    if (m_hRenThread)
    {
        LeaveCriticalSection(&m_csDisplay);
        ReleaseMutex(m_hSurfaceMutex);
    }

    m_dLastXScale = 0.0;
    m_dLastYScale = 0.0;
}

void CWinSurface2::_ReleaseSurface(CWinBaseRootSurface* pSurface)
{
    if (m_hRenThread)
    {
        Flush();

        // Make the next GetVidMem wait on new surface creation
        WaitForSingleObject(m_hSurfaceMutex, INFINITE);
        ResetEvent(m_hReinit);
      
        Flush();
        EnterCriticalSection(&m_csDisplay);
    }

    WINDRAW* pWindraw = pSurface->GetWinDraw();
    DestroyFallbackSurface();
    DestroyGdiSurface();
    
    CWinSurface::_ReleaseSurface(pSurface);


    memset(&m_lastSrcRect, 0, sizeof(m_lastSrcRect));

    if (m_hRenThread)
    {
        LeaveCriticalSection(&m_csDisplay);
        ReleaseMutex(m_hSurfaceMutex);
    }

    m_dLastXScale = 0.0;
    m_dLastYScale = 0.0;
}

void CWinSurface2::_ReleaseSurface()
{
    if (m_hRenThread)
    {
        Flush();

        // Make the next GetVidMem wait on new surface creation
        WaitForSingleObject(m_hSurfaceMutex, INFINITE);
        ResetEvent(m_hReinit);
      
        Flush();
        EnterCriticalSection(&m_csDisplay);
    }
   
    CWinBaseRootSurface* pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
    if (pSurface)
    {
        WINDRAW* pWindraw = pSurface->GetWinDraw();
        if (pWindraw)
        {
            DestroyFallbackSurface();
            DestroyGdiSurface();
            memset(&m_lastSrcRect, 0, sizeof(m_lastSrcRect));

            CWinSurface::_ReleaseSurface();
        }
    }

    if (m_hRenThread)
    {
        LeaveCriticalSection(&m_csDisplay);
        ReleaseMutex(m_hSurfaceMutex);
    }

    m_dLastXScale = 0.0;
    m_dLastYScale = 0.0;
}

void CWinSurface2::ReInitSurfaces()
{
    if ( (m_surface.fMode & WINDRAW_DIRECTDRAW) &&  m_surface.dd.lpDDSurface && m_bVideoSurface2)
    {
        return;
    }

    // Set yuv priority for vidsurf2 mode
    if (m_hRenThread)
    {
        // Lock the surface mutex
        WaitForSingleObject(m_hSurfaceMutex, INFINITE);
        
        m_pSite->_TLSLock();

        int cid = GetBitmapColor((LPBITMAPINFO)m_pOptimizedFormat);
        BOOL bRestore = SetYUVPriorityList(cid);

        m_nBackBufferCount = m_nOverlayBackBuffersCreated;

        CWinSurface::ReInitSurfaces();

        if (bRestore)
            RestoreColorspacePriorities(cid);

        // We switched to a mode that does not support overlay...yikes!
        if (m_bVideoSurface2 &&
            (m_nBltMode != HX_OVERLAY_BLT || !m_nBackBufferCount))
        {
            m_bMultipleOverlay = TRUE;
            ForceGDIMode(TRUE);
        }
        else
        {
            m_bMultipleOverlay = FALSE;
        }
        
        HXxSize rcSize = m_surfaceSize;
        CreateFallbackSurface(m_nSurfaceCID, &rcSize);

        m_pSite->_TLSUnlock();

        ResetBufferTimes(0);
        ReleaseMutex(m_hSurfaceMutex);

    }
    else
        CWinSurface::ReInitSurfaces();
}

BOOL CWinSurface2::_IsDisplaySurfaceYuv()
{
    if (!m_bVideoSurface2)
        return CWinSurface::_IsDisplaySurfaceYuv();

    return IsYUV(MapFourCCtoCID(m_bmi.biCompression));
}

BOOL CWinSurface2::_AllowsOverlayShrinking()
{
    if (m_bSurfaceRequiresOverlay)
        return TRUE;
    else
        return CWinSurface::_AllowsOverlayShrinking();
}

void CWinSurface2::_WaitForQueuedFrames()
{
    WaitForQueuedFrames();
}

void CWinSurface2::_LockBlitter()
{
    if (m_hSurfaceMutex)
    {
        // In the unlikely event that all of our hw buffers are
        // full AND GetVideoMem is blocking with m_hSurfaceMutex
        // while waiting for the time line to start, break
        // out of the time line wait loop.
        BOOL bOldValue = m_bWaitingForFlush;
        m_bWaitingForFlush = TRUE;

        WaitForSingleObject(m_hSurfaceMutex, INFINITE);
        
        m_bWaitingForFlush = bOldValue;
    }
}
void CWinSurface2::_UnlockBlitter()
{
    if (m_hSurfaceMutex)
        ReleaseMutex(m_hSurfaceMutex);
}

void CWinSurface2::_FlushSurfaces()
{
    Flush();
}

STDMETHODIMP CWinSurface2::SetProperties(HXBitmapInfoHeader* bmi,
                                        REF(UINT32) ulNumBuffers,
                                        IHXRenderTimeLine* pTimeLine)
{
    // Block GetVideoMem calls
    WaitForSingleObject(m_hSurfaceMutex, INFINITE);

    ulNumBuffers = min(m_nMaxBackBuffers+1, (INT32)ulNumBuffers);
      
    CWinBaseRootSurface* pSurface = (CWinBaseRootSurface*)m_pSite->GetRootSurface();
    if (!pSurface)
    {
        ReleaseMutex(m_hSurfaceMutex);
        return HXR_FAIL;
    }

    WINDRAW* pWindraw = pSurface->GetWinDraw();    
    
    // If we already have surfaces, destroy and recreate if necessary
    if (m_hRenThread)
    {
        if (bmi->biWidth != m_bmi.biWidth ||
            bmi->biHeight != m_bmi.biHeight ||
            m_surface.dwBackBufferCount == 0 ||
            ulNumBuffers != (UINT32)m_nBackBufferCount+1 ||
            WAIT_OBJECT_0 != WaitForSingleObject(m_hReinit, 0))
        {
            // Wait for display buffers to render
            if (HXR_OK != WaitForQueuedFrames())
                Flush();

            DestroySurfaces();

            m_nBackBufferCount = 0;
            memset(&m_bmi, 0, sizeof(m_bmi));
            memset(&m_lastSrcRect, 0, sizeof(m_lastSrcRect));
        }
        else
        {
            HX_RELEASE(m_pTimeLine);

            m_pTimeLine = pTimeLine;
            if (m_pTimeLine)
                m_pTimeLine->AddRef();
            
            m_bVideoSurface2 = TRUE;

            // If we are keeping our existing video buffers, reset
            // the flipping chain indexes if we have DirectDraw.
            if (!m_bLostHWAcceleration)
                WinDraw_ResetSurfaceIndexes(pWindraw, &m_surface);

            ReleaseMutex(m_hSurfaceMutex);
            return HXR_OK;
        }
    }
    
    // If we do not have a render thread and we have an optimized
    // format, we are in VS1 mode so fail the VS2 init.
    else if (m_pOptimizedFormat)
    {
        ReleaseMutex(m_hSurfaceMutex);
        return HXR_FAIL;
    }

    // Try and create an overlay flpping chain of pRequest->nNumBuffers buffers
    m_nBackBufferCount = ulNumBuffers - 1;

    if (m_nBackBufferCount)
        m_bFlipOverlay = TRUE;

    m_bSpamUpdateOverlay = FALSE;
    
    int cid = GetBitmapColor((LPBITMAPINFO)bmi);
    BOOL bRestore = SetYUVPriorityList(cid);

    BeginOptimizedBlt(bmi);
    int nBltMode = m_nBltMode;

    if (bRestore)
        RestoreColorspacePriorities(cid);

    if (nBltMode != HX_OVERLAY_BLT ||
        !m_nBackBufferCount)
    {
        DestroySurfaces();
        ulNumBuffers = 0;
        m_bVideoSurface2 = FALSE;
        
        ReleaseMutex(m_hSurfaceMutex);
        return HXR_FAIL;
    }

    m_nOverlayBackBuffersCreated = m_nBackBufferCount;
    bmi->biCompression = MapCIDtoFourCC(m_nSurfaceCID);

    // How odd, a dd driver that returns the wrong caps.
    // I have not seen anything like since the last time I tried
    // to use the caps.
    //
    // We will always try interval flips and swith to flip
    // waits if flip returns an error.

#if DIRECTDRAW_VERSION > 0x0500
    // Can we use the flip interval flag
    if ((pWindraw->dd.m_caps.dwCaps2 & DDCAPS2_FLIPINTERVAL) != DDCAPS2_FLIPINTERVAL)
    {
        m_bUseVBlankFlip = FALSE;
    }
#else
    m_bUseVBlankFlip = FALSE;

⌨️ 快捷键说明

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