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

📄 ddblt.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

#include "hxcom.h"
#include "hxtypes.h"
#include "hxwintyp.h"
#include "ddblt.h"

#ifdef __cplusplus
extern "C"
#endif

#if 0
static void MovePlain(
    UCHAR *srcPtr, int srcPitch, UCHAR *destPtr, int destPitch,
    int plainWidth, int plainHeight)
{
    register int i;

    for (i = 0; i < plainHeight; i ++)
    {
        /* must be done using MMX movqs,
         * but this is a simple test app, not a production code: */
        memcpy(destPtr, srcPtr, plainWidth); /* Flawfinder: ignore */
        srcPtr += srcPitch;
        destPtr += destPitch;
    }
}

#endif //0

CDDBlt::CDDBlt()
 :  CWinBlt()
 ,  m_pDD(NULL)
 ,  m_pPrimary(NULL)
 ,  m_pOffscreen(NULL)

{
}

CDDBlt::~CDDBlt()
{
    DestroySurface(0);
}

HX_RESULT CDDBlt::CreateSurface(int cidIn, int& cidOut,
                                int nWidth, int nHeight,
                                int nFlags, HWND hWnd,
                                int nCountIn, int& nCountOut)
{
    HRESULT hr;

    if (!m_pDD)
    {
        hr = DirectDrawCreate(NULL, &m_pDD, NULL);
        if (hr)
            return HXR_FAIL;
    }

    IDirectDraw2 *pDD2 = NULL;
    hr = m_pDD->QueryInterface(IID_IDirectDraw2, (void **)&pDD2);

    if (!pDD2)
    {
	HX_RELEASE(m_pDD);
	return HXR_FAIL;
    }

    m_hWnd = hWnd;
    hr = pDD2->SetCooperativeLevel(hWnd, DDSCL_NORMAL);

    if (!m_pPrimary)
    {
	// Create primary surface
	DDSURFACEDESC ddsd;
	ZeroMemory(&ddsd, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS;
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    
	pDD2->CreateSurface (&ddsd, &m_pPrimary, NULL);

	if (!m_pPrimary)
	{
	    HX_RELEASE(m_pDD);
	    HX_RELEASE(pDD2);
	    return HXR_FAIL;
	}

	IDirectDrawClipper *pDDclip;
	if (DD_OK == pDD2->CreateClipper(0, &pDDclip, NULL))
	{
	    pDDclip->SetHWnd(0, m_hWnd);
	    m_pPrimary->SetClipper(pDDclip);
	    HX_RELEASE(pDDclip);
	}
    }

    // Create offscreen surface
    DDSURFACEDESC ddsd;
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; 
    ddsd.dwWidth = nWidth;
    ddsd.dwHeight = nHeight;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;

    ddsd.dwFlags |= DDSD_PIXELFORMAT;
    ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);

    const int nOutputFormats = 6;
    UINT32 fourCC[nOutputFormats];
    UINT32 bbp[nOutputFormats];
    UINT32 rbm[nOutputFormats];
    UINT32 gbm[nOutputFormats];
    UINT32 bbm[nOutputFormats];
    UINT32 flags[nOutputFormats];
    int    cid[nOutputFormats];

    memset(&rbm, 0, sizeof(rbm));
    memset(&gbm, 0, sizeof(gbm));
    memset(&bbm, 0, sizeof(bbm));
    memset(&flags, 0, sizeof(flags));

    int nOutputTypes = 0;

#if defined (HELIX_FEATURE_CC_I420out)
    fourCC[nOutputTypes] = MAKEFOURCC('I', '4', '2', '0');
    bbp[nOutputTypes] = 12;
    cid[nOutputTypes] = CID_I420;
    flags[nOutputTypes] = DDPF_FOURCC;

    ++nOutputTypes;
#endif //HELIX_FEATURE_CC_I420out

#if defined (HELIX_FEATURE_CC_YV12out)
    fourCC[nOutputTypes] = MAKEFOURCC('Y', 'V', '1', '2');
    bbp[nOutputTypes] = 12;
    cid[nOutputTypes] = CID_YV12;
    flags[nOutputTypes] = DDPF_FOURCC;

    ++nOutputTypes;
#endif //HELIX_FEATURE_CC_YV12out

#if defined (HELIX_FEATURE_CC_YUY2out)
    fourCC[nOutputTypes] = MAKEFOURCC('Y', 'U', 'Y', '2');
    bbp[nOutputTypes] = 16;
    cid[nOutputTypes] = CID_YUY2;
    flags[nOutputTypes] = DDPF_FOURCC;

    ++nOutputTypes;
#endif //HELIX_FEATURE_CC_YUY2out

#if defined (HELIX_FEATURE_CC_UYVYout)
    fourCC[nOutputTypes] = MAKEFOURCC('U', 'Y', 'V', 'Y');
    bbp[nOutputTypes] = 16;
    cid[nOutputTypes] = CID_UYVY;
    flags[nOutputTypes] = DDPF_FOURCC;

    ++nOutputTypes;
#endif //HELIX_FEATURE_CC_UYVYout

#if defined (HELIX_FEATURE_CC_RGB32out)
    fourCC[nOutputTypes] = BI_RGB;
    bbp[nOutputTypes] = 32;
    cid[nOutputTypes] = CID_RGB32;

    rbm[nOutputTypes] = 0xFF0000;
    gbm[nOutputTypes] = 0x00FF00;
    bbm[nOutputTypes] = 0x0000FF;
    flags[nOutputTypes] = DDPF_RGB;

    ++nOutputTypes;
#endif //HELIX_FEATURE_CC_RGB32out

#if defined (HELIX_FEATURE_CC_RGB565out)
    fourCC[nOutputTypes] = BI_RGB;
    bbp[nOutputTypes] = 16;
    cid[nOutputTypes] = CID_RGB565;

    rbm[nOutputTypes] = 0x7C00;
    gbm[nOutputTypes] = 0x03E0;
    bbm[nOutputTypes] = 0x001F;
    flags[nOutputTypes] = DDPF_RGB;

    ++nOutputTypes;
#endif //HELIX_FEATURE_CC_RGB565out



    for (int i=0; i<nOutputTypes; i++)
    {
        ddsd.ddpfPixelFormat.dwFourCC       = fourCC[i];
        ddsd.ddpfPixelFormat.dwRGBBitCount  = bbp[i];                                                                   
        ddsd.ddpfPixelFormat.dwRBitMask     = rbm[i];
        ddsd.ddpfPixelFormat.dwGBitMask     = gbm[i];
        ddsd.ddpfPixelFormat.dwBBitMask     = bbm[i];
        ddsd.ddpfPixelFormat.dwFlags        = flags[i];                                                                

        if (DD_OK == pDD2->CreateSurface (&ddsd, &m_pOffscreen, NULL))
        {
            m_nCID = cid[i];
            break;
        }
    }
    
    pDD2->Release();

    // Don't use DirectDraw
    if (!m_pOffscreen)
    {
        HX_RELEASE(m_pPrimary);                  
        HX_RELEASE(m_pDD);
	
        return HXR_FAIL;
    }

    return HXR_OK;
}

