IDirect3DSurface9* MythRenderD3D9::CreateSurface(const QSize &size, bool video) { D3D9Locker locker(this); IDirect3DDevice9* dev = locker.Acquire(); if (!dev) return NULL; IDirect3DSurface9* temp_surface = NULL; D3DFORMAT format = video ? m_videosurface_fmt : m_surface_fmt; HRESULT hr = dev->CreateOffscreenPlainSurface( size.width(), size.height(), format, D3DPOOL_DEFAULT, &temp_surface, NULL); if (FAILED(hr)|| !temp_surface) { VERBOSE(VB_IMPORTANT, D3DERR + "Failed to create surface."); return NULL; } m_surfaces[temp_surface] = MythD3DSurface(size, format); dev->ColorFill(temp_surface, NULL, D3DCOLOR_ARGB(0xFF, 0, 0, 0) ); return temp_surface; }
HRESULT CDecDXVA2::CreateDXVA2Decoder(int nSurfaces, IDirect3DSurface9 **ppSurfaces) { DbgLog((LOG_TRACE, 10, L"-> CDecDXVA2::CreateDXVA2Decoder")); HRESULT hr = S_OK; LPDIRECT3DSURFACE9 pSurfaces[DXVA2_MAX_SURFACES]; if (!m_pDXVADecoderService) return E_FAIL; DestroyDecoder(false, true); GUID input = GUID_NULL; D3DFORMAT output; FindVideoServiceConversion(m_pAVCtx->codec_id, &input, &output); if (!nSurfaces) { m_dwSurfaceWidth = GetAlignedDimension(m_pAVCtx->coded_width); m_dwSurfaceHeight = GetAlignedDimension(m_pAVCtx->coded_height); m_NumSurfaces = GetBufferCount(); hr = m_pDXVADecoderService->CreateSurface(m_dwSurfaceWidth, m_dwSurfaceHeight, m_NumSurfaces - 1, output, D3DPOOL_DEFAULT, 0, DXVA2_VideoDecoderRenderTarget, pSurfaces, nullptr); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> Creation of surfaces failed with hr: %X", hr)); m_NumSurfaces = 0; return E_FAIL; } ppSurfaces = pSurfaces; } else { m_NumSurfaces = nSurfaces; for (int i = 0; i < m_NumSurfaces; i++) { ppSurfaces[i]->AddRef(); } } if (m_NumSurfaces <= 0) { DbgLog((LOG_TRACE, 10, L"-> No surfaces? No good!")); return E_FAIL; } // get the device, for ColorFill() to init the surfaces in black IDirect3DDevice9 *pDev = nullptr; ppSurfaces[0]->GetDevice(&pDev); for (int i = 0; i < m_NumSurfaces; i++) { m_pSurfaces[i].index = i; m_pSurfaces[i].d3d = ppSurfaces[i]; m_pSurfaces[i].age = 0; m_pSurfaces[i].used = false; // fill the surface in black, to avoid the "green screen" in case the first frame fails to decode. if (pDev) pDev->ColorFill(ppSurfaces[i], NULL, D3DCOLOR_XYUV(0, 128, 128)); } // and done with the device SafeRelease(&pDev); DbgLog((LOG_TRACE, 10, L"-> Successfully created %d surfaces (%dx%d)", m_NumSurfaces, m_dwSurfaceWidth, m_dwSurfaceHeight)); DXVA2_VideoDesc desc; ZeroMemory(&desc, sizeof(desc)); desc.SampleWidth = m_pAVCtx->coded_width; desc.SampleHeight = m_pAVCtx->coded_height; desc.Format = output; hr = FindDecoderConfiguration(input, &desc, &m_DXVAVideoDecoderConfig); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> FindDecoderConfiguration failed with hr: %X", hr)); return hr; } IDirectXVideoDecoder *decoder = nullptr; hr = m_pDXVADecoderService->CreateVideoDecoder(input, &desc, &m_DXVAVideoDecoderConfig, ppSurfaces, m_NumSurfaces, &decoder); if (FAILED(hr)) { DbgLog((LOG_TRACE, 10, L"-> CreateVideoDecoder failed with hr: %X", hr)); return E_FAIL; } m_pDecoder = decoder; m_guidDecoderDevice = input; /* fill hwaccel_context */ FillHWContext((dxva_context *)m_pAVCtx->hwaccel_context); memset(m_pRawSurface, 0, sizeof(m_pRawSurface)); for (int i = 0; i < m_NumSurfaces; i++) { m_pRawSurface[i] = m_pSurfaces[i].d3d; } return S_OK; }