Ticket #6618: 6618-vout_d3d_reinit_yv12.patch
File 6618-vout_d3d_reinit_yv12.patch, 5.8 KB (added by , 15 years ago) |
---|
-
libs/libmythtv/videoout_d3d.h
62 62 HWND m_hWnd; 63 63 HWND m_hEmbedWnd; 64 64 D3DFORMAT m_ddFormat; 65 D3DFORMAT m_surfaceFormat; 65 66 IDirect3D9 *m_pD3D; 66 67 IDirect3DDevice9 *m_pd3dDevice; 67 68 IDirect3DSurface9 *m_pSurface; -
libs/libmythtv/videoout_d3d.cpp
52 52 : VideoOutput(), m_InputCX(0), m_InputCY(0), 53 53 m_lock(QMutex::Recursive), m_RefreshRate(60), 54 54 m_hWnd(NULL), m_hEmbedWnd(NULL), 55 m_ddFormat(D3DFMT_UNKNOWN), m_pD3D(NULL), m_pd3dDevice(NULL), 55 m_ddFormat(D3DFMT_UNKNOWN), m_surfaceFormat(D3DFMT_UNKNOWN), 56 m_pD3D(NULL), m_pd3dDevice(NULL), 56 57 m_pSurface(NULL), m_pTexture(NULL), m_pVertexBuffer(NULL) 57 58 { 58 59 VERBOSE(VB_PLAYBACK, LOC + "ctor"); … … 188 189 QMutexLocker locker(&m_lock); 189 190 D3DCAPS9 d3dCaps; 190 191 192 UnInitD3D(); 193 191 194 typedef LPDIRECT3D9 (WINAPI *LPFND3DC)(UINT SDKVersion); 192 195 static LPFND3DC OurDirect3DCreate9 = NULL; 193 196 static HINSTANCE hD3DLib = NULL; … … 258 261 d3dpp.hDeviceWindow = m_hWnd; 259 262 d3dpp.Windowed = TRUE; 260 263 d3dpp.BackBufferWidth = m_InputCX; 261 d3dpp.BackBufferHeight = m_InputC X;264 d3dpp.BackBufferHeight = m_InputCY; 262 265 d3dpp.BackBufferCount = 1; 263 266 d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; 264 267 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; … … 278 281 //input seems to always be PIX_FMT_YUV420P 279 282 //MAKEFOURCC('I','4','2','0'); 280 283 //IYUV I420 284 //Most Windows drivers support YV12 but not I420 281 285 282 D3DFORMAT format = D3DFMT_X8R8G8B8; 286 VERBOSE(VB_PLAYBACK, LOC + "Checking YV12 color conversion support"); 287 m_surfaceFormat = (D3DFORMAT)MAKEFOURCC('Y','V','1','2'); 283 288 /* test whether device can create a surface of that format */ 284 289 HRESULT hr = m_pD3D->CheckDeviceFormat( 285 290 D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_ddFormat, 0, 286 D3DRTYPE_SURFACE, format);291 D3DRTYPE_SURFACE, m_surfaceFormat); 287 292 288 293 if (SUCCEEDED(hr)) 289 294 { … … 292 297 */ 293 298 hr = m_pD3D->CheckDeviceFormatConversion( 294 299 D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 295 format, m_ddFormat);300 m_surfaceFormat, m_ddFormat); 296 301 297 302 if (FAILED(hr)) 298 303 { 299 VERBOSE(VB_IMPORTANT, LOC _ERR+304 VERBOSE(VB_IMPORTANT, LOC + 300 305 "Device does not support conversion to RGB format"); 301 302 return false; 306 m_surfaceFormat = D3DFMT_X8R8G8B8; 303 307 } 304 308 } 305 309 else 306 310 { 307 VERBOSE(VB_IMPORTANT, LOC_ERR + 308 "Device does not support surfaces in RGB format"); 309 310 return false; 311 VERBOSE(VB_IMPORTANT, LOC + 312 "Device does not support surfaces in YV12 format"); 313 m_surfaceFormat = D3DFMT_X8R8G8B8; 311 314 } 312 315 313 316 hr = m_pd3dDevice->CreateOffscreenPlainSurface( 314 317 m_InputCX, 315 318 m_InputCY, 316 format,319 m_surfaceFormat, 317 320 D3DPOOL_DEFAULT, 318 321 &m_pSurface, 319 322 NULL); … … 522 525 return; 523 526 } 524 527 528 if (!m_pSurface) 529 { 530 VERBOSE(VB_IMPORTANT, LOC_ERR + "Picture surface not initialized"); 531 return; 532 } 533 525 534 if (!buffer) 526 535 buffer = vbuffers.GetScratchFrame(); 527 536 … … 537 546 return; 538 547 } 539 548 549 if (m_surfaceFormat == (D3DFORMAT)MAKEFOURCC('Y','V','1','2')) 550 { 551 for (int i = 0; i < m_InputCY; i++) 552 memcpy((uint8_t*)d3drect.pBits + (i * d3drect.Pitch), 553 buffer->buf + (i * m_InputCX), m_InputCX); 554 for (int i = 0; i < m_InputCY / 2; i++) 555 memcpy((uint8_t*)d3drect.pBits + (m_InputCY * d3drect.Pitch) 556 + (i * d3drect.Pitch / 2), 557 buffer->buf + m_InputCY * m_InputCX * 5/4 558 + (i * m_InputCX / 2), m_InputCX / 2); 559 for (int i = 0; i < m_InputCY / 2; i++) 560 memcpy((uint8_t*)d3drect.pBits + (m_InputCY * d3drect.Pitch * 5/4) 561 + (i * d3drect.Pitch / 2), 562 buffer->buf + m_InputCY * m_InputCX 563 + (i * m_InputCX / 2), m_InputCX / 2); 564 } 565 else 566 { 540 567 avpicture_fill(&image_out, (uint8_t*) d3drect.pBits, 541 568 PIX_FMT_RGB32, m_InputCX, m_InputCY); 542 569 image_out.linesize[0] = d3drect.Pitch; … … 546 573 myth_sws_img_convert( 547 574 &image_out, PIX_FMT_RGB32, &image_in, 548 575 PIX_FMT_YUV420P, m_InputCX, m_InputCY); 576 } 549 577 550 578 hr = m_pSurface->UnlockRect(); 551 579 if (FAILED(hr)) … … 577 605 switch (hr) 578 606 { 579 607 case D3DERR_DEVICENOTRESET: 580 VERBOSE(VB_IMPORTANT, LOC_ERR + 581 "The device has been lost but can be reset " 582 "at this time. TODO: implement device reset"); 583 // TODO: instead of goto renderError, reset the device 584 //m_pd3dDevice->Reset(... 608 VERBOSE(VB_IMPORTANT, LOC + 609 "The device was lost and will be reset now."); 610 InitD3D(); 585 611 goto RenderError; 586 612 case D3DERR_DEVICELOST: 587 VERBOSE(VB_ IMPORTANT, LOC_ERR+613 VERBOSE(VB_PLAYBACK, LOC + 588 614 "The device has been lost and cannot be reset " 589 615 "at this time."); 590 616 goto RenderError;