HX_RESULT CDDBlt::LockSurface(UCHAR** ppDestPtr,
                              LONG32* pnDestPitch,
                              int& cid,
                              REF(HXxSize) dstSize,
                              int nIndex)
{
    DDSURFACEDESC ddsd;
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);

    HRESULT hr;
    for (int i=0; i<3; i++)
    {
	hr = m_pOffscreen->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
	
        if (DDERR_SURFACELOST == hr)
	{
	    m_pOffscreen->Restore();
	    m_pPrimary->Restore();
	}
	else if (DD_OK == hr)
	{
	    *ppDestPtr = (UCHAR*)ddsd.lpSurface;
	    *pnDestPitch = ddsd.lPitch;

	    break;
	}
	else
	{
	    return HXR_FAIL;
	}
    }
    
    return HXR_OK;
}

HX_RESULT CDDBlt::FillSurface(int cidIn,
                              UCHAR* pSrcBuffer,
                              HXxSize* pSrcSize,
                              HXxRect* prSrcRect,
                              UCHAR* pDstBuffer,
                              LONG32 nDstPitch,
                              HXxRect* prDestRect)
{
#if 1
    return HXR_FAIL;

#else
    // If input and output are both planar, just copy each plane
    if (CID_YV12 != m_nCID || 
        (cidIn != CID_I420 && cidIn != CID_XING))
        return HXR_FAIL;

    INT32 yPitch = pSrcSize->cx;
    INT32 uvPitch = pSrcSize->cx/2;
    UCHAR *pU = pSrcBuffer + pSrcSize->cy*yPitch;
    UCHAR *pV = pU + pSrcSize->cy/2*uvPitch;

    if (cidIn == CID_XING)
    {
        yPitch = 768;
        uvPitch = 768;
        pU = pSrcBuffer + pSrcSize->cy*yPitch;
        pV = pU + yPitch/2;
    }
    
    // We only support YV12
    UCHAR *pDestV = pDstBuffer + pSrcSize->cy*nDstPitch;
    UCHAR *pDestU = pDestV + pSrcSize->cy*nDstPitch/4;

    MovePlain(pSrcBuffer, yPitch, pDstBuffer, nDstPitch,
              pSrcSize->cx,pSrcSize->cy);

    MovePlain(pU, uvPitch, pDestU, nDstPitch/2,
              pSrcSize->cx/2,pSrcSize->cy/2);

    MovePlain(pV, uvPitch, pDestV, nDstPitch/2,
              pSrcSize->cx/2,pSrcSize->cy/2);
    
#endif //1
    return HXR_OK;
}

HX_RESULT CDDBlt::UnlockSurface(UCHAR* pSurfPtr, int nIndex)
{
    m_pOffscreen->Unlock(NULL);
    return HXR_OK;
}

HX_RESULT CDDBlt::RenderSurface(HXxSize* pSrcSize,
                                HXxRect* prSrcRect,
                                HXxRect* prDestRect,
                                int nIndex)
{
    // Map to screen coordinates
    POINT   po = {0,0};
    ClientToScreen(m_hWnd, &po);
    
    RECT rc;
    GetClientRect(m_hWnd, &rc);
    
    rc.left += po.x;
    rc.right += po.x;
    rc.top += po.y;
    rc.bottom += po.y;
    
    DDBLTFX ddbltfx;
    memset(&ddbltfx, 0, sizeof(ddbltfx));
    ddbltfx.dwSize = sizeof(ddbltfx);
    ddbltfx.dwDDFX = DDBLTFX_NOTEARING; 
    HRESULT hr = m_pPrimary->Blt(&rc, m_pOffscreen, NULL, DDBLT_WAIT, &ddbltfx);

    if (DD_OK == hr)
        return HXR_OK;
    else
        return HXR_FAIL;
}

HX_RESULT CDDBlt::DestroySurface(int cid)
{
    HX_RELEASE(m_pPrimary);
    HX_RELEASE(m_pOffscreen);
    HX_RELEASE(m_pDD);
    
    return HXR_OK;
}

⌨️ 快捷键说明

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