VideoRendererOverlay.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:21k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /**************************************************************************************
  2.  *                                                                                    *
  3.  *                                                                                    *
  4.  **************************************************************************************/
  5. #include "VideoRendererOverlay.h"
  6. DDPIXELFORMAT ddpfOverlayFormats[] = 
  7. {   
  8. {sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('Y','U','Y','2'),0,0,0,0,0},  // YUY2
  9. {sizeof(DDPIXELFORMAT), DDPF_FOURCC,MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0},  // UYVY
  10. };
  11. media_video_mode_t videoModes[] = 
  12. {
  13. VIDEO_MODE_YUY2,
  14. VIDEO_MODE_UYVY,
  15. };
  16. MediaVideoRendererOverlay::MediaVideoRendererOverlay()
  17. {
  18. this->subtitler    = NULL;
  19. this->lpdd         = NULL;
  20. this->lpddsPrimary = NULL;
  21. this->lpddsOverlay = NULL;
  22. this->videoMode    = VIDEO_MODE_NONE;
  23. }
  24. MediaVideoRendererOverlay::~MediaVideoRendererOverlay()
  25. {
  26. }
  27. media_type_t MediaVideoRendererOverlay::GetType()
  28. {
  29. return MEDIA_TYPE_VIDEO_RENDERER;
  30. }
  31. char *MediaVideoRendererOverlay::GetName()
  32. {
  33. return "Overlay Video Renderer";
  34. }
  35. MP_RESULT MediaVideoRendererOverlay::Connect(MediaItem *item)
  36. {
  37. if(item && item->GetType() == MEDIA_TYPE_SUBTITLER) {
  38. this->subtitler = (MediaItemSubtitler *) item;
  39. return MP_RESULT_OK;
  40. }
  41. return MP_RESULT_ERROR;
  42. }
  43. MP_RESULT MediaVideoRendererOverlay::ReleaseConnections()
  44. {
  45. this->subtitler   = NULL;
  46. return MP_RESULT_OK;
  47. }
  48. DWORD         MediaVideoRendererOverlay::GetCaps()
  49. {
  50. return 0;
  51. }
  52. MP_RESULT     MediaVideoRendererOverlay::Configure(HINSTANCE hInstance, HWND hwnd)
  53. {
  54. return MP_RESULT_ERROR;
  55. }
  56. BOOL MediaVideoRendererOverlay::AreOverlaysSupported()
  57. {
  58.     DDCAPS  capsDrv;
  59.     HRESULT ddrval;
  60.     ZeroMemory(&capsDrv, sizeof(capsDrv));
  61.     capsDrv.dwSize = sizeof(capsDrv);
  62.  
  63.     ddrval = this->lpdd->GetCaps(&capsDrv, NULL);
  64.     
  65. if (FAILED(ddrval))
  66.         return FALSE;
  67.  
  68.     if (!(capsDrv.dwCaps & DDCAPS_OVERLAY))
  69.         return FALSE;
  70.     return TRUE;
  71. }
  72. MP_RESULT MediaVideoRendererOverlay::Init(HWND hwnd, unsigned int width, unsigned int height)
  73. {
  74. if(hwnd && width > 0 && height > 0) {
  75. HRESULT         ddrval;
  76.     DDSURFACEDESC2  ddsd;
  77.     DDSURFACEDESC2  ddsdOverlay;
  78. DWORD           i;
  79.     
  80. this->invertFlag  = FALSE;
  81. ddrval = DirectDrawCreateEx(NULL, (VOID**)&this->lpdd, IID_IDirectDraw7, NULL);
  82. if( FAILED(ddrval))
  83. return MP_RESULT_ERROR;
  84.     
  85. /*
  86.  * 检查是否支持叠加
  87.  */
  88. if(!this->AreOverlaysSupported()) {
  89.         this->lpdd->Release();
  90. this->lpdd=NULL;
  91. return MP_RESULT_ERROR;
  92. }
  93. ddrval = this->lpdd->SetCooperativeLevel(NULL, DDSCL_NORMAL);
  94. if( FAILED(ddrval)) {
  95.         this->lpdd->Release();
  96. this->lpdd=NULL;
  97. return MP_RESULT_ERROR;
  98. }
  99.    
  100.     ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
  101. ddsd.dwSize  = sizeof(DDSURFACEDESC2);
  102. ddsd.dwFlags = DDSD_CAPS;
  103. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  104.     
  105. ddrval = this->lpdd->CreateSurface(&ddsd, &this->lpddsPrimary, NULL );
  106. if(FAILED(ddrval)) {
  107. this->lpdd->Release();
  108.     this->lpdd=NULL;
  109. return MP_RESULT_ERROR;
  110. }
  111.     ddrval = this->lpdd->CreateClipper(0, &this->lpddClipper, NULL);
  112. if(FAILED(ddrval)) {
  113. return MP_RESULT_ERROR;
  114. }
  115.     ddrval = this->lpddClipper->SetHWnd(0, hwnd);
  116. if(FAILED(ddrval)) {
  117. return MP_RESULT_ERROR;
  118. }
  119.     ddrval = this->lpddsPrimary->SetClipper(this->lpddClipper);
  120.     
  121.     ZeroMemory(&ddsdOverlay, sizeof(DDSURFACEDESC2));
  122. ddsdOverlay.dwSize  = sizeof(DDSURFACEDESC2);
  123.     ddsdOverlay.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
  124. ddsdOverlay.dwFlags= DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
  125. ddsdOverlay.dwWidth           = width;
  126. ddsdOverlay.dwHeight          = height;
  127.     
  128.     i = 0;
  129.     
  130. do {
  131. ddsdOverlay.ddpfPixelFormat = ddpfOverlayFormats[i];
  132. this->videoMode = videoModes[i];
  133.    ddrval = this->lpdd->CreateSurface(&ddsdOverlay, &this->lpddsOverlay, NULL);
  134. } while( FAILED(ddrval) && (++i < 2) );
  135. if(FAILED(ddrval)) {
  136.     ZeroMemory(&ddsdOverlay, sizeof(DDSURFACEDESC2));
  137. ddsdOverlay.dwSize     = sizeof(DDSURFACEDESC2);
  138. ddsdOverlay.dwWidth           = width;
  139. ddsdOverlay.dwHeight          = height;
  140.         ddsdOverlay.dwBackBufferCount = 0;
  141. ddsdOverlay.ddsCaps.dwCaps    = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
  142. ddsdOverlay.dwFlags           = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
  143.         
  144.     i = 0;
  145.     
  146. do {
  147. ddsdOverlay.ddpfPixelFormat = ddpfOverlayFormats[i];
  148. this->videoMode = videoModes[i];
  149.   ddrval = this->lpdd->CreateSurface(&ddsdOverlay, &this->lpddsOverlay, NULL);
  150. } while( FAILED(ddrval) && (++i < 2) );
  151.         
  152. if (FAILED(ddrval)) {
  153. this->lpddsPrimary->Release();
  154. this->lpddsPrimary = NULL;
  155.         this->lpdd->Release();
  156. this->lpdd=NULL;
  157. this->videoMode = VIDEO_MODE_NONE;
  158.             return MP_RESULT_ERROR;
  159. }
  160. }
  161. if(FAILED(ddrval)) {
  162. return MP_RESULT_ERROR;
  163. }
  164. this->width  = width;
  165. this->height = height;
  166. this->bpp    = 16;
  167. ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
  168. ddsd.dwSize     = sizeof(DDSURFACEDESC2);
  169. ddrval = this->lpddsPrimary->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY | DDLOCK_WAIT, NULL);
  170. if(FAILED(ddrval)) {
  171. return MP_RESULT_ERROR;
  172. }
  173. this->lpddsPrimary->Unlock(NULL);
  174. switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {
  175. case 8:
  176. return MP_RESULT_ERROR;
  177. break;
  178. case 16:
  179. this->physicalDepth = 16;
  180. break;
  181. case 24:
  182. this->physicalDepth = 24;
  183. break;
  184. case 32:
  185. this->physicalDepth = 32;
  186. break;
  187. }
  188. ddrval = this->lpdd->GetDisplayMode(&ddsd);
  189. this->fullscreenWidth  = ddsd.dwWidth;
  190. this->fullscreenHeight = ddsd.dwHeight;
  191. this->hwndPlayback = hwnd;
  192. return MP_RESULT_OK;
  193. }
  194.     
  195. return MP_RESULT_ERROR;
  196. }
  197. MP_RESULT MediaVideoRendererOverlay::InitFullscreen(HWND hwnd, unsigned int width, unsigned int height)
  198. {
  199. if(hwnd && width > 0 && height > 0) {
  200. HRESULT         ddrval;
  201.     DDSURFACEDESC2  ddsd;
  202.     DDSURFACEDESC2  ddsdOverlay;
  203. DWORD           i;
  204. this->invertFlag  = FALSE;
  205.     
  206.     ddrval = DirectDrawCreateEx(NULL, (VOID**)&this->lpdd, IID_IDirectDraw7, NULL);
  207. if( FAILED(ddrval))
  208. return MP_RESULT_ERROR;
  209.   
  210. if(!this->AreOverlaysSupported()) {
  211.         this->lpdd->Release();
  212. this->lpdd=NULL;
  213. return MP_RESULT_ERROR;
  214. }
  215. ddrval = this->lpdd->SetCooperativeLevel(hwnd, DDSCL_NORMAL);
  216. if( FAILED(ddrval)) {
  217.         this->lpdd->Release();
  218. this->lpdd = NULL;
  219. return MP_RESULT_ERROR;
  220. }
  221. DDSURFACEDESC2 ddDesc;
  222. memset(&ddDesc, 0, sizeof(DDSURFACEDESC2));
  223. ddDesc.dwSize    = sizeof(DDSURFACEDESC2);
  224. ddrval = this->lpdd->GetDisplayMode(&ddDesc);
  225. if(FAILED(ddrval)) {
  226.         this->lpdd->Release();
  227. this->lpdd=NULL;
  228. return MP_RESULT_ERROR;;
  229. }
  230. this->fullscreenWidth  = ddDesc.dwWidth;
  231. this->fullscreenHeight = ddDesc.dwHeight;
  232.    
  233.     ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
  234. ddsd.dwSize  = sizeof(DDSURFACEDESC2);
  235. ddsd.dwFlags = DDSD_CAPS;
  236. ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
  237.     
  238. ddrval = this->lpdd->CreateSurface(&ddsd, &this->lpddsPrimary, NULL );
  239. if(FAILED(ddrval)) {
  240. this->lpdd->Release();
  241.     this->lpdd=NULL;
  242. return MP_RESULT_ERROR;
  243. }
  244.     
  245.     ZeroMemory(&ddsdOverlay, sizeof(DDSURFACEDESC2));
  246. ddsdOverlay.dwSize  = sizeof(DDSURFACEDESC2);
  247.     ddsdOverlay.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
  248. ddsdOverlay.dwFlags= DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
  249. ddsdOverlay.dwWidth           = width;
  250. ddsdOverlay.dwHeight          = height;
  251.     
  252.     i = 0;
  253.     
  254. do {
  255. ddsdOverlay.ddpfPixelFormat = ddpfOverlayFormats[i];
  256. this->videoMode = videoModes[i];
  257.    ddrval = this->lpdd->CreateSurface(&ddsdOverlay, &this->lpddsOverlay, NULL);
  258. } while( FAILED(ddrval) && (++i < 2) );
  259. if(FAILED(ddrval)) {
  260.     ZeroMemory(&ddsdOverlay, sizeof(DDSURFACEDESC2));
  261. ddsdOverlay.dwSize     = sizeof(DDSURFACEDESC2);
  262. ddsdOverlay.dwWidth           = width;
  263. ddsdOverlay.dwHeight          = height;
  264.         ddsdOverlay.dwBackBufferCount = 0;
  265. ddsdOverlay.ddsCaps.dwCaps    = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
  266. ddsdOverlay.dwFlags           = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
  267.         
  268.     i = 0;
  269.     
  270. do {
  271. ddsdOverlay.ddpfPixelFormat = ddpfOverlayFormats[i];
  272. this->videoMode = videoModes[i];
  273.   ddrval = this->lpdd->CreateSurface(&ddsdOverlay, &this->lpddsOverlay, NULL);
  274. } while( FAILED(ddrval) && (++i < 2) );
  275.         
  276. if (FAILED(ddrval)) {
  277. this->lpddsPrimary->Release();
  278. this->lpddsPrimary = NULL;
  279.         this->lpdd->Release();
  280. this->lpdd=NULL;
  281. this->videoMode = VIDEO_MODE_NONE;
  282.             return MP_RESULT_ERROR;
  283. }
  284. }
  285. if(FAILED(ddrval)) {
  286. return MP_RESULT_ERROR;
  287. }
  288. this->width  = width;
  289. this->height = height;
  290. this->bpp    = 16;
  291. this->hwndPlayback = hwnd;
  292. return MP_RESULT_OK;
  293. }
  294.     
  295. return MP_RESULT_ERROR;
  296. }
  297. MP_RESULT MediaVideoRendererOverlay::Stop()
  298. {
  299. if(this->lpdd && this->lpddsOverlay) {
  300. this->lpddsOverlay->UpdateOverlay(NULL, this->lpddsPrimary, NULL, DDOVER_HIDE, NULL);
  301. }
  302. return MP_RESULT_OK;
  303. }
  304. media_video_mode_t MediaVideoRendererOverlay::GetVideoMode()
  305. {
  306. return this->videoMode;
  307. }
  308. RECT *MediaVideoRendererOverlay::GetFullscreenRects()
  309. {
  310. DWORD width, height;
  311. switch(options.aspect_ratio) {
  312. case ASPECT_RATIO_FREE:
  313. case ASPECT_RATIO_ORIGINAL:
  314. width  = this->width;
  315. height = this->height;
  316. break;
  317. case ASPECT_RATIO_TV:
  318. case ASPECT_RATIO_WIDE:
  319. case ASPECT_RATIO_CUSTOM:
  320. if(aspectRatios[options.aspect_ratio].yFactor < aspectRatios[options.aspect_ratio].xFactor) {
  321. width  = this->width;
  322. height = this->width*aspectRatios[options.aspect_ratio].yFactor/aspectRatios[options.aspect_ratio].xFactor;
  323. }
  324. else {
  325. height = this->height;
  326. width  = this->height*aspectRatios[options.aspect_ratio].xFactor/aspectRatios[options.aspect_ratio].yFactor;
  327. }
  328. break;
  329. }
  330. if(this->fullscreenWidth * height / width > this->fullscreenHeight) {
  331. this->fullRects[0].left   = 0;
  332. this->fullRects[0].right  = (this->fullscreenWidth - (width * this->fullscreenHeight / height)) / 2;
  333. this->fullRects[0].top    = 0;
  334. this->fullRects[0].bottom = this->fullscreenHeight + 10;
  335. this->fullRects[1].left   = (this->fullscreenWidth - (width * this->fullscreenHeight / height)) / 2;
  336. this->fullRects[1].right  = (width * this->fullscreenHeight / height);
  337. this->fullRects[1].top    = 0;
  338. this->fullRects[1].bottom = this->fullscreenHeight + 10;
  339. this->fullRects[2].left   = this->fullRects[1].left + this->fullRects[1].right;
  340. this->fullRects[2].right  = (this->fullscreenWidth - (width * this->fullscreenHeight / height)) / 2;
  341. this->fullRects[2].top    = 0;
  342. this->fullRects[2].bottom = this->fullscreenHeight + 10;
  343. }
  344. else {
  345. this->fullRects[0].left   = 0;
  346. this->fullRects[0].right  = this->fullscreenWidth;
  347. this->fullRects[0].top    = 0;
  348. this->fullRects[0].bottom = (this->fullscreenHeight - (this->fullscreenWidth * height / width)) / 2;
  349. this->fullRects[1].left   = 0;
  350. this->fullRects[1].right  = this->fullscreenWidth;
  351. this->fullRects[1].top    = (this->fullscreenHeight - (this->fullscreenWidth * height / width)) / 2;
  352. this->fullRects[1].bottom = this->fullscreenWidth * height / width;
  353. this->fullRects[2].left   = 0;
  354. this->fullRects[2].right  = this->fullscreenWidth;
  355. this->fullRects[2].top    = this->fullRects[1].top + this->fullRects[1].bottom;
  356. this->fullRects[2].bottom = (this->fullscreenHeight - (this->fullscreenWidth * height / width)) / 2;
  357. }
  358. return this->fullRects;
  359. }
  360. MP_RESULT MediaVideoRendererOverlay::Draw(MediaBuffer *buffer, RECT *rect, int frameNumber, int invertFlag)
  361. {
  362. if(buffer && rect && this->lpdd && this->lpddsPrimary && this->lpddsOverlay) {
  363. POINT           pt;
  364.     HRESULT         ddrval;
  365.     RECT            rs, rd;
  366. DDOVERLAYFX     ovfx;
  367. DDSURFACEDESC2  ddsd;
  368. DDCAPS          capsDrv;
  369. unsigned int    uStretchFactor1000, i;
  370. unsigned int    uDestSizeAlign, uSrcSizeAlign;
  371. DWORD           dwUpdateFlags;
  372.        subtitles_t    *sub;
  373.  
  374. ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
  375. ddsd.dwSize     = sizeof(DDSURFACEDESC2);
  376. ddrval = this->lpddsOverlay->Lock( NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
  377.  
  378. if(FAILED(ddrval)) {
  379. return MP_RESULT_ERROR;
  380. }
  381. if(invertFlag) {
  382. for(i = 0; i < ddsd.dwHeight; i++) {
  383. memcpy((char *) ddsd.lpSurface + i*ddsd.lPitch, ((char *) buffer->GetData()) + (this->height - i - 1)*ddsd.dwWidth*this->bpp/8, ddsd.dwWidth*this->bpp/8);
  384. }
  385. }
  386. else {
  387. if(ddsd.dwWidth == ddsd.lPitch || this->videoMode == VIDEO_MODE_YUV12) {
  388. memcpy(ddsd.lpSurface, buffer->GetData(), this->width*this->height*this->bpp/8);
  389. }
  390. else {
  391. for(i = 0; i < ddsd.dwHeight; i++) {
  392. memcpy((char *) ddsd.lpSurface + i*ddsd.lPitch, ((char *) buffer->GetData()) + i*ddsd.dwWidth*this->bpp/8, ddsd.dwWidth*this->bpp/8);
  393. }
  394. }
  395. }
  396. this->lpddsOverlay->Unlock(NULL);
  397. ZeroMemory(&capsDrv, sizeof(DDCAPS));
  398. capsDrv.dwSize    = sizeof(DDCAPS);
  399. ddrval = this->lpdd->GetCaps(&capsDrv, NULL);
  400. if (FAILED(ddrval))
  401. return MP_RESULT_ERROR;
  402.     
  403. uStretchFactor1000 = capsDrv.dwMinOverlayStretch > 1000 ? capsDrv.dwMinOverlayStretch : 1000;
  404.     
  405. uDestSizeAlign = capsDrv.dwAlignSizeDest;
  406.     uSrcSizeAlign =  capsDrv.dwAlignSizeSrc;
  407.     
  408.     dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE;
  409.     
  410. if (capsDrv.dwCKeyCaps & DDCKEYCAPS_SRCOVERLAY)
  411. dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE;
  412.     
  413. ZeroMemory(&ovfx, sizeof(DDOVERLAYFX));
  414. ovfx.dwSize     = sizeof(DDOVERLAYFX);
  415. switch(this->physicalDepth) {
  416. case 16:
  417. ovfx.dckSrcColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_16BPP;
  418. ovfx.dckSrcColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;
  419.     
  420. ovfx.dckDestColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_16BPP;
  421. ovfx.dckDestColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;
  422. break;
  423. case 24:
  424. case 32:
  425. default:
  426. ovfx.dckSrcColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_32BPP;
  427. ovfx.dckSrcColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_32BPP;
  428.     
  429. ovfx.dckDestColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_32BPP;
  430. ovfx.dckDestColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_32BPP;
  431. break;
  432. }
  433. pt.x = 0;
  434. pt.y = 0;
  435. ClientToScreen(this->hwndPlayback, &pt);
  436.     rd.left   = pt.x + rect->left; 
  437. rd.top    = pt.y + rect->top; 
  438. rd.right  = pt.x + rect->left + (rect->right  * uStretchFactor1000 + 999) / 1000;
  439. rd.bottom = pt.y + rect->bottom * uStretchFactor1000 / 1000;
  440. if (capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST && uDestSizeAlign)
  441. rd.right = (int)((rd.right + uDestSizeAlign - 1) / uDestSizeAlign) * uDestSizeAlign;
  442. rs.left   = 0; 
  443. rs.top    = 0; 
  444. rs.right  = this->width;
  445. rs.bottom = this->height;
  446. if(rd.right < this->fullscreenWidth && rd.left > 0 && rd.top > 0 && rd.bottom < this->fullscreenHeight) {
  447. }
  448. else {
  449. if(rd.right > this->fullscreenWidth) {
  450. rs.right  = (this->fullscreenWidth - rd.left) * this->width / (rd.right - rd.left);
  451. rd.right = this->fullscreenWidth;
  452. }
  453. if(rd.left < 0) {
  454. rs.left = -rd.left * this->width / (rd.right - rd.left);
  455. rd.left = 0;
  456. }
  457. if(rd.bottom > this->fullscreenHeight) {
  458. rs.bottom  = (this->fullscreenHeight - rd.top) * this->height / (rd.bottom - rd.top);
  459. rd.bottom = this->fullscreenHeight;
  460. }
  461. if(rd.top < 0) {
  462. rs.top = -rd.top * this->height / (rd.bottom - rd.top);
  463. rd.top = 0;
  464. }
  465. }
  466.    
  467. if (capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC && uSrcSizeAlign)
  468. rs.right -= rs.right % uSrcSizeAlign;
  469. ddrval = this->lpddsOverlay->UpdateOverlay(&rs, this->lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
  470.     
  471. if(FAILED(ddrval)) {
  472.       
  473. return MP_RESULT_ERROR;
  474. }
  475.     
  476. return MP_RESULT_OK;
  477. }
  478. return MP_RESULT_ERROR;
  479. }
  480. MP_RESULT MediaVideoRendererOverlay::DrawFullscreen(MediaBuffer *buffer, int frameNumber, int invertFlag, int desktop)
  481. {
  482. if(buffer && this->lpdd && this->lpddsPrimary && this->lpddsOverlay) {
  483. HRESULT         ddrval;
  484.     RECT            rs, rd;
  485. DDOVERLAYFX     ovfx;
  486. DDSURFACEDESC2  ddsd;
  487. DDCAPS          capsDrv;
  488. unsigned int    uStretchFactor1000, i;
  489. unsigned int    uDestSizeAlign, uSrcSizeAlign;
  490. DWORD           dwUpdateFlags;
  491.  
  492. ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
  493. ddsd.dwSize     = sizeof(DDSURFACEDESC2);
  494. ddrval = this->lpddsOverlay->Lock( NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
  495.  
  496. if(FAILED(ddrval)) {
  497. return MP_RESULT_ERROR;
  498. }
  499. if(invertFlag) {
  500. for(i = 0; i < ddsd.dwHeight; i++) {
  501. memcpy((char *) ddsd.lpSurface + i*ddsd.lPitch, ((char *) buffer->GetData()) + (this->height - i - 1)*ddsd.dwWidth*this->bpp/8, ddsd.dwWidth*this->bpp/8);
  502. }
  503. }
  504. else {
  505. if(ddsd.dwWidth == ddsd.lPitch) {
  506. memcpy(ddsd.lpSurface, buffer->GetData(), this->width*this->height*this->bpp/8);
  507. }
  508. else {
  509. for(i = 0; i < ddsd.dwHeight; i++) {
  510. memcpy((char *) ddsd.lpSurface + i*ddsd.lPitch, ((char *) buffer->GetData()) + i*ddsd.dwWidth*this->bpp/8, ddsd.dwWidth*this->bpp/8);
  511. }
  512. }
  513. }
  514. this->lpddsOverlay->Unlock(NULL);
  515. ZeroMemory(&capsDrv, sizeof(DDCAPS));
  516. capsDrv.dwSize    = sizeof(DDCAPS);
  517. ddrval = this->lpdd->GetCaps(&capsDrv, NULL);
  518. if (FAILED(ddrval))
  519. return MP_RESULT_ERROR;
  520.     
  521. uStretchFactor1000 = capsDrv.dwMinOverlayStretch > 1000 ? capsDrv.dwMinOverlayStretch : 1000;
  522.     
  523. uDestSizeAlign = capsDrv.dwAlignSizeDest;
  524.     uSrcSizeAlign =  capsDrv.dwAlignSizeSrc;
  525.     
  526.     dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE;
  527.     
  528. if (capsDrv.dwCKeyCaps & DDCKEYCAPS_SRCOVERLAY)
  529. dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE;
  530.     
  531. ZeroMemory(&ovfx, sizeof(DDOVERLAYFX));
  532. ovfx.dwSize     = sizeof(DDOVERLAYFX);
  533. switch(this->physicalDepth) {
  534. case 16:
  535. ovfx.dckSrcColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_16BPP;
  536. ovfx.dckSrcColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;
  537.     
  538. ovfx.dckDestColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_16BPP;
  539. ovfx.dckDestColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_16BPP;
  540. break;
  541. case 24:
  542. case 32:
  543. default:
  544. ovfx.dckSrcColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_32BPP;
  545. ovfx.dckSrcColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_32BPP;
  546. ovfx.dckDestColorkey.dwColorSpaceLowValue  = DD_OVERLAY_COLORKEY_32BPP;
  547. ovfx.dckDestColorkey.dwColorSpaceHighValue = DD_OVERLAY_COLORKEY_32BPP;
  548. break;
  549. }
  550.     rs.left   = 0; 
  551. rs.top    = 0; 
  552. rs.right  = this->width;
  553. rs.bottom = this->height;
  554.  
  555. if (capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC && uSrcSizeAlign)
  556. rs.right -= rs.right % uSrcSizeAlign;
  557.  
  558. DWORD height;
  559. DWORD width;
  560. switch(options.aspect_ratio) {
  561. case ASPECT_RATIO_FREE:
  562. case ASPECT_RATIO_ORIGINAL:
  563. width  = this->width;
  564. height = this->height;
  565. break;
  566. case ASPECT_RATIO_TV:
  567. case ASPECT_RATIO_WIDE:
  568. case ASPECT_RATIO_CUSTOM:
  569. if(aspectRatios[options.aspect_ratio].yFactor < aspectRatios[options.aspect_ratio].xFactor) {
  570. width  = this->width;
  571. height = this->width*aspectRatios[options.aspect_ratio].yFactor/aspectRatios[options.aspect_ratio].xFactor;
  572. }
  573. else {
  574. height = this->height;
  575. width  = this->height*aspectRatios[options.aspect_ratio].xFactor/aspectRatios[options.aspect_ratio].yFactor;
  576. }
  577. break;
  578. }
  579. if(this->fullscreenWidth * height / width > this->fullscreenHeight) {
  580.     rd.left   = (this->fullscreenWidth - (this->fullscreenHeight * width / this->height)) / 2; 
  581. rd.top    = 0; 
  582. rd.right  = rd.left + (this->fullscreenHeight * width / height);
  583. rd.bottom = this->fullscreenHeight; 
  584. }
  585. else {
  586.     rd.left   = 0; 
  587. rd.top    = (this->fullscreenHeight - (this->fullscreenWidth * height / width)) / 2; 
  588. rd.right  = this->fullscreenWidth;
  589. rd.bottom = rd.top + (this->fullscreenWidth * height / width); 
  590. }
  591. if (capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST && uDestSizeAlign)
  592. rd.right = (int)((rd.right + uDestSizeAlign - 1) / uDestSizeAlign) * uDestSizeAlign;
  593. ddrval = this->lpddsOverlay->UpdateOverlay(&rs, this->lpddsPrimary, &rd, dwUpdateFlags, &ovfx);
  594.     
  595. if(FAILED(ddrval)) {
  596.       
  597. return MP_RESULT_ERROR;
  598. }
  599.     
  600. return MP_RESULT_OK;
  601. }
  602. return MP_RESULT_ERROR;
  603. }
  604. MP_RESULT MediaVideoRendererOverlay::Close()
  605. {
  606. if(this->lpdd) {
  607. this->lpdd->RestoreDisplayMode();
  608. this->lpdd->SetCooperativeLevel(this->hwndPlayback, DDSCL_NORMAL);
  609. }
  610. if(this->lpddsOverlay) {
  611. this->lpddsOverlay->Release();
  612. this->lpddsOverlay = NULL;
  613. }
  614. if(this->lpddsPrimary) {
  615. this->lpddsPrimary->Release();
  616. this->lpddsPrimary = NULL;
  617. }
  618. if(this->lpdd) {
  619. this->lpdd->Release();
  620. this->lpdd = NULL;
  621. }
  622. this->invertFlag  = FALSE;
  623. return MP_RESULT_ERROR;
  624. }