Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1199 lines
47 KiB

  1. //==========================================================================;
  2. // MSVidVideoRenderer.h : Declaration of the CMSVidVideoRenderer
  3. // copyright (c) Microsoft Corp. 1998-1999.
  4. //==========================================================================;
  5. #ifndef __MSVidVIDEORENDERERIMPL_H_
  6. #define __MSVidVIDEORENDERERIMPL_H_
  7. #pragma once
  8. #include <algorithm>
  9. #include <evcode.h>
  10. #include <uuids.h>
  11. #include <amvideo.h>
  12. #include <strmif.h>
  13. #include "vidrect.h"
  14. #include "vrsegimpl.h"
  15. #include "outputimpl.h"
  16. #include "seg.h"
  17. #include "videorenderercp.h"
  18. #include "strmif.h"
  19. #include "resource.h" // main symbols
  20. //typedef CComQIPtr<IVMRSurfaceAllocator> PQVMRSAlloc;
  21. //typedef CComQIPtr<IVMRAlphaBitmap> PQVMRAlphaBitm;
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CMSVidVideoRenderer
  24. template<class T, LPCGUID LibID, LPCGUID Category, class MostDerivedClass = IMSVidVideoRenderer>
  25. class DECLSPEC_NOVTABLE IMSVidVideoRendererImpl :
  26. public IMSVidOutputDeviceImpl<T, LibID, Category, MostDerivedClass>,
  27. public IMSVidVRGraphSegmentImpl<T> {
  28. public:
  29. IMSVidVideoRendererImpl()
  30. {
  31. m_opacity = -1;
  32. m_rectPosition.top = -1;
  33. m_rectPosition.left = -1;
  34. m_rectPosition.bottom = -1;
  35. m_rectPosition.right = -1;
  36. m_SourceSize = sslFullSize;
  37. m_lOverScan = 1;
  38. }
  39. virtual ~IMSVidVideoRendererImpl() {
  40. m_PQIPicture.Release();
  41. }
  42. protected:
  43. typedef IMSVidVRGraphSegmentImpl<T> VRSegbasetype;
  44. PQIPic m_PQIPicture;
  45. FLOAT m_opacity;
  46. NORMALIZEDRECT m_rectPosition;
  47. SourceSizeList m_SourceSize;
  48. LONG m_lOverScan;
  49. CScalingRect m_ClipRect;
  50. public:
  51. virtual HRESULT SetVRConfig() {
  52. HRESULT hr = S_OK;
  53. if (m_pVMR) {
  54. hr = VRSegbasetype::SetVRConfig();
  55. if (FAILED(hr)) {
  56. return hr;
  57. }
  58. if(m_pVMRWC){
  59. hr = m_pVMRWC->SetColorKey(m_ColorKey);
  60. }
  61. else{
  62. return ImplReportError(__uuidof(T), IDS_E_NOTWNDLESS, __uuidof(IVMRFilterConfig), E_FAIL);
  63. }
  64. if (FAILED(hr) && hr != E_NOTIMPL) {
  65. return hr;
  66. }
  67. }
  68. return NOERROR;
  69. }
  70. STDMETHOD(Refresh)() {
  71. ReComputeSourceRect();
  72. return VRSegbasetype::Refresh();
  73. }
  74. // IMSVidVideoRenderer
  75. STDMETHOD(get_OverScan)(LONG * plPercent)
  76. {
  77. if (!m_fInit) {
  78. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  79. }
  80. if (plPercent == NULL) {
  81. return E_POINTER;
  82. }
  83. try {
  84. *plPercent = m_lOverScan;
  85. return NOERROR;
  86. } catch(...) {
  87. return E_UNEXPECTED;
  88. }
  89. }
  90. STDMETHOD(put_OverScan)(LONG lPercent)
  91. {
  92. if (!m_fInit) {
  93. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  94. }
  95. try {
  96. if(lPercent > 4900 || lPercent < 0){
  97. return ImplReportError(__uuidof(T), IDS_INVALID_OVERSCAN, __uuidof(IMSVidVideoRenderer), CO_E_ERRORINAPP);
  98. }
  99. m_lOverScan = lPercent;
  100. return ReComputeSourceRect();
  101. } catch(...) {
  102. return E_UNEXPECTED;
  103. }
  104. }
  105. STDMETHOD(get_SourceSize)(/*[out, retval]*/ SourceSizeList *pCurrentSize) {
  106. if (!m_fInit) {
  107. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  108. }
  109. if (!pCurrentSize) {
  110. return E_POINTER;
  111. }
  112. try {
  113. *pCurrentSize = m_SourceSize;
  114. return NOERROR;
  115. } catch(...) {
  116. return E_UNEXPECTED;
  117. }
  118. }
  119. // TODO: add checks for input value being null
  120. STDMETHOD(get_MaxVidRect)(/*[out, retval]*/ IMSVidRect **ppVidRect){
  121. HRESULT hr = S_OK;
  122. CComQIPtr<IMSVidRect>PQIMSVRect;
  123. try{
  124. PQIMSVRect = static_cast<IMSVidRect *>(new CVidRect(0,0,0,0));
  125. if(!PQIMSVRect){
  126. throw(E_UNEXPECTED);
  127. }
  128. if(!m_pVMR){
  129. throw(ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED));
  130. }
  131. long dwWidth, dwHeight;
  132. if(m_pVMRWC){
  133. hr = m_pVMRWC->GetMaxIdealVideoSize(&dwWidth, &dwHeight);
  134. if(FAILED(hr)){
  135. throw(hr);
  136. }
  137. }
  138. else{
  139. throw(ImplReportError(__uuidof(T), IDS_E_NOTWNDLESS, __uuidof(IVMRFilterConfig), E_FAIL));
  140. }
  141. PQIMSVRect->put_Height(dwHeight);
  142. PQIMSVRect->put_Width(dwWidth);
  143. }
  144. catch(HRESULT hres){
  145. PQIMSVRect = static_cast<IMSVidRect *>(new CVidRect(-1,-1,-1,-1));
  146. *ppVidRect = PQIMSVRect.Detach();
  147. return hres;
  148. }
  149. *ppVidRect = PQIMSVRect.Detach();
  150. return hr;
  151. }
  152. STDMETHOD(get_MinVidRect)(/*[out, retval]*/ IMSVidRect **ppVidRect){
  153. HRESULT hr = S_OK;
  154. CComQIPtr<IMSVidRect>PQIMSVRect;
  155. try{
  156. PQIMSVRect = static_cast<IMSVidRect *>(new CVidRect(0,0,0,0));
  157. if(!PQIMSVRect){
  158. throw(E_UNEXPECTED);
  159. }
  160. if(!m_pVMR){
  161. throw(ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED));
  162. }
  163. long dwWidth, dwHeight;
  164. if(m_pVMRWC){
  165. hr = m_pVMRWC->GetMinIdealVideoSize(&dwWidth, &dwHeight);
  166. if(FAILED(hr)){
  167. throw(hr);
  168. }
  169. }
  170. else{
  171. throw(ImplReportError(__uuidof(T), IDS_E_NOTWNDLESS, __uuidof(IMSVidVideoRenderer), E_FAIL));
  172. }
  173. PQIMSVRect->put_Height(dwHeight);
  174. PQIMSVRect->put_Width(dwWidth);
  175. }
  176. catch(HRESULT hres){
  177. PQIMSVRect = static_cast<IMSVidRect *>(new CVidRect(-1,-1,-1,-1));
  178. *ppVidRect = PQIMSVRect.Detach();
  179. return hres;
  180. }
  181. *ppVidRect = PQIMSVRect.Detach();
  182. return hr;
  183. }
  184. STDMETHOD(put_SourceSize)(/*[in]*/ SourceSizeList NewSize) {
  185. if (!m_fInit) {
  186. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  187. }
  188. try {
  189. SourceSizeList prev = m_SourceSize;
  190. m_SourceSize = NewSize;
  191. if (m_SourceSize != prev) {
  192. return ReComputeSourceRect();
  193. }
  194. return NOERROR;
  195. } catch(...) {
  196. return E_UNEXPECTED;
  197. }
  198. }
  199. STDMETHOD(get_CustomCompositorClass)(/*[out, retval]*/ BSTR *CompositorCLSID) {
  200. try{
  201. if(!CompositorCLSID){
  202. return E_POINTER;
  203. }
  204. GUID2 gRetVal;
  205. HRESULT hr = get__CustomCompositorClass(&gRetVal);
  206. if(SUCCEEDED(hr)){
  207. *CompositorCLSID = gRetVal.GetBSTR();
  208. return S_OK;
  209. }
  210. }
  211. catch(...){
  212. return E_UNEXPECTED;
  213. }
  214. return S_OK;
  215. }
  216. STDMETHOD(get__CustomCompositorClass)(/*[out, retval]*/ GUID* CompositorCLSID) {
  217. HRESULT hr = S_OK;
  218. try{
  219. if(!CompositorCLSID){
  220. return E_POINTER;
  221. }
  222. if(m_compositorGuid != GUID_NULL){
  223. *CompositorCLSID = m_compositorGuid;
  224. return S_OK;
  225. }
  226. PQVMRImageComp pRetVal;
  227. hr = get__CustomCompositor(&pRetVal);
  228. if(FAILED(hr)){
  229. return hr;
  230. }
  231. CComQIPtr<IPersist> ipRet(pRetVal);
  232. hr = ipRet->GetClassID((CLSID*)CompositorCLSID);
  233. if(SUCCEEDED(hr)){
  234. return S_OK;
  235. }
  236. else{
  237. return E_UNEXPECTED;
  238. }
  239. }
  240. catch(...){
  241. return E_UNEXPECTED;
  242. }
  243. return S_OK;
  244. }
  245. STDMETHOD(put_CustomCompositorClass)(/*[in]*/ BSTR CompositorCLSID) {
  246. try{
  247. GUID2 inGuid(CompositorCLSID);
  248. HRESULT hr = put__CustomCompositorClass(inGuid);
  249. if(SUCCEEDED(hr)){
  250. return S_OK;
  251. }
  252. else{
  253. return hr;
  254. }
  255. }
  256. catch(...){
  257. return E_UNEXPECTED;
  258. }
  259. return S_OK;
  260. }
  261. STDMETHOD(put__CustomCompositorClass)(/*[in]*/ REFCLSID CompositorCLSID) {
  262. try{
  263. CComQIPtr<IVMRImageCompositor>IVMRICPtr;
  264. IVMRICPtr.Release();
  265. HRESULT hr = CoCreateInstance( CompositorCLSID, NULL, CLSCTX_INPROC_SERVER, IID_IVMRImageCompositor, (LPVOID*) &IVMRICPtr);
  266. if(FAILED(hr)){
  267. return E_UNEXPECTED;
  268. }
  269. hr = put__CustomCompositor(IVMRICPtr);
  270. if(FAILED(hr)){
  271. return hr;
  272. }
  273. else{
  274. return S_OK;
  275. }
  276. }
  277. catch(...){
  278. return E_UNEXPECTED;
  279. }
  280. return S_OK;
  281. }
  282. STDMETHOD(get__CustomCompositor)(/*[out, retval]*/ IVMRImageCompositor** Compositor) {
  283. try{
  284. if(!Compositor){
  285. return E_POINTER;
  286. }
  287. if(!ImCompositor){
  288. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);;
  289. }
  290. else{
  291. *Compositor = ImCompositor;
  292. return S_OK;
  293. }
  294. }
  295. catch(...){
  296. return E_UNEXPECTED;
  297. }
  298. return S_OK;
  299. }
  300. STDMETHOD(put__CustomCompositor)(/*[in]*/ IVMRImageCompositor* Compositor) {
  301. try{
  302. if(!Compositor){
  303. return E_POINTER;
  304. }
  305. ImCompositor = Compositor;
  306. HRESULT hr = CleanupVMR();
  307. if(FAILED(hr)){
  308. return hr;
  309. }
  310. }
  311. catch(...){
  312. return E_UNEXPECTED;
  313. }
  314. return S_OK;
  315. }
  316. STDMETHOD(get_AvailableSourceRect)(IMSVidRect **ppVidRect) {
  317. CComQIPtr<IMSVidRect>PQIMSVRect = static_cast<IMSVidRect *>(new CVidRect(0,0,0,0));
  318. try{
  319. if(!ppVidRect){
  320. return E_POINTER;
  321. }
  322. SIZE Size, Ar;
  323. HRESULT hr = get_NativeSize(&Size, &Ar);
  324. hr = PQIMSVRect->put_Height(Size.cy);
  325. if(FAILED(hr)){
  326. throw(hr);
  327. }
  328. hr = PQIMSVRect->put_Width(Size.cx);
  329. if(FAILED(hr)){
  330. throw(hr);
  331. }
  332. }
  333. catch(...){
  334. return E_UNEXPECTED;
  335. }
  336. *ppVidRect = PQIMSVRect.Detach();
  337. return S_OK;
  338. }
  339. STDMETHOD(put_ClippedSourceRect)(IMSVidRect *pVidRect) {
  340. if (!m_fInit) {
  341. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  342. }
  343. if (!pVidRect) {
  344. return E_POINTER;
  345. }
  346. try {
  347. m_ClipRect = *(static_cast<CScalingRect*>(static_cast<CVidRect*>(pVidRect)));
  348. return ReComputeSourceRect();
  349. } catch(...) {
  350. return E_UNEXPECTED;
  351. }
  352. }
  353. STDMETHOD(get_ClippedSourceRect)(IMSVidRect **ppVidRect) {
  354. if (!m_fInit) {
  355. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  356. }
  357. if (!ppVidRect) {
  358. return E_POINTER;
  359. }
  360. try {
  361. CComQIPtr<IMSVidRect>PQIMSVRect = static_cast<IMSVidRect *>(new CVidRect(-1,-1,-1,-1));
  362. PQIMSVRect->put_Left(m_ClipRect.left);
  363. PQIMSVRect->put_Height(m_ClipRect.bottom - m_ClipRect.top);
  364. PQIMSVRect->put_Top(m_ClipRect.top);
  365. PQIMSVRect->put_Width(m_ClipRect.right - m_ClipRect.left);
  366. *ppVidRect = PQIMSVRect.Detach();
  367. return S_OK;
  368. } catch(...) {
  369. return E_UNEXPECTED;
  370. }
  371. }
  372. /*************************************************************************/
  373. /* Function: Capture */
  374. /* Description: Returns the current image on screen */
  375. /*************************************************************************/
  376. STDMETHOD(Capture)(IPictureDisp **currentImage){
  377. HBITMAP hBitmap = 0;
  378. HPALETTE hPalette = 0;
  379. //VMRALPHABITMAP vmrAlphaBitmapStruct;
  380. CComQIPtr<IPicture> retPicture;
  381. PICTDESC PictDescStruct;
  382. HRESULT hr = S_OK;
  383. BYTE *lpDIB = NULL;
  384. try{
  385. if(!currentImage){
  386. throw(E_POINTER);
  387. }
  388. if(!m_pVMR){
  389. throw(E_FAIL);
  390. }
  391. if(m_pVMRWC){
  392. hr = m_pVMRWC->GetCurrentImage(&lpDIB);
  393. }
  394. else{
  395. throw(ImplReportError(__uuidof(T), IDS_E_NOTWNDLESS, __uuidof(IMSVidVideoRenderer), E_FAIL));
  396. }
  397. if(FAILED(hr)){
  398. throw(hr);
  399. }
  400. HDC curDC = GetDC(NULL);
  401. UINT wUsage = DIB_RGB_COLORS;
  402. DWORD dwFlags = CBM_INIT;
  403. hBitmap = CreateDIBitmap(curDC,
  404. reinterpret_cast<BITMAPINFOHEADER*>(lpDIB), dwFlags,
  405. reinterpret_cast<void *>((LPBYTE)(lpDIB) + (int)(reinterpret_cast<BITMAPINFOHEADER*>(lpDIB)->biSize)),
  406. reinterpret_cast<BITMAPINFO*>(lpDIB),
  407. wUsage);
  408. ReleaseDC(NULL,curDC);
  409. ZeroMemory(&PictDescStruct, sizeof(PictDescStruct));
  410. PictDescStruct.bmp.hbitmap = hBitmap;
  411. PictDescStruct.bmp.hpal = NULL;
  412. PictDescStruct.picType = PICTYPE_BITMAP;
  413. PictDescStruct.cbSizeofstruct = sizeof(PictDescStruct);
  414. hr = OleCreatePictureIndirect(&PictDescStruct, IID_IPicture, TRUE, (void **)&retPicture);
  415. if(SUCCEEDED(hr)){
  416. hr = retPicture.QueryInterface(reinterpret_cast<IPictureDisp**>(currentImage));
  417. return hr;
  418. }
  419. else{
  420. throw(hr);
  421. }
  422. }
  423. catch(HRESULT hres){
  424. hr = hres;
  425. }
  426. catch(...){
  427. hr = E_UNEXPECTED;
  428. }
  429. if(lpDIB){
  430. CoTaskMemFree(lpDIB);
  431. }
  432. return hr;
  433. }
  434. /*************************************************************************/
  435. /* Function: get_MixerBitmap */
  436. /* Description: Returns the current alpha bitmap to script wrapped in a */
  437. /* IPictureDisp. */
  438. /*************************************************************************/
  439. STDMETHOD(get_MixerBitmap)(/*[out,retval]*/ IPictureDisp** ppIPDisp){
  440. #if 0
  441. HDC *pHDC = NULL;
  442. HBITMAP hBitmap = 0;
  443. HPALETTE hPalette = 0;
  444. VMRALPHABITMAP vmrAlphaBitmapStruct;
  445. PQIPicDisp retPicture;
  446. CComQIPtr<IVMRMixerBitmap> PQIVMRMixerBitmap;
  447. PICTDESC PictDescStruct;
  448. try{
  449. HRESULT hr = get__MixerBitmap(&PQIVMRMixerBitmap);
  450. if(FAILED(hr)){
  451. return hr;
  452. }
  453. hr = PQIVMRMixerBitmap->GetAlphaBitmapParameters(&vmrAlphaBitmapStruct);
  454. if(FAILED(hr)){
  455. return hr;
  456. }
  457. hr = vmrAlphaBitmapStruct.pDDS->GetDC(pHDC);
  458. if(FAILED(hr)){
  459. return hr;
  460. }
  461. hBitmap = static_cast<HBITMAP>(GetCurrentObject(*pHDC, OBJ_BITMAP));
  462. if(!hBitmap){
  463. return hr;
  464. }
  465. hPalette = static_cast<HPALETTE>(GetCurrentObject(*pHDC, OBJ_PAL));
  466. if(!hPalette){
  467. return hr ;
  468. }
  469. PictDescStruct.bmp.hbitmap = hBitmap;
  470. PictDescStruct.bmp.hpal = hPalette;
  471. PictDescStruct.picType = PICTYPE_BITMAP;
  472. PictDescStruct.cbSizeofstruct = sizeof(PictDescStruct.bmp);
  473. hr = OleCreatePictureIndirect(&PictDescStruct, IID_IPictureDisp, true, reinterpret_cast<void**> (&retPicture));
  474. if(FAILED(hr)){
  475. return hr;
  476. }
  477. }
  478. catch(HRESULT hr){
  479. return hr;
  480. }
  481. catch(...){
  482. return E_FAIL;
  483. }
  484. ppIPDisp = &retPicture.Detach();
  485. return S_OK;
  486. #endif
  487. // If m_PQIPicture is set, return it
  488. try{
  489. if(m_PQIPicture){
  490. CComQIPtr<IPictureDisp> PQIPDisp(m_PQIPicture);
  491. *ppIPDisp = PQIPDisp.Detach();
  492. throw S_OK;
  493. }
  494. else{
  495. throw ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  496. }
  497. }
  498. catch(HRESULT hres){
  499. return hres;
  500. }
  501. catch(...){
  502. return E_UNEXPECTED;
  503. }
  504. }
  505. /*************************************************************************/
  506. /* Function: get__MixerBitmap */
  507. /* Description: Returns the IVMRMixerBitmap from the VMR */
  508. /*************************************************************************/
  509. STDMETHOD(get__MixerBitmap)(/*[out, retval]*/ IVMRMixerBitmap ** ppIVMRMBitmap){
  510. try{
  511. if(!ppIVMRMBitmap){
  512. return E_POINTER;
  513. }
  514. // Make sure there is a VMR filter init'ed
  515. if(!m_pVMR){
  516. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  517. }
  518. CComQIPtr<IVMRMixerBitmap> PQIVMRMBitmap(m_pVMR);
  519. *ppIVMRMBitmap = PQIVMRMBitmap.Detach();
  520. }
  521. catch(HRESULT hr){
  522. return hr;
  523. }
  524. catch(...){
  525. return E_UNEXPECTED;
  526. }
  527. return S_OK;
  528. }
  529. /*************************************************************************/
  530. /* Function: put_MixerBitmap */
  531. /* Description: Updates the current VMR Alpha Bitmap */
  532. /* uses SutupMixerBitmap helper function */
  533. /*************************************************************************/
  534. STDMETHOD(put_MixerBitmap)(/*[in*/ IPictureDisp* pIPDisp){
  535. try{
  536. return SetupMixerBitmap(pIPDisp);
  537. }
  538. catch(HRESULT hr){
  539. return hr;
  540. }
  541. catch(...){
  542. return E_UNEXPECTED;
  543. }
  544. }
  545. /*************************************************************************/
  546. /* Function: put__MixerBitmap */
  547. /* Description: Updates the current VMR Alpha Bitmap */
  548. /* directly using the VMR fucntions */
  549. /*************************************************************************/
  550. STDMETHOD(put__MixerBitmap)(/*[in]*/ VMRALPHABITMAP * pVMRAlphaBitmapStruct){ //pMixerPicture
  551. try{
  552. HRESULT hr = S_OK;
  553. if(!pVMRAlphaBitmapStruct){
  554. return E_POINTER;
  555. }
  556. // Make sure there is a vmr to add the bitmap to
  557. if(!m_pVMR){
  558. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  559. }
  560. // Querry the vmr for the MixerBitmap Interface
  561. CComQIPtr<IVMRMixerBitmap> pVMRMBitmap(m_pVMR);
  562. if (!pVMRMBitmap) {
  563. return E_UNEXPECTED;
  564. }
  565. // Set the mixer bitmap to pVMRAlphaBitmapStruct
  566. hr = pVMRMBitmap->SetAlphaBitmap(pVMRAlphaBitmapStruct);
  567. return hr;
  568. }
  569. catch(HRESULT hr){
  570. return hr;
  571. }
  572. catch(...){
  573. return E_UNEXPECTED;
  574. }
  575. }
  576. /**************************************************************************/
  577. /* Function: get_MixerBitmapPositionRect */
  578. /* Description: Lets script folk access the position of the overlay bitmap*/
  579. /* the units are normalized vs the display rect so the values*/
  580. /* should be between 0 and 1 though will be converted if they*/
  581. /* are not */
  582. /**************************************************************************/
  583. STDMETHOD(get_MixerBitmapPositionRect)(/*[out,retval]*/IMSVidRect **ppIMSVRect){
  584. HRESULT hr = S_OK;
  585. CComQIPtr<IMSVidRect>PQIMSVRect;
  586. try{
  587. CComQIPtr<IVMRMixerBitmap> PQIVMRMBitmap;
  588. PQIMSVRect = static_cast<IMSVidRect *>(new CVidRect(-1,-1,-1,-1));
  589. VMRALPHABITMAP VMRAlphaBitmap;
  590. if(!m_pVMR){
  591. hr = S_FALSE;
  592. throw(hr);
  593. }
  594. hr = get__MixerBitmap(&PQIVMRMBitmap);
  595. // If the VMRBitmap is not set on the VRM, if it is not make sure that the local one is set
  596. if(SUCCEEDED(hr) ){
  597. // QI for the Parameters
  598. hr = PQIVMRMBitmap->GetAlphaBitmapParameters(&VMRAlphaBitmap);
  599. // if it fails or they are not set make sure that the local copy is
  600. if(SUCCEEDED(hr)){
  601. // Make sure that the rDest points are valid top and left : [0,1)
  602. // and right and bottom (0,1]
  603. if(VMRAlphaBitmap.rDest.top >= 0 && VMRAlphaBitmap.rDest.left >= 0 &&
  604. VMRAlphaBitmap.rDest.top < 1 && VMRAlphaBitmap.rDest.left < 1 &&
  605. VMRAlphaBitmap.rDest.right <= 1 && VMRAlphaBitmap.rDest.bottom <= 1 &&
  606. VMRAlphaBitmap.rDest.right > 0 && VMRAlphaBitmap.rDest.bottom > 0){
  607. // Make sure the local copy of the normalized rect is upto date
  608. m_rectPosition = VMRAlphaBitmap.rDest;
  609. }
  610. }
  611. }
  612. if( m_rectPosition.left < 0 || m_rectPosition.top < 0 ||
  613. m_rectPosition.right < 0 || m_rectPosition.bottom < 0 ){
  614. hr = S_FALSE;
  615. throw(hr);
  616. }
  617. else{
  618. // Convert and copy the values in the local copy of the normalized rect to the return rect
  619. hr = PQIMSVRect->put_Top(static_cast<long> (m_rectPosition.top * m_rectDest.Height()));
  620. if(FAILED(hr)){
  621. hr = ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  622. throw(hr);
  623. }
  624. // bottom * height - top
  625. hr = PQIMSVRect->put_Height(static_cast<long>((m_rectPosition.bottom * m_rectDest.Height())
  626. - (m_rectPosition.top * m_rectDest.Height())));
  627. if(FAILED(hr)){
  628. hr = ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  629. throw(hr);
  630. }
  631. // right * width - left
  632. hr = PQIMSVRect->put_Width(static_cast<long>(m_rectPosition.right * m_rectDest.Width()
  633. - (m_rectPosition.left * m_rectDest.Width())));
  634. if(FAILED(hr)){
  635. hr = ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  636. throw(hr);
  637. }
  638. hr = PQIMSVRect->put_Left(static_cast<long>(m_rectPosition.left * m_rectDest.Width()));
  639. if(FAILED(hr)){
  640. hr = ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  641. throw(hr);
  642. }
  643. }
  644. *ppIMSVRect = PQIMSVRect.Detach();
  645. return S_OK;
  646. }
  647. catch(HRESULT hres){
  648. if(FAILED(hres)){
  649. return hres;
  650. }
  651. if(m_rectDest){
  652. PQIMSVRect.Release();
  653. PQIMSVRect = static_cast<IMSVidRect *>(new CVidRect(m_rectDest));
  654. }
  655. else{
  656. PQIMSVRect.Release();
  657. PQIMSVRect = static_cast<IMSVidRect *>(new CVidRect(-1,-1,-1,-1));
  658. }
  659. *ppIMSVRect = PQIMSVRect.Detach();
  660. return S_FALSE;
  661. }
  662. catch(...){
  663. return E_UNEXPECTED;
  664. }
  665. }
  666. /**************************************************************************/
  667. /* Function: put_MixerBitmapPositionRect */
  668. /* Description: Lets script folk change the position of the overlay bitmap*/
  669. /* the units are normalized vs the display rect so the values*/
  670. /* should be between 0 and 1 though will be converted if they*/
  671. /* are not */
  672. /**************************************************************************/
  673. STDMETHOD(put_MixerBitmapPositionRect)(/*[in]*/ IMSVidRect *pIMSVRect){
  674. if(pIMSVRect){
  675. NORMALIZEDRECT NormalizedRectStruct;
  676. long lValue;
  677. NormalizedRectStruct.left = -1.f;
  678. NormalizedRectStruct.top = -1.f;
  679. NormalizedRectStruct.right = -1.f;
  680. NormalizedRectStruct.bottom = -1.f;
  681. if(SUCCEEDED(pIMSVRect->get_Left(&lValue))){
  682. if(m_rectDest.Width() != 0){
  683. // check m_rectDest.Width() for zero
  684. if(lValue > 0){
  685. NormalizedRectStruct.left =
  686. static_cast<float>(lValue)/static_cast<float>(m_rectDest.Width());
  687. }
  688. else{
  689. NormalizedRectStruct.left = static_cast<float>(lValue);
  690. }
  691. }
  692. }
  693. if(SUCCEEDED(pIMSVRect->get_Top(&lValue))){
  694. if(m_rectDest.Height() != 0){
  695. if(lValue > 0){
  696. NormalizedRectStruct.top =
  697. static_cast<float>(lValue)/static_cast<float>(m_rectDest.Height());
  698. }
  699. else{
  700. NormalizedRectStruct.top = static_cast<float>(lValue);
  701. }
  702. }
  703. }
  704. if(SUCCEEDED(pIMSVRect->get_Width(&lValue))){
  705. if(m_rectDest.Width() != 0){
  706. if(lValue > 0){
  707. NormalizedRectStruct.right =
  708. (static_cast<float>(lValue)/static_cast<float>(m_rectDest.Width()))
  709. + static_cast<float>(NormalizedRectStruct.left);
  710. }
  711. }
  712. }
  713. if(SUCCEEDED(pIMSVRect->get_Height(&lValue))){
  714. if(m_rectDest.Width() != 0){
  715. if(lValue > 0){
  716. NormalizedRectStruct.bottom =
  717. (static_cast<float>(lValue)/static_cast<float>(m_rectDest.Height()))
  718. + static_cast<float>(NormalizedRectStruct.top);
  719. }
  720. }
  721. }
  722. if(NormalizedRectStruct.top < 0 || NormalizedRectStruct.left < 0 ||
  723. NormalizedRectStruct.top > 1 || NormalizedRectStruct.left > 1 ||
  724. NormalizedRectStruct.right < 0 || NormalizedRectStruct.bottom < 0 ||
  725. NormalizedRectStruct.right > 1 || NormalizedRectStruct.bottom > 1){
  726. return ImplReportError(__uuidof(T), IDS_E_MIXERSRC, __uuidof(IMSVidVideoRenderer), CO_E_ERRORINAPP);
  727. }
  728. m_rectPosition = NormalizedRectStruct;
  729. }
  730. if(m_PQIPicture == NULL){
  731. return S_OK;
  732. }
  733. else{
  734. return SetupMixerBitmap(reinterpret_cast<IPictureDisp*>(-1));
  735. }
  736. }
  737. /**************************************************************************/
  738. /* Function: get_MixerBitmapOpacity */
  739. /* Description: lets script access the opacity value */
  740. /* should be between 0 and 100 (%) */
  741. /**************************************************************************/
  742. STDMETHOD(get_MixerBitmapOpacity)(/*[out,retval]*/ int *pwOpacity){
  743. CComQIPtr<IVMRMixerBitmap> PQIVMRMBitmap;
  744. VMRALPHABITMAP VMRAlphaBitmapStruct;
  745. HRESULT hr = get__MixerBitmap(&PQIVMRMBitmap);
  746. if(SUCCEEDED(hr)){
  747. hr = PQIVMRMBitmap->GetAlphaBitmapParameters(&VMRAlphaBitmapStruct);
  748. if(SUCCEEDED(hr)){
  749. if(m_opacity != VMRAlphaBitmapStruct.fAlpha){
  750. m_opacity = VMRAlphaBitmapStruct.fAlpha;
  751. }
  752. }
  753. }
  754. if(m_opacity == -1){
  755. return ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED);
  756. }
  757. if(m_opacity > 1 || m_opacity < 0){
  758. return E_UNEXPECTED;
  759. }
  760. *pwOpacity = static_cast<int>(m_opacity*100);
  761. return S_OK;
  762. }
  763. /**************************************************************************/
  764. /* Function: put_MixerBitmapOpacity */
  765. /* Description: lets script set the value opacity */
  766. /* should be between 0 and 100 (%) */
  767. /**************************************************************************/
  768. STDMETHOD(put_MixerBitmapOpacity)(/*[in]*/ int wOpacity){
  769. // make sure the value is between 0 and 100
  770. if(wOpacity >=0 && wOpacity <= 100){
  771. if(wOpacity == 0){
  772. //if it is 0 set it by hand instead of deviding by 0
  773. m_opacity = static_cast<float>(wOpacity);
  774. }
  775. m_opacity = static_cast<float>(wOpacity)/100.f;
  776. }
  777. else{
  778. return ImplReportError(__uuidof(T), IDS_E_OPACITY, __uuidof(IMSVidVideoRenderer), CO_E_ERRORINAPP);
  779. }
  780. if(!m_PQIPicture){
  781. return S_OK;
  782. }
  783. else{
  784. HRESULT hr = SetupMixerBitmap(reinterpret_cast<IPictureDisp*>(-1));
  785. return hr;
  786. }
  787. }
  788. /**************************************************************************/
  789. /* Function: SetupMixerBitmap */
  790. /* Description: big nasty function to set bitmap, opacity and the position*/
  791. /* rect. It wraps everyting up in a mixer bitmap struct and */
  792. /* then passes it off to put__MixerBitmap */
  793. /* It is both a helper function and a automation method so */
  794. /* that script people can make sure that transparent overlays*/
  795. /* dont show up opaque for a few frames */
  796. /* for reference the vmralphabitmap struct */
  797. /* typedef struct _VMRALPHABITMAP { */
  798. /* DWORD dwFlags;// flags word = VMRBITMAP_HDC */
  799. /* HDC hdc; // DC for the bitmap to copy */
  800. /* LPDIRECTDRAWSURFACE7 pDDS; // DirectDraw surface to copy IGNORED */
  801. /* RECT rSrc; // rectangle to copy from the sourceR */
  802. /* NORMALIZEDRECT rDest; // output rectangle in composition space*/
  803. /* FLOAT fAlpha; // opacity of the bitmap */
  804. /* } VMRALPHABITMAP, *PVMRALPHABITMAP; */
  805. /**************************************************************************/
  806. STDMETHOD(SetupMixerBitmap)(/*[in]*/ IPictureDisp* pIPDisp = NULL, /*[in]*/ long wOpacity = -1,
  807. /*[in]*/ IMSVidRect *pIMSVRect = NULL){
  808. VMRALPHABITMAP VMRAlphaBitmapStruct;
  809. ZeroMemory(&VMRAlphaBitmapStruct, sizeof(VMRALPHABITMAP));
  810. RECT rSource;
  811. ZeroMemory(&rSource, sizeof(RECT));
  812. long lPicHeight, lPicWidth;
  813. HRESULT hr = S_OK;
  814. try{
  815. if(!pIPDisp){
  816. if(m_PQIPicture){
  817. m_PQIPicture.Release();
  818. }
  819. VMRAlphaBitmapStruct.dwFlags = VMRBITMAP_DISABLE;
  820. return hr = put__MixerBitmap(&VMRAlphaBitmapStruct);
  821. }
  822. // Our input is a IPictureDisp which we need to massage into a VMRALPHABITMAP
  823. // Problem is that it does not quite all go in but what does we will keep and pass on up
  824. if(pIPDisp == reinterpret_cast<IPictureDisp*>(-1)){
  825. CComQIPtr<IPicture>PQIPicture(m_PQIPicture);
  826. if(!PQIPicture){
  827. return S_OK;
  828. }
  829. }
  830. else if(pIPDisp){
  831. // QI for a IPicture
  832. CComQIPtr<IPicture>PQIPicture(pIPDisp);
  833. if(!PQIPicture){
  834. return E_NOINTERFACE;
  835. }
  836. // Save the IPicture for possible use later
  837. m_PQIPicture = PQIPicture;
  838. }
  839. // Get the source rect size (and for some reason ole returns the size
  840. // in tenths of a millimeter so I need to convert it)
  841. short shortType;
  842. m_PQIPicture->get_Type(&shortType);
  843. if(shortType != PICTYPE_BITMAP){
  844. return ImplReportError(__uuidof(T), IDS_E_MIXERBADFORMAT, __uuidof(IMSVidVideoRenderer), E_INVALIDARG); // Need to add a the is not a valid picture string
  845. }
  846. hr = m_PQIPicture->get_Height(&lPicHeight);
  847. if(FAILED(hr)){
  848. return ImplReportError(__uuidof(T), IDS_E_IPICTURE, __uuidof(IMSVidVideoRenderer), CO_E_ERRORINAPP);
  849. }
  850. hr = m_PQIPicture->get_Width(&lPicWidth);
  851. if(FAILED(hr)){
  852. return ImplReportError(__uuidof(T), IDS_E_IPICTURE, __uuidof(IMSVidVideoRenderer), CO_E_ERRORINAPP);
  853. }
  854. SIZEL x, y;
  855. AtlHiMetricToPixel((const SIZEL*)&lPicWidth, &(x));
  856. AtlHiMetricToPixel((const SIZEL*)&lPicHeight, &(y));
  857. // The AtlHiMetricToPixel function returns a size with the cx value set (no idea why)
  858. rSource.right = x.cx;
  859. rSource.bottom = y.cx;
  860. // create a hdc to store the bitmap
  861. HDC memHDC = CreateCompatibleDC(NULL);
  862. // create a bitmap to store in the hdc
  863. HBITMAP memHBIT = 0;
  864. // pull out the bitmap from the IlPicture
  865. hr = m_PQIPicture->get_Handle(reinterpret_cast<OLE_HANDLE*>(&memHBIT));
  866. if(FAILED(hr)){
  867. return ImplReportError(__uuidof(T), IDS_E_IPICTURE, __uuidof(IMSVidVideoRenderer), CO_E_ERRORINAPP);
  868. }
  869. // Stuff the bitmap into a hdc and keep handle to delete bitmap later
  870. HBITMAP delHBIT = static_cast<HBITMAP>(SelectObject(memHDC, memHBIT));
  871. // Put all of the collected info into a VMRBITMAP stuct and pass it on
  872. VMRAlphaBitmapStruct.rSrc = rSource;
  873. VMRAlphaBitmapStruct.hdc = memHDC;
  874. VMRAlphaBitmapStruct.dwFlags = VMRBITMAP_HDC;
  875. // If the wOpacity value is valid use it
  876. if(wOpacity >=0 && wOpacity <= 100){
  877. if(wOpacity == 0){
  878. m_opacity = wOpacity;
  879. }
  880. m_opacity = static_cast<float>(wOpacity/100.f);
  881. VMRAlphaBitmapStruct.fAlpha = static_cast<float>(m_opacity);
  882. }
  883. // wOpacity is not set so check other values
  884. // if m_opacity is set use it, if not default to 50% (.5)
  885. else if (wOpacity == -1){
  886. if(m_opacity < 0){
  887. VMRAlphaBitmapStruct.fAlpha = .5f;
  888. }
  889. else{
  890. VMRAlphaBitmapStruct.fAlpha = m_opacity;
  891. }
  892. }
  893. // Bad wOpacity value give them an error
  894. else{
  895. return ImplReportError(__uuidof(T), IDS_E_OPACITY, __uuidof(IMSVidVideoRenderer), CO_E_ERRORINAPP);
  896. }
  897. // If the m_rectPostion is set use it, else default to full screen
  898. if(pIMSVRect){
  899. NORMALIZEDRECT NormalizedRectStruct;
  900. long lValue;
  901. NormalizedRectStruct.left = -1.f;
  902. NormalizedRectStruct.top = -1.f;
  903. NormalizedRectStruct.right = -1.f;
  904. NormalizedRectStruct.bottom = -1.f;
  905. if(SUCCEEDED(pIMSVRect->get_Left(&lValue))){
  906. if(m_rectDest.Width() != 0){
  907. // check m_rectDest.Width() for zero
  908. if(lValue > 0){
  909. NormalizedRectStruct.left =
  910. static_cast<float>(lValue)/static_cast<float>(m_rectDest.Width());
  911. }
  912. else{
  913. NormalizedRectStruct.left = static_cast<float>(lValue);
  914. }
  915. }
  916. }
  917. if(SUCCEEDED(pIMSVRect->get_Top(&lValue))){
  918. if(m_rectDest.Height() != 0){
  919. if(lValue > 0){
  920. NormalizedRectStruct.top =
  921. static_cast<float>(lValue)/static_cast<float>(m_rectDest.Height());
  922. }
  923. else{
  924. NormalizedRectStruct.top = static_cast<float>(lValue);
  925. }
  926. }
  927. }
  928. if(SUCCEEDED(pIMSVRect->get_Width(&lValue))){
  929. if(m_rectDest.Width() != 0){
  930. if(lValue > 0){
  931. NormalizedRectStruct.right =
  932. (static_cast<float>(lValue)/static_cast<float>(m_rectDest.Width()))
  933. + static_cast<float>(NormalizedRectStruct.left);
  934. }
  935. }
  936. }
  937. if(SUCCEEDED(pIMSVRect->get_Height(&lValue))){
  938. if(m_rectDest.Width() != 0){
  939. if(lValue > 0){
  940. NormalizedRectStruct.bottom =
  941. (static_cast<float>(lValue)/static_cast<float>(m_rectDest.Height()))
  942. + static_cast<float>(NormalizedRectStruct.top);
  943. }
  944. }
  945. }
  946. if(NormalizedRectStruct.top < 0 || NormalizedRectStruct.left < 0 ||
  947. NormalizedRectStruct.top > 1 || NormalizedRectStruct.left > 1 ||
  948. NormalizedRectStruct.right < 0 || NormalizedRectStruct.bottom < 0 ||
  949. NormalizedRectStruct.right > 1 || NormalizedRectStruct.bottom > 1){
  950. return ImplReportError(__uuidof(T), IDS_E_MIXERSRC, __uuidof(IMSVidVideoRenderer), CO_E_ERRORINAPP);
  951. }
  952. m_rectPosition = NormalizedRectStruct;
  953. VMRAlphaBitmapStruct.rDest = m_rectPosition;
  954. }
  955. else{
  956. if( m_rectPosition.left < 0 || m_rectPosition.top < 0 || m_rectPosition.right < 0 || m_rectPosition.bottom < 0 ){
  957. VMRAlphaBitmapStruct.rDest.left = 0.f;
  958. VMRAlphaBitmapStruct.rDest.top = 0.f;
  959. VMRAlphaBitmapStruct.rDest.right = 1.f;
  960. VMRAlphaBitmapStruct.rDest.bottom = 1.f;
  961. }
  962. else{
  963. VMRAlphaBitmapStruct.rDest = m_rectPosition;
  964. }
  965. }
  966. // If it is all valid then this is all good
  967. hr = put__MixerBitmap(&VMRAlphaBitmapStruct);
  968. if(!DeleteDC(memHDC)){
  969. return ImplReportError(__uuidof(T), IDS_E_CANT_DELETE, __uuidof(IMSVidVideoRenderer), ERROR_DS_CANT_DELETE);
  970. }
  971. if(SUCCEEDED(hr)){
  972. return S_OK;
  973. }
  974. else{
  975. return hr;
  976. }
  977. }
  978. catch(...){
  979. return E_UNEXPECTED;
  980. }
  981. }
  982. STDMETHOD(get_UsingOverlay)(/*[out, retval]*/ VARIANT_BOOL *pfUseOverlay) {
  983. return get_UseOverlay(pfUseOverlay);
  984. }
  985. STDMETHOD(put_UsingOverlay)(/*[in]*/ VARIANT_BOOL fUseOverlayVal) {
  986. return put_UseOverlay(fUseOverlayVal);
  987. }
  988. STDMETHOD(get_FramesPerSecond)(/*[out, retval]*/ long *pVal){
  989. try{
  990. if(pVal){
  991. if(!m_pVMR){
  992. throw(ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED));
  993. }
  994. IQualProp *IQProp = NULL;
  995. HRESULT hr = m_pVMR->QueryInterface(IID_IQualProp, reinterpret_cast<void**>(&IQProp));
  996. if(FAILED(hr)){
  997. return hr;
  998. }
  999. if(!IQProp){
  1000. return E_NOINTERFACE;
  1001. }
  1002. hr = IQProp->get_AvgFrameRate(reinterpret_cast<int*>(pVal));
  1003. IQProp->Release();
  1004. return hr;
  1005. }
  1006. else{
  1007. return E_POINTER;
  1008. }
  1009. }
  1010. catch(...){
  1011. return E_UNEXPECTED;
  1012. }
  1013. }
  1014. STDMETHOD(put_DecimateInput)(/*[in]*/ VARIANT_BOOL bDeci){
  1015. try{
  1016. if(bDeci != VARIANT_TRUE && bDeci != VARIANT_FALSE){
  1017. return E_INVALIDARG;
  1018. }
  1019. m_Decimate = (bDeci == VARIANT_TRUE);
  1020. if(!m_pVMR){
  1021. return S_OK;
  1022. }
  1023. DWORD curPrefs;
  1024. DWORD deci;
  1025. CComQIPtr<IVMRMixerControl>PQIVMRMixer(m_pVMR);
  1026. if(!PQIVMRMixer){
  1027. return E_UNEXPECTED;
  1028. }
  1029. HRESULT hr = PQIVMRMixer->GetMixingPrefs(&curPrefs);
  1030. if(FAILED(hr)){
  1031. return hr;
  1032. }
  1033. deci = (m_Decimate?MixerPref_DecimateOutput:MixerPref_NoDecimation);
  1034. if(!(curPrefs&deci)){
  1035. hr = CleanupVMR();
  1036. if(FAILED(hr)){
  1037. return hr;
  1038. }
  1039. }
  1040. return NOERROR;
  1041. }
  1042. catch(...){
  1043. return E_UNEXPECTED;
  1044. }
  1045. }
  1046. STDMETHOD(get_DecimateInput)(/*[out,retval]*/ VARIANT_BOOL *pDeci){
  1047. try{
  1048. if(!pDeci){
  1049. return E_POINTER;
  1050. }
  1051. if(!m_pVMR){
  1052. throw(ImplReportError(__uuidof(T), IDS_OBJ_NO_INIT, __uuidof(IMSVidVideoRenderer), CO_E_NOTINITIALIZED));
  1053. }
  1054. DWORD curPrefs;
  1055. CComQIPtr<IVMRMixerControl>PQIVMRMixer(m_pVMR);
  1056. if(!PQIVMRMixer){
  1057. return E_UNEXPECTED;
  1058. }
  1059. HRESULT hr = PQIVMRMixer->GetMixingPrefs(&curPrefs);
  1060. if(FAILED(hr)){
  1061. return hr;
  1062. }
  1063. *pDeci = ((curPrefs&MixerPref_DecimateMask)==MixerPref_DecimateOutput)? VARIANT_TRUE : VARIANT_FALSE;
  1064. return NOERROR;
  1065. }
  1066. catch(...){
  1067. return E_UNEXPECTED;
  1068. }
  1069. }
  1070. STDMETHOD(ReComputeSourceRect)() {
  1071. switch (m_SourceSize) {
  1072. case sslFullSize: {
  1073. CSize sz;
  1074. CSize ar;
  1075. if(m_pVMRWC){
  1076. HRESULT hr = m_pVMRWC->GetNativeVideoSize(&sz.cx, &sz.cy, &ar.cx, &ar.cy);
  1077. if (FAILED(hr)) {
  1078. return hr;
  1079. }
  1080. TRACELSM(TRACE_PAINT, (dbgDump << "CMSVidVideoRenderer::ReComputeSourceRect() sslFullSize vmr sz = " << sz), "");
  1081. }
  1082. CRect r(0, 0, sz.cx, sz.cy);
  1083. TRACELSM(TRACE_DETAIL, (dbgDump << "CMSVidVideoRenderer::ReComputeSource() full = " << r), "");
  1084. return put_Source(r);
  1085. } break;
  1086. case sslClipByOverScan: {
  1087. CSize sz;
  1088. CSize ar;
  1089. if(m_pVMRWC){
  1090. HRESULT hr = m_pVMRWC->GetNativeVideoSize(&sz.cx, &sz.cy, &ar.cx, &ar.cy);
  1091. if (FAILED(hr)) {
  1092. return hr;
  1093. }
  1094. TRACELSM(TRACE_PAINT, (dbgDump << "CMSVidVideoRenderer::ReComputeSourceRect() sslClipByOverScan vmr sz = " << sz), "");
  1095. }
  1096. CRect r(0, 0, sz.cx, sz.cy);
  1097. CRect r2;
  1098. float fpct = m_lOverScan / 10000.0; // overscan is in hundredths of pct, i.e 1.75% == 175
  1099. long wcrop = (long)(r.Width() * fpct + 0.5);
  1100. long hcrop = (long)(r.Height() * fpct + 0.5);
  1101. r2.left = 0 + wcrop;
  1102. r2.top = 0 + hcrop;
  1103. r2.right = r2.left + r.Width() - (2.0 * wcrop);
  1104. r2.bottom = r2.top + r.Height() - (2.0 * hcrop);
  1105. TRACELSM(TRACE_DETAIL, (dbgDump << "CMSVidVideoRenderer::ReComputeSource() over = " << m_lOverScan <<
  1106. " w " << wcrop <<
  1107. " h " << hcrop), "");
  1108. TRACELSM(TRACE_DETAIL, (dbgDump << "CMSVidVideoRenderer::ReComputeSource() full = " << r << " clip = " << r2), "");
  1109. return put_Source(r2);
  1110. } break;
  1111. case sslClipByClipRect: {
  1112. TRACELSM(TRACE_DETAIL, (dbgDump << "CMSVidVideoRenderer::ReComputeSource() cliprect = " << m_ClipRect), "");
  1113. if(m_ClipRect.Width() == 0 && m_ClipRect.Height() == 0){
  1114. CSize sz;
  1115. CSize ar;
  1116. if(m_pVMRWC){
  1117. HRESULT hr = m_pVMRWC->GetNativeVideoSize(&sz.cx, &sz.cy, &ar.cx, &ar.cy);
  1118. if (FAILED(hr)) {
  1119. return hr;
  1120. }
  1121. TRACELSM(TRACE_PAINT, (dbgDump << "CMSVidVideoRenderer::ReComputeSourceRect() sslClipByClipRect vmr sz = " << sz), "");
  1122. }
  1123. CRect r(0, 0, sz.cx, sz.cy);
  1124. TRACELSM(TRACE_DETAIL, (dbgDump << "CMSVidVideoRenderer::ReComputeSource() full = " << r), "");
  1125. return put_Source(r);
  1126. } else{
  1127. TRACELSM(TRACE_PAINT, (dbgDump << "CMSVidVideoRenderer::ReComputeSourceRect() sslClipByClipRect cliprect = " << m_ClipRect), "");
  1128. return put_Source(m_ClipRect);
  1129. }
  1130. } break;
  1131. default:{
  1132. return E_INVALIDARG;
  1133. } break;
  1134. }
  1135. return NOERROR;
  1136. }
  1137. };
  1138. #endif //__MSVidVIDEORENDERER_H_