コード例 #1
0
        private void ProcessFrame(DesktopFrame frame)
        {
            // Get the desktop capture texture
            var mapSource = _device.ImmediateContext.MapSubresource(_desktopImageTexture, 0, MapMode.Read, MapFlags.None);

            FinalImage = new Bitmap(_outputDescription.DesktopBounds.Width, _outputDescription.DesktopBounds.Height,
                                    PixelFormat.Format32bppRgb);
            var boundsRect = new System.Drawing.Rectangle(0, 0, _outputDescription.DesktopBounds.Width,
                                                          _outputDescription.DesktopBounds.Height);
            // 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 (var y = 0; y < _outputDescription.DesktopBounds.Height; y++)
            {
                // Copy a single line
                Utilities.CopyMemory(destPtr, sourcePtr, _outputDescription.DesktopBounds.Width * 4);

                // Advance pointers
                sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
                destPtr   = IntPtr.Add(destPtr, mapDest.Stride);
            }

            // Release source and dest locks
            FinalImage.UnlockBits(mapDest);
            _device.ImmediateContext.UnmapSubresource(_desktopImageTexture, 0);
            frame.DesktopImage = FinalImage;
        }
コード例 #2
0
        /// <summary>
        /// Retrieves the latest desktop image and associated metadata.
        /// </summary>
        public DesktopFrame GetLatestFrame()
        {
            // Try to get the latest frame; this may timeout
            var retrievalTimedOut = RetrieveFrame();

            if (retrievalTimedOut)
            {
                return(null);
            }

            var frame = new DesktopFrame();

            try
            {
                RetrieveFrameMetadata(frame);
                RetrieveCursorMetadata(frame);
                if (frame.MovedRegions.Length != 0 || frame.UpdatedRegions.Length != 0)
                {
                    ProcessFrame(frame);
                }
            }
            catch
            {
                // ignored
            }
            try
            {
                ReleaseFrame();
            }
            catch
            {
                //    throw new DesktopDuplicationException("Couldn't release frame.");
            }
            return(frame);
        }
コード例 #3
0
        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.Left, movedRectangles[i].DestinationRect.Top, 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].Left, dirtyRectangles[i].Top, dirtyRectangles[i].Width(), dirtyRectangles[i].Height());
                }
            }
            else
            {
                frame.MovedRegions   = new MovedRegion[0];
                frame.UpdatedRegions = new System.Drawing.Rectangle[0];
            }
        }
コード例 #4
0
        /// <summary>
        /// Retrieves the latest desktop image and associated metadata.
        /// </summary>
        public DesktopFrame GetLatestFrame()
        {
            var frame = new DesktopFrame();

            if (vSync >= VSyncLevel.Vsync)
            {
                waitForVSync();
            }
            if (vSync >= VSyncLevel.DoubleVsync)
            {
                waitForVSync();
            }

            ReleaseFrame();

            // Try to get the latest frame; this may timeout
            bool retrievalTimedOut = RetrieveFrame();

            if (retrievalTimedOut)
            {
                return(null);
            }

            ProcessFrame(frame);

            return(frame);
        }
コード例 #5
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);
        }
コード例 #6
0
        private void RetrieveCursorMetadata(DesktopFrame frame)
        {
            var pointerInfo = new PointerInfo();

            // A non-zero mouse update timestamp indicates that there is a mouse position update and optionally a shape change
            //if (frameInfo.LastMouseUpdateTime == 0)
            //    return;

            var updatePosition = _frameInfo.PointerPosition.Visible ||
                                 (pointerInfo.WhoUpdatedPositionLast == _whichOutputDevice);

            // If two outputs both say they have a visible, only update if new update has newer timestamp
            if (_frameInfo.PointerPosition.Visible && pointerInfo.Visible &&
                (pointerInfo.WhoUpdatedPositionLast != _whichOutputDevice) &&
                (pointerInfo.LastTimeStamp > _frameInfo.LastMouseUpdateTime))
            {
                updatePosition = false;
            }

            // Update position
            if (updatePosition)
            {
                pointerInfo.Position = _frameInfo.PointerPosition.Position;
                pointerInfo.WhoUpdatedPositionLast = _whichOutputDevice;
                pointerInfo.LastTimeStamp          = _frameInfo.LastMouseUpdateTime;
                pointerInfo.Visible = _frameInfo.PointerPosition.Visible;
            }

            // No new shape
            if (_frameInfo.PointerShapeBufferSize != 0)
            {
                try
                {
                    frame.CursorIcon = ExtractIcon(pointerInfo);
                    frame.CursorSize = new Size(pointerInfo.ShapeInfo.Width, pointerInfo.ShapeInfo.Type == 1 ? pointerInfo.ShapeInfo.Height / 2 : pointerInfo.ShapeInfo.Height);
                }
                catch (SharpDXException ex)
                {
                    if (ex.ResultCode.Failure)
                    {
                        throw new DesktopDuplicationException("Failed to get frame pointer shape.");
                    }
                }
            }

            //frame.CursorVisible = pointerInfo.Visible;
            frame.CursorLocation = new System.Drawing.Point(pointerInfo.Position.X, pointerInfo.Position.Y);
        }
