private void RetrieveFrameMetadata(DesktopFrame frame) { if (frameInfo.TotalMetadataBufferSize > 0) { // Get moved regions int movedRegionsLength = 0; OutputDuplicateMoveRectangle[] movedRectangles = new OutputDuplicateMoveRectangle[frameInfo.TotalMetadataBufferSize]; mDeskDupl.GetFrameMoveRects(movedRectangles.Length, movedRectangles, out movedRegionsLength); frame.MovedRegions = new MovedRegion[movedRegionsLength / Marshal.SizeOf(typeof(OutputDuplicateMoveRectangle))]; for (int i = 0; i < frame.MovedRegions.Length; i++) { frame.MovedRegions[i] = new MovedRegion() { Source = new System.Drawing.Point(movedRectangles[i].SourcePoint.X, movedRectangles[i].SourcePoint.Y), Destination = new System.Drawing.Rectangle(movedRectangles[i].DestinationRect.X, movedRectangles[i].DestinationRect.Y, movedRectangles[i].DestinationRect.Width, movedRectangles[i].DestinationRect.Height) }; } // Get dirty regions int dirtyRegionsLength = 0; Rectangle[] dirtyRectangles = new Rectangle[frameInfo.TotalMetadataBufferSize]; mDeskDupl.GetFrameDirtyRects(dirtyRectangles.Length, dirtyRectangles, out dirtyRegionsLength); frame.UpdatedRegions = new System.Drawing.Rectangle[dirtyRegionsLength / Marshal.SizeOf(typeof(Rectangle))]; for (int i = 0; i < frame.UpdatedRegions.Length; i++) { frame.UpdatedRegions[i] = new System.Drawing.Rectangle(dirtyRectangles[i].X, dirtyRectangles[i].Y, dirtyRectangles[i].Width, dirtyRectangles[i].Height); } } else { frame.MovedRegions = new MovedRegion[0]; frame.UpdatedRegions = new System.Drawing.Rectangle[0]; } }
/// <summary> /// Retrieves the latest desktop image and associated metadata. /// </summary> public DesktopFrame GetLatestFrame() { var frame = new DesktopFrame(); // Try to get the latest frame; this may timeout bool retrievalTimedOut = RetrieveFrame(); if (retrievalTimedOut) { return(null); } try { // RetrieveFrameMetadata(frame); // RetrieveCursorMetadata(frame); ProcessFrame(frame); } catch { ReleaseFrame(); } try { ReleaseFrame(); } catch { // throw new DesktopDuplicationException("Couldn't release frame."); } return(frame); }
private void ProcessFrame(DesktopFrame frame) { // Get the desktop capture texture var mapSource = mDevice.ImmediateContext.MapSubresource(desktopImageTexture, 0, MapMode.Read, MapFlags.None); var Real_DesktopHeight = mOutputDesc.DesktopBounds.Height; var Real_DesktopWidth = mOutputDesc.DesktopBounds.Width; // var x = Real_DesktopHeight; // Real_DesktopHeight = Real_DesktopWidth; // Real_DesktopWidth = x; Bitmap newImage; if (!_allocatedBitmaps.TryDequeue(out newImage)) { newImage = new Bitmap(Real_DesktopWidth, Real_DesktopHeight, PixelFormat.Format32bppRgb); } FinalImage = newImage; var boundsRect = new System.Drawing.Rectangle(0, 0, Real_DesktopWidth, Real_DesktopHeight); // Copy pixels from screen capture Texture to GDI bitmap var mapDest = FinalImage.LockBits(boundsRect, ImageLockMode.WriteOnly, FinalImage.PixelFormat); var sourcePtr = mapSource.DataPointer; var destPtr = mapDest.Scan0; for (int y = 0; y < Real_DesktopHeight; y++) { // Copy a single line Utilities.CopyMemory(destPtr, sourcePtr, Real_DesktopWidth * 4); // Advance pointers sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch); destPtr = IntPtr.Add(destPtr, mapDest.Stride); } // Release source and dest locks FinalImage.UnlockBits(mapDest); mDevice.ImmediateContext.UnmapSubresource(desktopImageTexture, 0); frame.DesktopImage = FinalImage; }