minisurf.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:16k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: minisurf.cpp,v 1.22.2.3 2004/07/09 01:59:28 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "minisite.h"
  50. #include "minisurf.h"
  51. #include "ciddefs.h"
  52. #if defined(HELIX_CONFIG_NOSTATICS)
  53. //On Symbian we don't use a colorconvert DLL. We compile in 
  54. //one and use slightly different color converter calls that
  55. //don't use static data.
  56. # include "nostatic/yuv.h" //for the color_data_t struct.
  57. # include "nostatic/colorlib.h" //for the new converters
  58. #else
  59. #include "colorlib.h"
  60. #endif
  61. #if defined(_UNIX) || defined(_MACINTOSH) || defined(_SYMBIAN) || defined(_OPENWAVE)
  62. #  ifndef MAKEFOURCC
  63. #define MAKEFOURCC(ch0, ch1, ch2, ch3) 
  64.                   ((ULONG32)(BYTE)(ch0) | ((ULONG32)(BYTE)(ch1) << 8) | 
  65.                   ((ULONG32)(BYTE)(ch2) << 16) | ((ULONG32)(BYTE)(ch3) << 24 ))
  66. #  endif //defined(MAKEFOURCC)
  67. #endif //_UNIX || _MACINTOSH
  68. CMiniBaseSurface::CMiniBaseSurface(IUnknown* pContext, CMiniBaseSite* pSite)
  69.     :  m_lRefCount(0)
  70.        ,  m_pContext(pContext)
  71.        ,  m_pSite(pSite)
  72.        ,  m_pOptimizedFormat(NULL)
  73.        ,  m_nSrcCID(CID_UNKNOWN)
  74.        ,  m_nDstBuffers(0)
  75.        ,  m_fpColorConverter(NULL)
  76.        ,  m_pImageHelper(NULL)
  77. {
  78.     memset(&m_dstBufSize, 0, sizeof(m_dstBufSize));
  79.     m_pContext->AddRef();
  80.     m_pImageHelper = new CFmtObj;
  81. }
  82. CMiniBaseSurface::~CMiniBaseSurface()
  83. {
  84.     HX_RELEASE(m_pContext);
  85.     HX_DELETE(m_pImageHelper);
  86.     HX_DELETE(m_pOptimizedFormat);
  87. }
  88. /************************************************************************
  89.  *  Method:
  90.  *    IUnknown::QueryInterface
  91.  */
  92. STDMETHODIMP CMiniBaseSurface::QueryInterface(REFIID riid, void** ppvObj)
  93. {
  94.     if (IsEqualIID(riid, IID_IHXVideoSurface))
  95.     {
  96.         AddRef();
  97.         *ppvObj = (IUnknown*)(IHXVideoSurface*)this;
  98.         return HXR_OK;
  99.     }
  100.     else if (IsEqualIID(riid, IID_IUnknown))
  101.     {
  102.         AddRef();
  103.         *ppvObj = (IUnknown*)(IHXSite*)this;
  104.         return HXR_OK;
  105.     }
  106.     *ppvObj = NULL;
  107.     return HXR_NOINTERFACE;
  108. }
  109. /************************************************************************
  110.  *  Method:
  111.  *    IUnknown::AddRef
  112.  */
  113. STDMETHODIMP_(ULONG32) CMiniBaseSurface::AddRef()
  114. {
  115.     return InterlockedIncrement(&m_lRefCount);
  116. }
  117. /************************************************************************
  118.  *  Method:
  119.  *    IUnknown::Release
  120.  */
  121. STDMETHODIMP_(ULONG32) CMiniBaseSurface::Release()
  122. {
  123.     if (InterlockedDecrement(&m_lRefCount) > 0)
  124.     {
  125.         return m_lRefCount;
  126.     }
  127.     delete this;
  128.     return 0;
  129. }
  130. inline
  131. IsCompatible(const HXBitmapInfoHeader* pLeft, const HXBitmapInfoHeader* pRight)
  132. {
  133.     //return (0 == memcmp(m_pOptimizedFormat, pBitmapInfo, sizeof(HXBitmapInfoHeader));
  134.     return (pLeft->biWidth == pRight->biWidth &&
  135.             pLeft->biHeight == pRight->biHeight &&
  136.             pLeft->biPlanes == pRight->biPlanes &&
  137.             pLeft->biBitCount == pRight->biBitCount &&
  138.             pLeft->biCompression == pRight->biCompression);
  139. }
  140. /************************************************************************
  141.  *  Method:
  142.  *    IHXVideoSurface::BeginOptimizedBlt
  143.  */
  144. STDMETHODIMP CMiniBaseSurface::BeginOptimizedBlt(HXBitmapInfoHeader* pBitmapInfo)
  145. {
  146.     HX_ASSERT(pBitmapInfo);    
  147.     if(m_pOptimizedFormat && IsCompatible(m_pOptimizedFormat, pBitmapInfo))
  148.     {
  149.         // current optimized format bitmap info (as well as info we derive from it) is valid
  150.         return HXR_OK;
  151.     }
  152.     // clean up
  153.     EndOptimizedBlt();
  154.     // save copy of bitmap info
  155.     m_pOptimizedFormat = new HXBitmapInfoHeader;
  156.     if(!m_pOptimizedFormat)
  157.     {
  158.         return HXR_OUTOFMEMORY;
  159.     }
  160.     *m_pOptimizedFormat = *pBitmapInfo;
  161.     // save current color format id
  162.     m_nSrcCID = m_pImageHelper->GetBitmapColor((HXBitmapInfo*) pBitmapInfo);
  163.     HX_ASSERT(m_nSrcCID != -1);
  164.     // determine color converter
  165.     int nDstCID = GetDstCID();
  166.     switch (m_nSrcCID)
  167.     {
  168. #if defined(HELIX_FEATURE_SMIL_SITE) && defined(HELIX_FEATURE_CC_RGB444out)
  169.        case CID_RGB32:
  170.        case CID_ARGB32:
  171.            if (nDstCID == CID_RGB444)
  172.                m_fpColorConverter = RGB32toRGB444;
  173.            m_nSrcPitch = m_pImageHelper->GetBitmapPitch((HXBitmapInfo*)pBitmapInfo);
  174.            break;
  175.        case CID_RGB444:
  176.            if (nDstCID == CID_RGB444)
  177.                m_fpColorConverter = RGB444toRGB444;
  178.            m_nSrcPitch = m_pImageHelper->GetBitmapPitch((HXBitmapInfo*)pBitmapInfo);
  179.            break;
  180. #endif //HELIX_FEATURE_SMIL_SITE
  181.            
  182.        case CID_I420:
  183.         
  184. #if defined (HELIX_FEATURE_CC_YV12out)
  185.            if (nDstCID == CID_YV12)
  186.                m_fpColorConverter = I420toYV12;
  187. #endif //HELIX_FEATURE_CC_YV12out
  188. #if defined (HELIX_FEATURE_CC_YUY2out)
  189.            if (nDstCID == CID_YUY2)
  190.                m_fpColorConverter = I420toYUY2;
  191. #endif //HELIX_FEATURE_CC_YUY2out
  192. #if defined (HELIX_FEATURE_CC_RGB32out)                     
  193.            if (nDstCID == CID_RGB32)
  194.                m_fpColorConverter = I420toRGB32;
  195. #endif //HELIX_FEATURE_CC_RGB32out
  196. #if defined (HELIX_FEATURE_CC_RGB24out)
  197.            if (nDstCID == CID_RGB24)
  198.                m_fpColorConverter = I420toRGB24;
  199. #endif //HELIX_FEATURE_CC_RGB24out
  200. #if defined (HELIX_FEATURE_CC_RGB565out)
  201.            if (nDstCID == CID_RGB565)
  202.                m_fpColorConverter = I420toRGB565;
  203. #endif //HELIX_FEATURE_CC_RGB565out
  204. #if defined (HELIX_FEATURE_CC_RGB555out)
  205.            if (nDstCID == CID_RGB555)
  206.                m_fpColorConverter = I420toRGB555;
  207. #endif //HELIX_FEATURE_CC_RGB555out
  208. #if defined (HELIX_FEATURE_CC_RGB444out)
  209.            if (nDstCID == CID_RGB444)
  210.                m_fpColorConverter = I420toRGB444;
  211. #endif //HELIX_FEATURE_CC_RGB444out
  212. #if defined (HELIX_FEATURE_CC_RGB8out)
  213.            if (nDstCID == CID_RGB8)
  214.                m_fpColorConverter = I420toRGB8;
  215. #endif //HELIX_FEATURE_CC_RGB444out
  216.            m_nSrcPitch = pBitmapInfo->biWidth;
  217.            break;
  218.        case CID_XING:
  219. #if defined (HELIX_FEATURE_CC_YV12out)
  220.            if (nDstCID == CID_YV12)
  221.                m_fpColorConverter = XINGtoYV12;
  222. #endif //HELIX_FEATURE_CC_YV12out
  223. #if defined (HELIX_FEATURE_CC_YUY2out)
  224.            if (nDstCID == CID_YUY2)
  225.                m_fpColorConverter = XINGtoYUY2;
  226. #endif //HELIX_FEATURE_CC_YUY2out
  227. #if defined (HELIX_FEATURE_CC_RGB32out)
  228.            if (nDstCID == CID_RGB32)
  229.                m_fpColorConverter = XINGtoRGB32;
  230. #endif //HELIX_FEATURE_CC_YUY2out
  231.         
  232. #if defined (HELIX_FEATURE_CC_RGB565out)
  233.            if (nDstCID == CID_RGB565)
  234.                m_fpColorConverter = XINGtoRGB565;
  235. #endif //HELIX_FEATURE_CC_RGB565out
  236.            m_nSrcPitch = 768;
  237.            break;
  238.     }
  239.     HX_ASSERT(m_fpColorConverter);
  240.     
  241. #if defined(HELIX_CONFIG_NOSTATICS)
  242.     SetSrcI420Colors (0, 0, 0, 0, GetColorData());
  243. #else    
  244.     SetSrcI420Colors (0, 0, 0, 0); 
  245.     SetDestI420Colors (0, 0, 0, 0);
  246.     SetI420ChromaResamplingMode (0);
  247. #endif    
  248.     
  249.     return m_fpColorConverter ? HXR_OK : HXR_FAIL;
  250. }
  251. /************************************************************************
  252.  *  Method:
  253.  *    IHXVideoSurface::Blt
  254.  */
  255. STDMETHODIMP CMiniBaseSurface::Blt(UCHAR*              pSrcBuffer,
  256.                                    HXBitmapInfoHeader* pBitmapInfo,
  257.                                    REF(HXxRect)        rDestRect,
  258.                                    REF(HXxRect)        rSrcRect)
  259. {
  260.     
  261.     HX_RESULT hr = BeginOptimizedBlt(pBitmapInfo);
  262.     if (FAILED(hr))
  263.     {
  264.         return hr;
  265.     }
  266.         
  267.     int nDstWidth   = rDestRect.right - rDestRect.left;
  268.     int nDstHeight  = rDestRect.bottom - rDestRect.top;
  269.     // ensure destination buffers are allocated, ensuring that we properly handle image stretching.
  270.     if(ScaleDuringRender(GetDstCID()))
  271.     {
  272.         hr = AllocateDestBuffers(pBitmapInfo->biWidth, pBitmapInfo->biHeight);
  273.     }
  274.     else
  275.     {
  276.         // we stretch during the transfer from source to dest 
  277.         // buffer; dest buffer must be same size as dest rect.
  278.         hr = AllocateDestBuffers(nDstWidth, nDstHeight);
  279.     }
  280.     if(FAILED(hr))
  281.     {
  282.         return hr;
  283.     }
  284.     UCHAR*  pDestBuffer = NULL;
  285.     LONG32  nDestPitch  = 0;
  286.     HXxSize dstSize     = m_dstBufSize;
  287.     hr = _LockDestBuffer(&pDestBuffer,
  288.                          &nDestPitch,
  289.                          m_nSrcCID,
  290.                          dstSize);
  291.     if (FAILED(hr))
  292.         return hr;
  293.     HXxRect rcDst = rDestRect;
  294.     HXxRect rcSrc = rSrcRect;
  295.     // If the dest buffer dimensions do not match the dest rect,
  296.     // map the dest rect to the dest buffer for video transfer.
  297.     if ((m_dstBufSize.cx != nDstWidth) | 
  298.         (m_dstBufSize.cy != nDstHeight))
  299.     {
  300.  
  301.         rcDst.left = (rcDst.left*m_dstBufSize.cx) / nDstWidth;
  302.         rcDst.right = (rcDst.right*m_dstBufSize.cx) / nDstWidth;
  303.         rcDst.top = (rcDst.top*m_dstBufSize.cy) / nDstHeight;
  304.         rcDst.bottom = (rcDst.bottom*m_dstBufSize.cy) / nDstHeight;
  305.     }
  306.     hr = _TransferToDestBuffer(pSrcBuffer,
  307.                                pBitmapInfo,
  308.                                &rcSrc,
  309.                                &rcDst,
  310.                                pDestBuffer,
  311.                                nDestPitch);
  312.     
  313.     _UnlockDestBuffer(pDestBuffer);
  314.     if (SUCCEEDED(hr))
  315.         hr = _RenderDestBuffer(&rcDst, &rDestRect);
  316.     
  317.     //Give the device a chance to keep the screen alive.
  318.     _KeepScreenAlive();
  319.     
  320.     return hr;
  321. }
  322. /************************************************************************
  323.  *  Method:
  324.  *    IHXVideoSurface::OptimizedBlt
  325.  */
  326. STDMETHODIMP CMiniBaseSurface::OptimizedBlt(UCHAR* pSrcBuffer,
  327.                                             REF(HXxRect) rDestRect,
  328.                                             REF(HXxRect) rSrcRect)
  329. {
  330.     return Blt(pSrcBuffer, 
  331.                m_pOptimizedFormat,
  332.                rDestRect,
  333.                rSrcRect); 
  334. }
  335. /************************************************************************
  336.  *  Method:
  337.  *    IHXVideoSurface::EndOptimizedBlt
  338.  */
  339. STDMETHODIMP CMiniBaseSurface::EndOptimizedBlt(void)
  340. {
  341.     HX_RESULT hr =  DestroyDestBuffers(m_nDstBuffers);
  342.     HX_DELETE(m_pOptimizedFormat);
  343.     m_nSrcCID = CID_UNKNOWN;
  344.     return hr;
  345. }
  346. /************************************************************************
  347.  *  Method:
  348.  *    IHXVideoSurface::GetOptimizedFormat
  349.  */
  350. STDMETHODIMP CMiniBaseSurface::GetOptimizedFormat(REF(HX_COMPRESSION_TYPE) ulType)
  351. {
  352.     ulType = 0;
  353.     return HXR_OK;
  354. }
  355. /************************************************************************
  356.  *  Method:
  357.  *    IHXVideoSurface::GetPreferredFormat
  358.  */
  359. STDMETHODIMP CMiniBaseSurface::GetPreferredFormat(REF(HX_COMPRESSION_TYPE) ulType)
  360. {                             
  361.     ulType = 0;
  362.     return HXR_OK;
  363. }                                                        
  364.                                       
  365. HX_RESULT 
  366. CMiniBaseSurface::_TransferToDestBuffer(UCHAR* pSrcBuffer,
  367.                                         HXBitmapInfoHeader* pBitmapInfo,
  368.                                         HXxRect* prSrcRect,
  369.                                         HXxRect* prDstRect,
  370.                                         UCHAR* pDstBuffer,
  371.                                         LONG32 nDstPitch)
  372. {
  373.     if (!m_fpColorConverter)
  374.         return HXR_FAIL;
  375.     int nRet = m_fpColorConverter( pDstBuffer,
  376.                                    m_dstBufSize.cx,
  377.                                    m_dstBufSize.cy,
  378.                                    nDstPitch,
  379.                                    prDstRect->left, prDstRect->top,
  380.                                    prDstRect->right-prDstRect->left, 
  381.                                    prDstRect->bottom-prDstRect->top,
  382.                                    pSrcBuffer,
  383.                                    pBitmapInfo->biWidth,
  384.                                    pBitmapInfo->biHeight,
  385.                                    m_nSrcPitch,
  386.                                    prSrcRect->left, prSrcRect->top,
  387.                                    prSrcRect->right-prSrcRect->left, 
  388.                                    prSrcRect->bottom-prSrcRect->top
  389. #if defined(HELIX_CONFIG_NOSTATICS)    
  390.                                    ,GetColorData()
  391. #endif    
  392.                                    );
  393.     if (nRet < 0)
  394.         return HXR_FAIL;
  395.     else
  396.         return HXR_OK;
  397. }
  398. BOOL CMiniBaseSurface::ScaleDuringRender(int nCID)
  399. {
  400.     // Our YUVtoYUV color converters do not scale so scaling
  401.     // must be done during rendering.
  402.     //
  403.     // Our XXXtoRGB do scaling
  404.     return (nCID == CID_DVPF) | 
  405.            (nCID >= CID_I420 && nCID <= CID_UYVY);
  406. }
  407. HX_RESULT CMiniBaseSurface::AllocateDestBuffers(int nWidth,
  408.                                                 int nHeight,
  409.                                                 int nCount)
  410. {
  411.     if (nWidth == m_dstBufSize.cx &&
  412.         nHeight == m_dstBufSize.cy &&
  413.         nCount == m_nDstBuffers)
  414.     {
  415.         return HXR_OK;
  416.     }
  417.     else
  418.     {
  419.         DestroyDestBuffers(m_nDstBuffers);
  420.     }
  421.     HX_RESULT hr = _CreateDestBuffer(m_nSrcCID, nWidth, nHeight, nCount);
  422.     if (HXR_OK == hr)
  423.     {
  424.         m_dstBufSize.cx = nWidth;
  425.         m_dstBufSize.cy = nHeight;
  426.         m_nDstBuffers = nCount;
  427.     }
  428.     return hr;
  429. }
  430. HX_RESULT CMiniBaseSurface::DestroyDestBuffers(int nCount)
  431. {
  432.     HX_RESULT hr = HXR_OK;
  433.     if (m_dstBufSize.cx || m_dstBufSize.cy)
  434.     {
  435.         hr = _DestroyDestBuffer(m_nSrcCID, nCount); 
  436.         memset(&m_dstBufSize, 0, sizeof(m_dstBufSize));
  437.         m_nDstBuffers = 0;
  438.     }
  439.     return hr;
  440. }