📄 baseroot.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: baseroot.cpp,v 1.6.4.2 2004/07/26 10:27:16 pankajgupta Exp $ * * Portions Copyright (c) 1995-2004 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 (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (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. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * 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 "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_FILEstatic 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_BUGCBaseRootSurface::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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -