示例#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 (int 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
        private void RetrieveFrameMetadata(DesktopFrame frame)
        {
            if (_frameInfo.TotalMetadataBufferSize > 0)
            {
                // Get moved regions
                int movedRegionsLength;
                OutputDuplicateMoveRectangle[] movedRectangles = new OutputDuplicateMoveRectangle[_frameInfo.TotalMetadataBufferSize];
                _outputDuplication.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;
                Rectangle[] dirtyRectangles = new Rectangle[_frameInfo.TotalMetadataBufferSize];
                _outputDuplication.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];
            }
        }
示例#3
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 succeeded = RetrieveFrame();

            if (!succeeded)
            {
                return(null);
            }
            try
            {
                RetrieveFrameMetadata(frame);
                RetrieveCursorMetadata(frame);
                ProcessFrame(frame);
            }
            finally
            {
                try
                {
                    ReleaseFrame();
                }
                catch
                {
                    //ignored
                }
            }
            return(frame);
        }
示例#4
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 != _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 != _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)
            //        {
            //            _outputDuplication.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.");
            //    }
            //}
        }