HRESULT D3DPresentEngine::CreateD3DSample(IDirect3DSwapChain9 *pSwapChain, IMFSample **ppVideoSample) { // Caller holds the object lock. HRESULT hr = S_OK; D3DCOLOR clrBlack = D3DCOLOR_ARGB(0xFF, 0x00, 0x00, 0x00); IDirect3DSurface9* pSurface = NULL; IMFSample* pSample = NULL; // Get the back buffer surface. CHECK_HR(hr = pSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurface)); // Fill it with black. CHECK_HR(hr = m_pDevice->ColorFill(pSurface, NULL, clrBlack)); // Create the sample. CHECK_HR(hr = MFCreateVideoSampleFromSurface(pSurface, &pSample)); // Return the pointer to the caller. *ppVideoSample = pSample; (*ppVideoSample)->AddRef(); done: SAFE_RELEASE(pSurface); SAFE_RELEASE(pSample); return hr; }
HRESULT D3DPresentEngine::createD3DSample(IDirect3DSwapChain9 *swapChain, IMFSample **videoSample) { D3DCOLOR clrBlack = D3DCOLOR_ARGB(0xFF, 0x00, 0x00, 0x00); IDirect3DSurface9* surface = NULL; IMFSample* sample = NULL; // Get the back buffer surface. HRESULT hr = swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &surface); if (FAILED(hr)) goto done; // Fill it with black. hr = m_device->ColorFill(surface, NULL, clrBlack); if (FAILED(hr)) goto done; hr = MFCreateVideoSampleFromSurface(surface, &sample); if (FAILED(hr)) goto done; *videoSample = sample; (*videoSample)->AddRef(); done: qt_wmf_safeRelease(&surface); qt_wmf_safeRelease(&sample); return hr; }
HRESULT GDISampleProvider::GetSample(IMFSample** ppSample) const { BOOL b = BitBlt(hDest, 0, 0, width, height, hdc, 0, 0, SRCCOPY); assert(b); BYTE * pixels; IMFMediaBufferPtr pBuffer; HRESULT hr = MFCreateMemoryBuffer(length, &pBuffer); BITMAPINFOHEADER bi; bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = width; bi.biHeight = height; bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; if (SUCCEEDED(hr)) hr = pBuffer->Lock(&pixels, nullptr, nullptr); if (SUCCEEDED(hr)) GetDIBits(hdc, hbDesktop, 0, height, pixels, reinterpret_cast<BITMAPINFO*>(&bi), DIB_RGB_COLORS); if (SUCCEEDED(hr)) hr = pBuffer->Unlock(); if (SUCCEEDED(hr)) hr = pBuffer->SetCurrentLength(cbWidth * VIDEO_HEIGHT); if (SUCCEEDED(hr)) hr = MFCreateVideoSampleFromSurface(nullptr, ppSample); if (SUCCEEDED(hr)) hr = (*ppSample)->AddBuffer(pBuffer); return hr; }
// Creates video samples based on a specified media type. HRESULT D3DPresentEngine::CreateVideoSamples(IMFMediaType *pFormat, VideoSampleList& videoSampleQueue) { if (pFormat == NULL) { return MF_E_UNEXPECTED; } HRESULT hr = S_OK; D3DFORMAT d3dFormat = D3DFMT_UNKNOWN; IMFSample *pVideoSample = NULL; AutoLock lock(m_ObjectLock); ReleaseResources(); // Helper object for reading the proposed type. VideoType videoType(pFormat); // Get some information about the video format. hr = videoType.GetFrameDimensions(&m_Width, &m_Height); CHECK_HR(hr, "D3DPresentEngine::CreateVideoSamples VideoType::GetFrameDimensions() failed"); hr = GetAspectRatio(pFormat, m_ArX, m_ArY); if (FAILED(hr)) { m_ArX = m_Width; m_ArY = m_Height; } //hr = videoType.GetFourCC((DWORD*)&d3dFormat); //CHECK_HR(hr, "D3DPresentEngine::CreateVideoSamples VideoType::GetFourCC() failed"); // Morpheus_xx, 2016-08-14: we force a format without alpha channel here, because rendering subtitles with MPC-HC engine expects this format. Actually I can't imagine a video format // that actually delivers alpha channel information. d3dFormat = D3DFMT_X8R8G8B8; for (int i = 0; i < NUM_PRESENTER_BUFFERS; i++) { CComPtr<IDirect3DTexture9> texture; hr = m_pDevice->CreateTexture(m_Width, m_Height, 1, D3DUSAGE_RENDERTARGET, d3dFormat, D3DPOOL_DEFAULT, &texture, NULL); if (FAILED(hr)) { Log("D3DPresentEngine::CreateVideoSamples Could not create texture %d. Error 0x%x", i, hr); break; } CComPtr<IDirect3DSurface9> surface; hr = texture->GetSurfaceLevel(0, &surface); if (FAILED(hr)) { Log("D3DPresentEngine::CreateVideoSamples Could not get surface from texture. Error 0x%x", hr); break; } hr = MFCreateVideoSampleFromSurface(surface, &pVideoSample); if (FAILED(hr)) { Log("D3DPresentEngine::CreateVideoSamples CreateVideoSampleFromSurface failed: 0x%x", hr); break; } // Add it to the list. hr = videoSampleQueue.InsertBack(pVideoSample); if (FAILED(hr)) { SAFE_RELEASE(pVideoSample); ReleaseResources(); return hr; } SAFE_RELEASE(pVideoSample); } return hr; }