//------------------------------------------------------------------- // DrawFrame // // Draw the video frame. //------------------------------------------------------------------- public int DrawFrame(IMFMediaBuffer pCaptureDeviceBuffer) { if (m_convertFn == null) { return MFError.MF_E_INVALIDREQUEST; } int hr = S_Ok; IntPtr pbScanline0; int lStride = 0; Result res; Surface pSurf = null; Surface pBB = null; if (m_pDevice == null || m_pSwapChain == null) { return S_Ok; } // Helper object to lock the video buffer. using (VideoBufferLock xbuffer = new VideoBufferLock(pCaptureDeviceBuffer)) { hr = TestCooperativeLevel(); if (Failed(hr)) { goto done; } // Lock the video buffer. This method returns a pointer to the first scan // line in the image, and the stride in bytes. hr = xbuffer.LockBuffer(m_lDefaultStride, m_height, out pbScanline0, out lStride); if (Failed(hr)) { goto done; } // Copy in bitmap if (m_Data != IntPtr.Zero) { unsafe { byte *ipSource = (byte *)m_Data; byte *ipDest = (byte *)pbScanline0; for (int x = 0; x < m_LogoHeight; x++) { CopyMemory(ipDest, ipSource, (uint)m_LogoStride); ipDest += lStride; ipSource += m_LogoStride; } } } // Get the swap-chain surface. pSurf = m_pSwapChain.GetBackBuffer(0); // Lock the swap-chain surface and get Graphic stream object. DataRectangle dr = pSurf.LockRectangle(LockFlags.NoSystemLock); try { using (dr.Data) { // Convert the frame. This also copies it to the Direct3D surface. m_convertFn(dr.Data.DataPointer, dr.Pitch, pbScanline0, lStride, m_width, m_height); } } finally { res = pSurf.UnlockRectangle(); MFError.ThrowExceptionForHR(res.Code); } } // Color fill the back buffer. pBB = m_pDevice.GetBackBuffer(0, 0); m_pDevice.ColorFill(pBB, Color.FromArgb(0, 0, 0x80)); // Blit the frame. Rectangle r = new Rectangle(0, 0, m_width, m_height); res = m_pDevice.StretchRectangle(pSurf, r, pBB, m_rcDest, TextureFilter.Linear); hr = res.Code; if (res.IsSuccess) { // Present the frame. res = m_pDevice.Present(); hr = res.Code; } done: SafeRelease(pBB); SafeRelease(pSurf); return hr; }
//------------------------------------------------------------------- // DrawFrame // // Draw the video frame. //------------------------------------------------------------------- public HResult DrawFrame(IMFMediaBuffer pCaptureDeviceBuffer) { if (m_convertFn == null) { return(HResult.MF_E_INVALIDREQUEST); } HResult hr = HResult.S_OK; IntPtr pbScanline0; int lStride = 0; Result res; Surface pSurf = null; Surface pBB = null; if (m_pDevice == null || m_pSwapChain == null) { return(HResult.S_OK); } // Helper object to lock the video buffer. using (VideoBufferLock xbuffer = new VideoBufferLock(pCaptureDeviceBuffer)) { hr = TestCooperativeLevel(); if (Failed(hr)) { goto done; } // Lock the video buffer. This method returns a pointer to the first scan // line in the image, and the stride in bytes. hr = xbuffer.LockBuffer(m_lDefaultStride, m_height, out pbScanline0, out lStride); if (Failed(hr)) { goto done; } // Copy in bitmap if (m_Data != IntPtr.Zero) { unsafe { byte *ipSource = (byte *)m_Data; byte *ipDest = (byte *)pbScanline0; for (int x = 0; x < m_LogoHeight; x++) { CopyMemory(ipDest, ipSource, (uint)m_LogoStride); ipDest += lStride; ipSource += m_LogoStride; } } } // Get the swap-chain surface. pSurf = m_pSwapChain.GetBackBuffer(0); // Lock the swap-chain surface and get Graphic stream object. DataRectangle dr = pSurf.LockRectangle(LockFlags.NoSystemLock); try { using (dr.Data) { // Convert the frame. This also copies it to the Direct3D surface. m_convertFn(dr.Data.DataPointer, dr.Pitch, pbScanline0, lStride, m_width, m_height); } } finally { res = pSurf.UnlockRectangle(); MFError.ThrowExceptionForHR(res.Code); } } // Color fill the back buffer. pBB = m_pDevice.GetBackBuffer(0, 0); m_pDevice.ColorFill(pBB, Color.FromArgb(0, 0, 0x80)); // Blit the frame. Rectangle r = new Rectangle(0, 0, m_width, m_height); res = m_pDevice.StretchRectangle(pSurf, r, pBB, m_rcDest, TextureFilter.Linear); hr = (HResult)res.Code; if (res.IsSuccess) { // Present the frame. res = m_pDevice.Present(); hr = (HResult)res.Code; } done: SafeRelease(pBB); SafeRelease(pSurf); return(hr); }