コード例 #7
0
        private void RetrieveCursorMetadata(DesktopFrame frame)
        {
            var pointerInfo = new PointerInfo();

            // A non-zero mouse update timestamp indicates that there is a mouse position update and optionally a shape change
            if (frameInfo.LastMouseUpdateTime == 0)
            {
                return;
            }

            bool updatePosition = true;

            // Make sure we don't update pointer position wrongly
            // If pointer is invisible, make sure we did not get an update from another output that the last time that said pointer
            // was visible, if so, don't set it to invisible or update.

            if (!frameInfo.PointerPosition.Visible && (pointerInfo.WhoUpdatedPositionLast != this.mWhichOutputDevice))
            {
                updatePosition = false;
            }

            // If two outputs both say they have a visible, only update if new update has newer timestamp
            if (frameInfo.PointerPosition.Visible && pointerInfo.Visible && (pointerInfo.WhoUpdatedPositionLast != this.mWhichOutputDevice) && (pointerInfo.LastTimeStamp > frameInfo.LastMouseUpdateTime))
            {
                updatePosition = false;
            }

            // Update position
            if (updatePosition)
            {
                pointerInfo.Position = frameInfo.PointerPosition.Position;
                pointerInfo.WhoUpdatedPositionLast = mWhichOutputDevice;
                pointerInfo.LastTimeStamp          = frameInfo.LastMouseUpdateTime;
                pointerInfo.Visible = frameInfo.PointerPosition.Visible;
            }

            // No new shape
            if (frameInfo.PointerShapeBufferSize == 0)
            {
                return;
            }

            if (frameInfo.PointerShapeBufferSize > pointerInfo.BufferSize)
            {
                pointerInfo.PtrShapeBuffer = new byte[frameInfo.PointerShapeBufferSize];
                pointerInfo.BufferSize     = frameInfo.PointerShapeBufferSize;
            }

            try
            {
                unsafe
                {
                    fixed(byte *ptrShapeBufferPtr = pointerInfo.PtrShapeBuffer)
                    {
                        mDeskDupl.GetFramePointerShape(frameInfo.PointerShapeBufferSize, (IntPtr)ptrShapeBufferPtr, out pointerInfo.BufferSize, out pointerInfo.ShapeInfo);
                    }
                }
            }
            catch (SharpDXException ex)
            {
                if (ex.ResultCode.Failure)
                {
                    throw new DesktopDuplicationException("Failed to get frame pointer shape.");
                }
            }

            //frame.CursorVisible = pointerInfo.Visible;
            frame.CursorLocation = new System.Drawing.Point(pointerInfo.Position.X, pointerInfo.Position.Y);
        }
        private void ProcessFrame(DesktopFrame frame)
        {
            // Get the desktop capture texture
            var mapSource = mDevice.ImmediateContext.MapSubresource(desktopImageTexture, 0, MapMode.Read, MapFlags.None);

            FinalImage = new System.Drawing.Bitmap(mOutputDesc.DesktopBounds.Width, mOutputDesc.DesktopBounds.Height, PixelFormat.Format32bppRgb);
            var boundsRect = new System.Drawing.Rectangle(0, 0, mOutputDesc.DesktopBounds.Width, mOutputDesc.DesktopBounds.Height);
            // 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 < mOutputDesc.DesktopBounds.Height; y++)
            {
                // Copy a single line 
                Utilities.CopyMemory(destPtr, sourcePtr, mOutputDesc.DesktopBounds.Width * 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 = (Bitmap)FinalImage.Clone();
        }
        private void RetrieveCursorMetadata(DesktopFrame frame)
        {
            var pointerInfo = new PointerInfo();

            // A non-zero mouse update timestamp indicates that there is a mouse position update and optionally a shape change
            if (frameInfo.LastMouseUpdateTime == 0)
                return;

            bool updatePosition = true;

            // Make sure we don't update pointer position wrongly
            // If pointer is invisible, make sure we did not get an update from another output that the last time that said pointer
            // was visible, if so, don't set it to invisible or update.

            if (!frameInfo.PointerPosition.Visible && (pointerInfo.WhoUpdatedPositionLast != this.mWhichOutputDevice))
                updatePosition = false;

            // If two outputs both say they have a visible, only update if new update has newer timestamp
            if (frameInfo.PointerPosition.Visible && pointerInfo.Visible && (pointerInfo.WhoUpdatedPositionLast != this.mWhichOutputDevice) && (pointerInfo.LastTimeStamp > frameInfo.LastMouseUpdateTime))
                updatePosition = false;

            // Update position
            if (updatePosition)
            {
                pointerInfo.Position = new SharpDX.Point(frameInfo.PointerPosition.Position.X, frameInfo.PointerPosition.Position.Y);
                pointerInfo.WhoUpdatedPositionLast = mWhichOutputDevice;
                pointerInfo.LastTimeStamp = frameInfo.LastMouseUpdateTime;
                pointerInfo.Visible = frameInfo.PointerPosition.Visible;
            }
                        
            // No new shape
            if (frameInfo.PointerShapeBufferSize == 0)
                return;

            if (frameInfo.PointerShapeBufferSize > pointerInfo.BufferSize)
            {
                pointerInfo.PtrShapeBuffer = new byte[frameInfo.PointerShapeBufferSize];
                pointerInfo.BufferSize = frameInfo.PointerShapeBufferSize;
            }

            try
            {
                unsafe
                {
                    fixed (byte* ptrShapeBufferPtr = pointerInfo.PtrShapeBuffer)
                    {
                        mDeskDupl.GetFramePointerShape(frameInfo.PointerShapeBufferSize, (IntPtr)ptrShapeBufferPtr, out pointerInfo.BufferSize, out pointerInfo.ShapeInfo);
                    }
                }
            }
            catch (SharpDXException ex)
            {
                if (ex.ResultCode.Failure)
                {
                    throw new DesktopDuplicationException("Failed to get frame pointer shape.");
                }
            }

            frame.CursorVisible = pointerInfo.Visible;
            frame.CursorLocation = new System.Drawing.Point(pointerInfo.Position.X, pointerInfo.Position.Y);
            //Console.WriteLine(frame.CursorLocation.X+":"+frame.CursorLocation.Y);
        }
        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;
 }
コード例 #12
0
        private void RetrieveCursorMetadata(DesktopFrame frame)
        {
            var pointerInfo = new PointerInfo();

            // A non-zero mouse update timestamp indicates that there is a mouse position update and optionally a shape change
            //if (frameInfo.LastMouseUpdateTime == 0)
            //    return;

            var updatePosition = _frameInfo.PointerPosition.Visible || (pointerInfo.WhoUpdatedPositionLast == _whichOutputDevice);

            // If two outputs both say they have a visible, only update if new update has newer timestamp
            if (_frameInfo.PointerPosition.Visible && pointerInfo.Visible && (pointerInfo.WhoUpdatedPositionLast != _whichOutputDevice) && (pointerInfo.LastTimeStamp > _frameInfo.LastMouseUpdateTime))
            {
                updatePosition = false;
            }

            // Update position
            if (updatePosition)
            {
                pointerInfo.Position = new SharpDX.Point(_frameInfo.PointerPosition.Position.X, _frameInfo.PointerPosition.Position.Y);
                pointerInfo.WhoUpdatedPositionLast = _whichOutputDevice;
                pointerInfo.LastTimeStamp          = _frameInfo.LastMouseUpdateTime;
                pointerInfo.Visible = _frameInfo.PointerPosition.Visible;
            }

            // No new shape
            if (_frameInfo.PointerShapeBufferSize != 0)
            {
                if (_frameInfo.PointerShapeBufferSize > pointerInfo.BufferSize)
                {
                    pointerInfo.PtrShapeBuffer = new byte[_frameInfo.PointerShapeBufferSize];
                    pointerInfo.BufferSize     = _frameInfo.PointerShapeBufferSize;
                }

                try
                {
                    unsafe
                    {
                        fixed(byte *ptrShapeBufferPtr = pointerInfo.PtrShapeBuffer)
                        {
                            _deskDupl.GetFramePointerShape(_frameInfo.PointerShapeBufferSize, (IntPtr)ptrShapeBufferPtr,
                                                           out pointerInfo.BufferSize, out pointerInfo.ShapeInfo);

                            var bitmap     = new Bitmap(pointerInfo.ShapeInfo.Width, pointerInfo.ShapeInfo.Height, PixelFormat.Format32bppArgb);
                            var boundsRect = new System.Drawing.Rectangle(0, 0, pointerInfo.ShapeInfo.Width, pointerInfo.ShapeInfo.Height);
                            var mapDest    = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
                            var sourcePtr  = (IntPtr)ptrShapeBufferPtr;
                            var destPtr    = mapDest.Scan0;

                            for (var y = 0; y < pointerInfo.ShapeInfo.Height; y++)
                            {
                                // Copy a single line
                                Utilities.CopyMemory(destPtr, sourcePtr, pointerInfo.ShapeInfo.Width * 4);

                                // Advance pointers
                                sourcePtr = IntPtr.Add(sourcePtr, pointerInfo.ShapeInfo.Pitch);
                                destPtr   = IntPtr.Add(destPtr, mapDest.Stride);
                            }

                            // Release bitmap lock
                            bitmap.UnlockBits(mapDest);
                            frame.CursorBitmap = bitmap;
                        }
                    }
                }
                catch (SharpDXException ex)
                {
                    if (ex.ResultCode.Failure)
                    {
                        throw new DesktopDuplicationException("Failed to get frame pointer shape.");
                    }
                }
            }

            //frame.CursorVisible = pointerInfo.Visible;
            frame.CursorLocation = new System.Drawing.Point(pointerInfo.Position.X, pointerInfo.Position.Y);
        }