RealMediaWindowlessSite.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:18k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include "mplayerc.h"
  23. #include <math.h>
  24. #include <atlbase.h>
  25. #include <atlcoll.h>
  26. #include "realmediawindowlesssite.h"
  27. #include "....DSUtilDSUtil.h"
  28. void DSObjects::ExtractRects(REGION* pRegion)
  29. {
  30. LPRGNDATA lpRgnData;
  31. DWORD sizeNeeed = GetRegionData((HRGN)pRegion->pOSRegion, 0, NULL); 
  32. lpRgnData = (LPRGNDATA)new char[sizeNeeed];
  33. DWORD returnValue = GetRegionData((HRGN)pRegion->pOSRegion, sizeNeeed, lpRgnData); 
  34. PN_VECTOR_DELETE(pRegion->rects);
  35. pRegion->numRects = lpRgnData->rdh.nCount;
  36. pRegion->extents.left = lpRgnData->rdh.rcBound.left;
  37. pRegion->extents.top = lpRgnData->rdh.rcBound.top;
  38. pRegion->extents.right = lpRgnData->rdh.rcBound.right;
  39. pRegion->extents.bottom = lpRgnData->rdh.rcBound.bottom;
  40. if(lpRgnData->rdh.nCount)
  41. {
  42. pRegion->rects = new PNxRect[lpRgnData->rdh.nCount];
  43. // now extract the information.
  44. for(int j = 0; j < (int) lpRgnData->rdh.nCount;j++)
  45. {
  46. RECT* pRect = (RECT*)lpRgnData->Buffer;
  47. pRegion->rects[j].left = pRect[j].left;
  48. pRegion->rects[j].top = pRect[j].top;
  49. pRegion->rects[j].right = pRect[j].right;
  50. pRegion->rects[j].bottom = pRect[j].bottom;
  51. }
  52. }
  53. PN_VECTOR_DELETE(lpRgnData);
  54. }
  55. REGION* DSObjects::RMACreateRectRegion(int left, int top, int right, int bottom)
  56. {
  57. REGION* retVal = new REGION;
  58. retVal->pOSRegion = (void*)CreateRectRgn(left, top, right, bottom);
  59. ExtractRects(retVal);
  60. return retVal;
  61. }
  62. void DSObjects::RMASubtractRegion(REGION* regM, REGION* regS, REGION* regD)
  63. {
  64. CombineRgn((HRGN)regD->pOSRegion, (HRGN)regM->pOSRegion, (HRGN)regS->pOSRegion, RGN_DIFF);
  65. ExtractRects(regD);
  66. }
  67. void DSObjects::RMAUnionRegion(REGION* reg1, REGION* reg2, REGION* regD)
  68. {
  69. CombineRgn((HRGN)regD->pOSRegion, (HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion, RGN_OR);
  70. ExtractRects(regD);
  71. }
  72. void DSObjects::RMAIntersectRegion(REGION* reg1, REGION* reg2, REGION* regD)
  73. {
  74. CombineRgn((HRGN)regD->pOSRegion, (HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion, RGN_AND);
  75. ExtractRects(regD);
  76. }
  77. BOOL DSObjects::RMAEqualRegion(REGION* reg1, REGION* reg2)
  78. {
  79. return EqualRgn((HRGN)reg1->pOSRegion, (HRGN)reg2->pOSRegion)
  80. && !memcmp(&reg1->extents, &reg2->extents, sizeof(PNxRect)) ? TRUE : FALSE;
  81. }
  82. void DSObjects::RMADestroyRegion(REGION* reg)
  83. {
  84. if(reg) DeleteObject((HRGN)reg->pOSRegion),
  85. PN_VECTOR_DELETE(reg->rects);
  86. PN_DELETE(reg);
  87. }
  88. REGION* DSObjects::RMACreateRegion()
  89. {
  90. return RMACreateRectRegion(0,0,0,0);
  91. }
  92. //
  93. // CRealMediaWindowlessSite
  94. //
  95. CRealMediaWindowlessSite::CRealMediaWindowlessSite(HRESULT& hr, IUnknown* pContext, CRealMediaWindowlessSite* pParentSite, IUnknown* pUnkOuter)
  96. : CUnknown(NAME("CRealMediaWindowlessSite"), pUnkOuter, &hr)
  97. , m_pContext(pContext)
  98. , m_pParentSite(pParentSite)
  99. , m_pCCF(pContext)
  100. , m_fDamaged(false), m_fInRedraw(false), m_fIsVisible(true)
  101. , m_lZOrder(0)
  102. , m_pRegion(NULL), m_pRegionWithoutChildren(NULL)
  103. {
  104. m_size.cx = m_size.cy = 0;
  105. m_position.x = m_position.y = 0;
  106. memset(&m_lastBitmapInfo, 0, sizeof(m_lastBitmapInfo));
  107. hr = S_OK;
  108. if(!m_pContext || !m_pCCF)
  109. {
  110. hr = E_POINTER;
  111. return;
  112. }
  113. m_pCCF->CreateInstance(CLSID_IRMAValues, (void**)&m_pValues);
  114. }
  115. CRealMediaWindowlessSite::~CRealMediaWindowlessSite()
  116. {
  117. POSITION pos = m_pChildren.GetHeadPosition();
  118. while(pos) DestroyChild(m_pChildren.GetNext(pos));
  119. RMADestroyRegion(m_pRegion);
  120. RMADestroyRegion(m_pRegionWithoutChildren);
  121. }
  122. STDMETHODIMP CRealMediaWindowlessSite::NonDelegatingQueryInterface(REFIID riid, void** ppv)
  123. {
  124. return 
  125. QI2(IRMASite)
  126. QI2(IRMASite2)
  127. QI2(IRMASiteWindowless)
  128. QI2(IRMAVideoSurface)
  129. (m_pValues && m_pValues->QueryInterface(riid, ppv) == PNR_OK) ? PNR_OK :
  130. CUnknown::NonDelegatingQueryInterface(riid, ppv);
  131. }
  132. // public
  133. void CRealMediaWindowlessSite::GetTopLeft(PNxPoint* pPoint)
  134. {
  135. pPoint->x += m_position.x;
  136. pPoint->y += m_position.y;
  137. if(m_pParentSite)
  138. m_pParentSite->GetTopLeft(pPoint);
  139. }
  140. REGION* CRealMediaWindowlessSite::GetRegion()
  141. {
  142. return m_pRegion;
  143. }
  144. // private
  145. void CRealMediaWindowlessSite::RecomputeRegion()
  146. {
  147. if(m_pParentSite) m_pParentSite->RecomputeRegion();
  148. else InternalRecomputeRegion();
  149. }
  150. void CRealMediaWindowlessSite::InternalRecomputeRegion()
  151. {
  152. ComputeRegion();
  153. POSITION pos = m_pChildren.GetHeadPosition();
  154. while(pos)
  155. {
  156. CRealMediaWindowlessSite* pSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pChildren.GetNext(pos);
  157. if(pSite) pSite->InternalRecomputeRegion();
  158. }
  159. }
  160. void CRealMediaWindowlessSite::ComputeRegion()
  161. {
  162. REGION* pTempRegion = NULL;
  163. if(m_pRegion)
  164. {
  165. pTempRegion = RMACreateRegion();
  166. RMAUnionRegion(pTempRegion, m_pRegion, pTempRegion);
  167. RMADestroyRegion(m_pRegion);
  168. }
  169. if(m_pRegionWithoutChildren)
  170. {
  171. RMADestroyRegion(m_pRegionWithoutChildren);
  172. }
  173. PNxPoint topleft = {0,0};
  174. GetTopLeft(&topleft);
  175. if(IsSiteVisible())
  176. {
  177. m_pRegionWithoutChildren = RMACreateRectRegion(topleft.x, topleft.y, topleft.x + m_size.cx, topleft.y + m_size.cy);
  178. if(m_pParentSite)
  179. {
  180. RMAIntersectRegion(m_pRegionWithoutChildren, m_pParentSite->m_pRegionWithoutChildren, m_pRegionWithoutChildren);
  181. POSITION pos = m_pParentSite->m_pChildren.GetHeadPosition();
  182.             while(pos)
  183. {
  184. CRealMediaWindowlessSite* pSiblingSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pParentSite->m_pChildren.GetNext(pos);
  185. if(pSiblingSite != this)
  186. {
  187. INT32 zOrder;
  188. pSiblingSite->GetZOrder(zOrder);
  189. if(zOrder > m_lZOrder && pSiblingSite->IsSiteVisible())
  190. {
  191. pSiblingSite->SubtractSite(m_pRegionWithoutChildren);
  192. }
  193. }
  194. }
  195. }
  196. m_pRegion = RMACreateRegion();
  197. RMAUnionRegion(m_pRegion, m_pRegionWithoutChildren, m_pRegion);
  198. POSITION pos = m_pChildren.GetHeadPosition();
  199. while(pos)
  200. {
  201. CRealMediaWindowlessSite* pChildSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pChildren.GetNext(pos);
  202. if(pChildSite->IsSiteVisible()) pChildSite->SubtractSite(m_pRegion);
  203. }
  204. }
  205. else
  206. {
  207. m_pRegionWithoutChildren = RMACreateRectRegion(0,0,0,0);
  208. m_pRegion = RMACreateRectRegion(0,0,0,0);
  209. }
  210. if(pTempRegion && !RMAEqualRegion(m_pRegion, pTempRegion))
  211. {
  212. ForceRedraw();
  213. }
  214. RMADestroyRegion(pTempRegion);
  215. }
  216. void CRealMediaWindowlessSite::SubtractSite(REGION* pRegion)
  217. {
  218. PNxPoint topLeft;
  219. memset(&topLeft, 0, sizeof(PNxPoint));
  220. GetTopLeft(&topLeft);
  221. REGION* pTempRegion = RMACreateRectRegion(topLeft.x, topLeft.y, topLeft.x + m_size.cx, topLeft.y + m_size.cy);
  222. RMASubtractRegion(pRegion, pTempRegion, pRegion);
  223. RMADestroyRegion(pTempRegion);
  224. }
  225. void CRealMediaWindowlessSite::UpdateZOrder(CRealMediaWindowlessSite* pUpdatedChildSite, INT32 lOldZOrder, INT32 lNewZOrder)
  226. {
  227. POSITION pos = m_pChildren.GetHeadPosition();
  228. while(pos)
  229. {
  230. CRealMediaWindowlessSite* pSite = (CRealMediaWindowlessSite*)(IRMASite*)m_pChildren.GetNext(pos);
  231. INT32 lItsOldZOrder;
  232. pSite->GetZOrder(lItsOldZOrder);
  233. if(pSite != pUpdatedChildSite)
  234. {
  235. if(lOldZOrder < lNewZOrder)
  236. {
  237. if(lItsOldZOrder >= lOldZOrder && lItsOldZOrder < lNewZOrder)
  238. {
  239. pSite->SetInternalZOrder(lItsOldZOrder-1);
  240. }
  241. }
  242. else
  243. {
  244. if(lItsOldZOrder >= lNewZOrder && lItsOldZOrder < lOldZOrder)
  245. {
  246. pSite->SetInternalZOrder(lItsOldZOrder+1);
  247. }
  248. }
  249. }
  250. else
  251. {
  252. pSite->SetInternalZOrder(lNewZOrder);
  253. }
  254. }
  255. }
  256. void CRealMediaWindowlessSite::SetInternalZOrder(INT32 lZOrder)
  257. {
  258. m_lZOrder = lZOrder;
  259. }
  260. // IRMASiteWindowless
  261. STDMETHODIMP CRealMediaWindowlessSite::EventOccurred(PNxEvent* /*IN*/ pEvent)
  262. {
  263. return PNR_NOTIMPL;  /* not necessary within our implementation */
  264. }
  265. STDMETHODIMP_(PNxWindow*) CRealMediaWindowlessSite::GetParentWindow()
  266. {
  267. return NULL;
  268. }
  269. // IRMASite
  270. STDMETHODIMP CRealMediaWindowlessSite::AttachUser(IRMASiteUser* /*IN*/ pUser)
  271. {
  272. HRESULT hr = PNR_FAIL;
  273. if(m_pUser) return PNR_UNEXPECTED;
  274. if(CComQIPtr<IRMASite, &IID_IRMASite> pOuterSite = GetOwner())
  275. hr = pUser->AttachSite(pOuterSite);
  276. if(PNR_OK == hr)
  277. m_pUser = pUser;
  278. return hr;
  279. }
  280. STDMETHODIMP CRealMediaWindowlessSite::DetachUser()
  281. {
  282. HRESULT hr = PNR_OK;
  283. if(!m_pUser) return PNR_UNEXPECTED;
  284. hr = m_pUser->DetachSite();
  285. if(PNR_OK == hr)
  286. m_pUser = NULL;
  287. return hr;
  288. }
  289. STDMETHODIMP CRealMediaWindowlessSite::GetUser(REF(IRMASiteUser*) /*OUT*/ pUser)
  290. {
  291. HRESULT hr = PNR_OK;
  292. if(!m_pUser) return PNR_UNEXPECTED;
  293. (pUser = m_pUser)->AddRef();
  294. return hr;
  295. }
  296. STDMETHODIMP CRealMediaWindowlessSite::CreateChild(REF(IRMASite*) /*OUT*/ pChildSite)
  297. {
  298. HRESULT hr = PNR_OK;
  299. CComPtr<IRMASite> pSite = 
  300. (IRMASite*)new CRealMediaWindowlessSite(hr, m_pContext, this);
  301. if(FAILED(hr) || !pSite)
  302. return E_FAIL;
  303. pChildSite = pSite.Detach();
  304. m_pChildren.AddTail(pChildSite);
  305. return hr;
  306. }
  307. STDMETHODIMP CRealMediaWindowlessSite::DestroyChild(IRMASite* /*IN*/ pChildSite)
  308. {
  309. if(POSITION pos = m_pChildren.Find(pChildSite))
  310. {
  311. m_pChildren.RemoveAt(pos);
  312. return PNR_OK;
  313. }
  314. return PNR_UNEXPECTED;
  315. }
  316. STDMETHODIMP CRealMediaWindowlessSite::AttachWatcher(IRMASiteWatcher* /*IN*/ pWatcher)
  317. {
  318. if(m_pWatcher) return PNR_UNEXPECTED;
  319. if(m_pWatcher = pWatcher)
  320. m_pWatcher->AttachSite((IRMASite*)this);
  321. return PNR_OK;
  322. }
  323. STDMETHODIMP CRealMediaWindowlessSite::DetachWatcher()
  324. {
  325. if(!m_pWatcher) return PNR_UNEXPECTED;
  326. m_pWatcher->DetachSite();
  327. m_pWatcher = NULL;
  328. return PNR_OK;
  329. }
  330. STDMETHODIMP CRealMediaWindowlessSite::SetPosition(PNxPoint position)
  331. {
  332. HRESULT hr = PNR_OK;
  333. if(m_pWatcher)
  334. {
  335. hr = m_pWatcher->ChangingPosition(m_position, position);
  336. }
  337. if(PNR_OK == hr)
  338. {
  339. m_position = position;
  340. POSITION pos = m_pPassiveWatchers.GetHeadPosition();
  341. while(pos) m_pPassiveWatchers.GetNext(pos)->PositionChanged(&position);
  342. RecomputeRegion();
  343. }
  344. return hr;
  345. }
  346. STDMETHODIMP CRealMediaWindowlessSite::GetPosition(REF(PNxPoint) position)
  347. {
  348. position = m_position;
  349. return PNR_OK;
  350. }
  351. STDMETHODIMP CRealMediaWindowlessSite::SetSize(PNxSize size)
  352. {
  353. HRESULT hr = PNR_OK;
  354. if(m_pWatcher)
  355. {
  356. hr = m_pWatcher->ChangingSize(m_size, size);
  357. }
  358. if(PNR_OK == hr && size.cx != 0 && size.cy != 0)
  359. {
  360. m_size = size;
  361. POSITION pos = m_pPassiveWatchers.GetHeadPosition();
  362. while(pos) m_pPassiveWatchers.GetNext(pos)->SizeChanged(&size);
  363. RecomputeRegion();
  364. }
  365. return hr;
  366. }
  367. STDMETHODIMP CRealMediaWindowlessSite::GetSize(REF(PNxSize) size)
  368. {
  369. size = m_size;
  370. return PNR_OK;
  371. }
  372. STDMETHODIMP CRealMediaWindowlessSite::DamageRect(PNxRect rect)
  373. {
  374. m_fDamaged = TRUE;
  375. return PNR_OK;
  376. }
  377. STDMETHODIMP CRealMediaWindowlessSite::DamageRegion(PNxRegion region)
  378. {
  379. m_fDamaged = TRUE;
  380. return PNR_OK;
  381. }
  382. STDMETHODIMP CRealMediaWindowlessSite::ForceRedraw()
  383. {
  384. // make sure we have a visible window and are not re-enterering and we have damage
  385. if(!m_fInRedraw && m_fDamaged && m_fIsVisible)
  386. {
  387. m_fInRedraw = TRUE; 
  388. PNxEvent event = {RMA_SURFACE_UPDATE, NULL, (IRMAVideoSurface*)this, NULL, 0, 0};
  389. m_pUser->HandleEvent(&event);
  390. m_fInRedraw = FALSE;
  391. m_fDamaged = FALSE;
  392. }
  393. return PNR_OK;
  394. }
  395. // IRMASite2
  396. STDMETHODIMP CRealMediaWindowlessSite::UpdateSiteWindow(PNxWindow* /*IN*/ pWindow)
  397. {
  398. return PNR_OK;
  399. }
  400. STDMETHODIMP CRealMediaWindowlessSite::ShowSite(BOOL bShow)
  401. {
  402. m_fIsVisible = !!bShow;
  403. RecomputeRegion();
  404. return PNR_OK;
  405. }
  406. STDMETHODIMP_(BOOL) CRealMediaWindowlessSite::IsSiteVisible()
  407. {
  408. BOOL fIsVisible = m_fIsVisible;
  409. if(m_pParentSite) fIsVisible = fIsVisible && m_pParentSite->IsSiteVisible();
  410. return fIsVisible;
  411. }
  412. STDMETHODIMP CRealMediaWindowlessSite::SetZOrder(INT32 lZOrder)
  413. {
  414. if(!m_pParentSite) return PNR_UNEXPECTED;
  415. if(lZOrder == -1 || lZOrder >= (INT32)m_pParentSite->GetNumberOfChildSites())
  416. lZOrder = m_pParentSite->GetNumberOfChildSites() - 1; 
  417. if(m_lZOrder != lZOrder)
  418. m_pParentSite->UpdateZOrder(this, m_lZOrder, lZOrder);
  419. m_lZOrder = lZOrder;
  420. return PNR_OK;
  421. }
  422. STDMETHODIMP CRealMediaWindowlessSite::GetZOrder(REF(INT32) lZOrder)
  423. {
  424. if(!m_pParentSite) return PNR_UNEXPECTED;
  425. lZOrder = m_lZOrder;
  426. return PNR_OK;
  427. }
  428. STDMETHODIMP CRealMediaWindowlessSite::MoveSiteToTop()
  429. {
  430. if(!m_pParentSite) return PNR_UNEXPECTED;
  431. return PNR_NOTIMPL;
  432. }
  433. STDMETHODIMP CRealMediaWindowlessSite::GetVideoSurface(REF(IRMAVideoSurface*) pSurface)
  434. {
  435. (pSurface = (IRMAVideoSurface*)this)->AddRef();
  436. return PNR_OK;
  437. }
  438. STDMETHODIMP_(UINT32) CRealMediaWindowlessSite::GetNumberOfChildSites()
  439. {
  440. return (UINT32)m_pChildren.GetCount();
  441. }
  442. STDMETHODIMP CRealMediaWindowlessSite::AddPassiveSiteWatcher(IRMAPassiveSiteWatcher* pWatcher)
  443. {
  444. m_pPassiveWatchers.AddTail(pWatcher);
  445. return PNR_OK;
  446. }
  447. STDMETHODIMP CRealMediaWindowlessSite::RemovePassiveSiteWatcher(IRMAPassiveSiteWatcher* pWatcher)
  448. {
  449. if(POSITION pos = m_pPassiveWatchers.Find(pWatcher))
  450. {
  451. m_pPassiveWatchers.RemoveAt(pos);
  452. return PNR_OK;
  453. }
  454. return PNR_UNEXPECTED;
  455. }
  456. STDMETHODIMP CRealMediaWindowlessSite::SetCursor(PNxCursor cursor, REF(PNxCursor) oldCursor)
  457. {
  458. return PNR_NOTIMPL;
  459. }
  460. // private
  461. void CRealMediaWindowlessSite::IntersectRect(PNxRect* pRect, PNxRect* pBox, PNxRect* pRetVal)
  462. {
  463. pRetVal->left   = max(pRect->left, pBox->left);
  464. pRetVal->top    = max(pRect->top, pBox->top);
  465. pRetVal->right  = min(pRect->right, pBox->right);
  466. pRetVal->bottom = min(pRect->bottom, pBox->bottom);
  467. }
  468. // protected
  469. bool CRealMediaWindowlessSite::GetBltService(IRMAVideoSurface** ppBltService)
  470. {
  471. bool fRet = false;
  472. if(ppBltService)
  473. {
  474. if(m_pParentSite)
  475. {
  476. fRet = m_pParentSite->GetBltService(ppBltService);
  477.     }
  478.     else if(m_pBltService)
  479. {
  480. (*ppBltService = m_pBltService)->AddRef();
  481. fRet = true;
  482. }
  483. }
  484.        
  485. return(fRet);
  486. }
  487. void CRealMediaWindowlessSite::SetBltService(IRMAVideoSurface* pBltService)
  488. {
  489. m_pBltService = pBltService; 
  490. }
  491. // IRMAVideoSurface
  492. STDMETHODIMP CRealMediaWindowlessSite::Blt(UCHAR* /*IN*/ pImageData, RMABitmapInfoHeader* /*IN*/ pBitmapInfo, REF(PNxRect) /*IN*/ inDestRect, REF(PNxRect) /*IN*/ inSrcRect)
  493. {
  494. BeginOptimizedBlt(pBitmapInfo);
  495. return OptimizedBlt(pImageData, inDestRect, inSrcRect);
  496. }
  497. STDMETHODIMP CRealMediaWindowlessSite::BeginOptimizedBlt(RMABitmapInfoHeader* /*IN*/ pBitmapInfo)
  498. {
  499. if(memcmp(&m_bitmapInfo, pBitmapInfo, sizeof(RMABitmapInfoHeader)))
  500. {
  501. memcpy(&m_bitmapInfo, pBitmapInfo, sizeof(RMABitmapInfoHeader));
  502.         // format of image has changed somehow.
  503. // do something here if this affects you.
  504. }
  505. /*
  506. CComPtr<IRMAVideoSurface> pBltService;
  507. GetBltService(&pBltService);
  508. if(!pBltService)
  509. return PNR_UNEXPECTED;
  510. RMA_COMPRESSION_TYPE ulType = (RMA_COMPRESSION_TYPE)-1;
  511. pBltService->GetPreferredFormat(ulType);
  512. if(pBitmapInfo->biCompression != ulType)
  513. return PNR_UNEXPECTED;
  514. */
  515. return PNR_OK;
  516. }
  517. STDMETHODIMP CRealMediaWindowlessSite::OptimizedBlt(UCHAR* /*IN*/ pImageBits, REF(PNxRect) /*IN*/ rDestRect, REF(PNxRect) /*IN*/ rSrcRect)
  518. {
  519. CComPtr<IRMAVideoSurface> pBltService;
  520. GetBltService(&pBltService);
  521. REGION* pRegion = GetRegion();
  522. if(!pBltService || !pRegion)
  523. return PNR_UNEXPECTED;
  524. PNxPoint origin;
  525. memset(&origin, 0, sizeof(PNxPoint));
  526. GetTopLeft(&origin);
  527. PNxRect adjustedDestRect;
  528. adjustedDestRect.left   = rDestRect.left + origin.x;
  529. adjustedDestRect.top    = rDestRect.top + origin.y;
  530. adjustedDestRect.right  = rDestRect.right + origin.x;
  531. adjustedDestRect.bottom = rDestRect.bottom + origin.y;
  532. for(int i = 0; i < pRegion->numRects; i++)
  533. {
  534. PNxRect* pRect = pRegion->rects+i;
  535. // intersect the dest rect with the rect from the
  536. // region to get the final dest rect.
  537. PNxRect finalDestRect;
  538. IntersectRect(&adjustedDestRect, pRect, &finalDestRect);
  539.         // now compute the src rect for this blt.
  540. double xStretch = (double) (rDestRect.right - rDestRect.left) / (double) (rSrcRect.right - rSrcRect.left);
  541. double yStretch = (double) (rDestRect.bottom - rDestRect.top) / (double) (rSrcRect.bottom - rSrcRect.top);
  542. PNxRect finalSrcRect;
  543. finalSrcRect.left   = (INT32)((double)(finalDestRect.left-origin.x) / xStretch + 0.5);
  544. finalSrcRect.top    = (INT32)((double)(finalDestRect.top-origin.y) / yStretch + 0.5);
  545. finalSrcRect.right  = (INT32)((double)(finalDestRect.right-origin.x) / xStretch + 0.5);
  546. finalSrcRect.bottom = (INT32)((double)(finalDestRect.bottom-origin.y) / yStretch + 0.5);
  547. pBltService->Blt(pImageBits, &m_bitmapInfo, finalDestRect, finalSrcRect);
  548. }
  549. return PNR_OK;
  550. }
  551. STDMETHODIMP CRealMediaWindowlessSite::EndOptimizedBlt()
  552. {
  553. memset(&m_bitmapInfo, 0, sizeof(m_bitmapInfo));
  554. return PNR_OK;
  555. }
  556. STDMETHODIMP CRealMediaWindowlessSite::GetOptimizedFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType)
  557. {
  558. ulType =  m_bitmapInfo.biCompression;
  559. return PNR_OK;
  560. }
  561. STDMETHODIMP CRealMediaWindowlessSite::GetPreferredFormat(REF(RMA_COMPRESSION_TYPE) /*OUT*/ ulType)
  562. {
  563. CComPtr<IRMAVideoSurface> pBltService;
  564. GetBltService(&pBltService);
  565. if(!pBltService)
  566. return PNR_UNEXPECTED;
  567. return pBltService->GetPreferredFormat(ulType);
  568. }