📄 baseroot.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 "hxmtypes.h"
#include "hxwintyp.h"
#include "hxvsurf.h"
#include "hxslist.h"
#include "hxthread.h"
#if defined(_WINDOWS)
#include "winroot.h" // must be included before colormap.h
#endif
#include "baseroot.h"
#include "coloracc.h"
#include "colormap.h"
//XXXgfw just to cletbiean up the code. We still *REALLY* need to clean
//this up.
#ifdef _WIN32
#define GETBITMAPCOLOR(x) GetBitmapColor( (LPBITMAPINFO)(x) )
#else
#define GETBITMAPCOLOR(x) GetBitmapColor( (HXBitmapInfo*)(x))
#endif
#ifdef _WIN32
#define GETBITMAPPITCH(x) GetBitmapPitch( (LPBITMAPINFO)(x) )
#else
#define GETBITMAPPITCH(x) GetBitmapPitch( (HXBitmapInfo*)(x))
#endif
#include "basesurf.h"
#include "basesite.h"
#include "hxprefs.h"
#include "hxtick.h"
#if defined(_UNIX) && !defined(_MAC_UNIX)
# include "unixroot.h"
#endif
#if defined(_MACINTOSH) || defined(_MAC_UNIX)
#include "platform/mac/macroot.h"
#endif
#include "sitefact.h"
#if defined(HELIX_FEATURE_PREFERENCES)
#include "hxprefs.h"
#include "hxprefutil.h"
#endif /* HELIX_FEATURE_PREFERENCES */
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
#define RED 0x00ff0000
#define GREEN 0x0000ff00
#define BLUE 0x000000ff
//#define _CHECK_CONVERSION_DATA
//#define _WORKAROUND_YUV_RGB_16BIT_HXCOLOR_BUG
CBaseRootSurface::CBaseRootSurface(IUnknown* pContext, CHXBaseSite* pSite)
: m_lRefCount(0)
, m_pContext(pContext)
, m_pSite(pSite)
, m_fSurfaceType(0)
, m_pMutex(NULL)
, m_pCompMutex(NULL)
, m_nBLTMode(0)
, m_pCompositionSurface(NULL)
, m_bCompositionSurfaceCreated(FALSE)
#ifdef _WINDOWS
, m_pPlayer(NULL)
#endif
, m_bUseCardMemory(FALSE)
, m_pUnlockingSite(NULL)
, zm_pColorAcc(NULL)
{
#ifdef _BLT_IN_DEBUG
m_nBLTMode = HX_WINDOWLESS_DEBUG;
#else
m_nBLTMode = HX_WINDOWLESS_MINIMAL;
#endif
HX_ASSERT( m_pContext );
HX_ASSERT( m_pSite );
m_pContext->AddRef();
m_pSite->AddRef();
#if defined(THREADS_SUPPORTED) || defined(_UNIX_THREADS_SUPPORTED)
HXMutex::MakeMutex(m_pMutex);
HXMutex::MakeMutex(m_pCompMutex);
#else
HXMutex::MakeStubMutex(m_pMutex);
HXMutex::MakeStubMutex(m_pCompMutex);
#endif
CreateColorAccess(pContext);
zm_pColorAcc->InitColorConverter();
/*
* Determine what level of Video 'Acceleration' we want to use.
*/
// XXXAH we will want to unify all of the OSes to use the same value.
// Something like VideoAcceleration or something.
// For now ... "Don't break windows" (tm).
BOOL bUseWindraw = TRUE;
IHXPreferences* pPreferences = NULL;
IHXBuffer* pBuffer = NULL;
if (HXR_OK == m_pContext->QueryInterface(IID_IHXPreferences,(void**)&pPreferences))
{
ReadPrefBOOL(pPreferences, "UseWinDraw", bUseWindraw);
ReadPrefBOOL(pPreferences, "UseCardMemory", m_bUseCardMemory);
HX_RELEASE(pBuffer);
}
HX_RELEASE(pPreferences);
if (bUseWindraw)
{
m_fSurfaceType = HX_ACCELERATION_ON;
if (m_bUseCardMemory)
{
m_fSurfaceType |= HX_USE_VIDEO_MEMORY;
}
else
{
m_fSurfaceType |= HX_USE_SYSTEM_MEMORY;
}
}
m_boundsRect.left = 65536;
m_boundsRect.top = 65536;
m_boundsRect.right = 0;
m_boundsRect.bottom = 0;
}
CBaseRootSurface::~CBaseRootSurface()
{
/*
* Clean up the color access functions
*/
HX_DELETE(zm_pColorAcc);
#ifdef _WINDOWS
HX_RELEASE(m_pPlayer);
#endif
HX_DELETE(m_pMutex);
HX_DELETE(m_pCompMutex);
HX_RELEASE(m_pContext);
HX_RELEASE(m_pSite);
while(m_pBltRects.GetCount())
{
HXxRect* pRect = (HXxRect*) m_pBltRects.RemoveHead();
HX_DELETE(pRect);
}
}
/************************************************************************
* Method:
* IUnknown::QueryInterface
*/
STDMETHODIMP CBaseRootSurface::QueryInterface(REFIID riid, void** ppvObj)
{
if (IsEqualIID(riid, IID_IUnknown))
{
AddRef();
*ppvObj = (IUnknown*)(IHXVideoSurface*)this;
return HXR_OK;
}
*ppvObj = NULL;
return HXR_NOINTERFACE;
}
/************************************************************************
* Method:
* IUnknown::AddRef
*/
STDMETHODIMP_(ULONG32)
CBaseRootSurface::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/************************************************************************
* Method:
* IUnknown::Release
*/
STDMETHODIMP_(ULONG32)
CBaseRootSurface::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
void CBaseRootSurface::BltComposition()
{
HXxRect rSrcRect;
rSrcRect.top = 0;
rSrcRect.left = 0;
rSrcRect.right = m_compositionSize.cx;
rSrcRect.bottom = m_compositionSize.cy;
//Blt the entire presentation.
m_boundsRect.right = m_compositionSize.cx;
m_boundsRect.bottom = m_compositionSize.cy;
m_boundsRect.left = 0;
m_boundsRect.top = 0;
if( IsCompositionEnabled() )
{
#if defined(_WINDOWS)
_MinimalUnlock(m_pSite->GetWindow());
#else
_MinimalBlt(rSrcRect, rSrcRect);
#endif
}
}
STDMETHODIMP CBaseRootSurface::Blt( UCHAR* pImageData,
HXBitmapInfoHeader* pBitmapInfo,
REF(HXxRect) rDestRect,
REF(HXxRect) rSrcRect,
CHXBaseSite* pSite)
{
HX_RESULT retVal = HXR_FAIL;
if( NULL == pImageData || NULL == pBitmapInfo )
return retVal;
switch (m_nBLTMode)
{
case HX_WINDOWLESS_DEBUG:
retVal = DebugBlt(pImageData, pBitmapInfo, rDestRect, rSrcRect);
break;
case HX_WINDOWLESS_MINIMAL:
retVal = MinimalBlt(pImageData, pBitmapInfo, rDestRect, rSrcRect, pSite);
break;
}
return retVal;
}
HX_RESULT CBaseRootSurface::DebugBlt( UCHAR* pImageData,
HXBitmapInfoHeader* pBitmapInfo,
REF(HXxRect) rDestRect,
REF(HXxRect) rSrcRect)
{
// Use OS services to draw solid boxes with outlines. Just to see
// what kind of freakiness is going on.
return _DebugBlt(pImageData, pBitmapInfo, rDestRect, rSrcRect);
}
HX_RESULT CBaseRootSurface::MinimalBlt( UCHAR* pImageData,
HXBitmapInfoHeader* pBitmapInfo,
REF(HXxRect) rDestRect,
REF(HXxRect) rSrcRect,
CHXBaseSite* pSite)
{
// color convert into the surface
HX_RESULT retVal = HXR_FAIL;
int cidIn = GETBITMAPCOLOR(pBitmapInfo);
int pitchIn = GETBITMAPPITCH(pBitmapInfo);
int nRet = 0;
#ifdef _WINDOWS
zm_pColorAcc->SetPlayer(GetPlayer());
#endif
BOOL bConverter = zm_pColorAcc->CheckColorConverter(cidIn, m_nCompositionSurfaceCID);
pSite->ColorConverterRequest(cidIn, m_nCompositionSurfaceCID, bConverter);
int dxDst = rDestRect.right - rDestRect.left;
int dyDst = rDestRect.bottom - rDestRect.top;
int dxSrc = rSrcRect.right - rSrcRect.left;
int dySrc = rSrcRect.bottom - rSrcRect.top;
//Please do not freak out the color converter!
if (dxSrc > pBitmapInfo->biWidth)
{
dxSrc = pBitmapInfo->biWidth;
}
if (dySrc > pBitmapInfo->biHeight)
{
dySrc = pBitmapInfo->biHeight;
}
//At this point I should be checking to see if the bitmap is going
//to be stretched. If so I should consider using Direct Draw to do
//the stretching.
//If our input is YUV and not I420 it is unlikely that we will have
//a color converter. So we will convert to I420 1st. Yeah, yeah, it
//blows. Big deal. For the moment we only look for an input in the
//form of YUY2, XING's format.
if(!bConverter)
{
UINT32 width, height;
_GetYUVScratchWidthHeight(&width, &height);
if (width != (UINT32) pBitmapInfo->biWidth || height != (UINT32) pBitmapInfo->biHeight)
{
_CreateYUVScratchSurface(pBitmapInfo->biWidth, pBitmapInfo->biHeight);
}
UCHAR* pYUVBits;
INT32 nYUVPitch;
_GetYUVScratchSurfacePointer(&pYUVBits, &nYUVPitch);
if (pYUVBits)
{
#ifdef _WINDOWS
zm_pColorAcc->SetPlayer(GetPlayer());
#endif
bConverter = zm_pColorAcc->CheckColorConverter(cidIn, 0);
pSite->ColorConverterRequest(cidIn, 0, bConverter);
if (bConverter)
{
nRet = zm_pColorAcc->ColorConvert(0, pYUVBits,
pBitmapInfo->biWidth, pBitmapInfo->biHeight,
nYUVPitch, 0, 0,
pBitmapInfo->biWidth, pBitmapInfo->biHeight,
cidIn, pImageData, pBitmapInfo->biWidth,
pBitmapInfo->biHeight, pitchIn,
0, 0, pBitmapInfo->biWidth, pBitmapInfo->biHeight);
if (nRet == -1)
{
retVal = HXR_FAIL;
bConverter = FALSE;
}
else
{
cidIn = 0;
pImageData = pYUVBits;
pitchIn = nYUVPitch;
bConverter = zm_pColorAcc->CheckColorConverter(cidIn, m_nCompositionSurfaceCID);
pSite->ColorConverterRequest(cidIn, m_nCompositionSurfaceCID, bConverter);
}
}
else
retVal = HXR_FAIL;
}
}
if (bConverter)
{
m_pSite->CheckColorSettings();
#ifdef _CHECK_CONVERSION_DATA
FILE* f1 = ::fopen("/tmp/ConversionData.txt", "a+"); /* Flawfinder: ignore */
::fprintf(f1, "ColorConversion (%d -> %d) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d %d)\n",
cidIn, m_nCompositionSurfaceCID, m_pCompositionSurface,
m_allocatedCompositionSize.cx, m_allocatedCompositionSize.cy,
m_nCompositionPitch, rDestRect.left, rDestRect.top,
dxDst, dyDst, pImageData, pBitmapInfo->biWidth,
pBitmapInfo->biHeight, pitchIn,
rSrcRect.left, rSrcRect.top, dxSrc, dySrc);
::fclose(f1);
#endif
int returnVal = E_FAIL;
if (returnVal!=NOERROR)
{
#ifdef _WORKAROUND_YUV_RGB_16BIT_HXCOLOR_BUG
/* working around a bug in the color convertor for strecth
* larger than doubel size for YUV to RGB 16 bit conversion */
// BOOL bUseScratch = HXDebugOptionEnabled("zUseScratch");
if (IsYUV(cidIn) && (rSrcRect.left || rSrcRect.top))
{
// The color converter does not like it when we are going
// from YUV->RGB with sub rects. To work around this we
// will convert THE WHOLE THING to RGB. Then we will use
// the RGB converter to select the portion that we
// want. BWHAHAHA!^ This sucks, HUGE.
HXxSize tempSize;
tempSize.cx = pBitmapInfo->biWidth;
tempSize.cy = pBitmapInfo->biHeight;
CreateScratchSurface(m_nCompositionSurfaceCID, &tempSize);
UCHAR* pScratchBits;
INT32 nScratchPitch;
ScratchLock(&pScratchBits, &nScratchPitch);
// if somehow scratch surface creation failed
if (!pScratchBits)
{
goto regularConvert;
}
returnVal = zm_pColorAcc->ColorConvert(
m_nCompositionSurfaceCID,
pScratchBits,
m_allocatedScratchSize.cx,
m_allocatedScratchSize.cy,
nScratchPitch, 0, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -