Example #1
0
        // TODO: Something in the flow is wrong and causes bleeding pixels when doing a move.
        private static unsafe void CopyRegion(byte *fromBuffer, byte *toBuffer, int totalWidth, MovedRegion region)
        {
            var widthInBytes = totalWidth * 4;

            for (var yOffset = 0; yOffset < region.Height; yOffset++)
            {
                var yOrigin = region.FromY + yOffset;
                var yOriginIndex = yOrigin * widthInBytes;
                var yDestination = region.ToY + yOffset;
                var yDestinationIndex = yDestination * widthInBytes;

                for (var xOffset = 0; xOffset < region.Width; xOffset++)
                {
                    var xOrigin = region.FromX + xOffset;
                    var xOriginIndex = yOriginIndex + xOrigin * 4;
                    var xDestination = region.ToX + xOffset;
                    var xDestinationIndex = yDestinationIndex + xDestination * 4;

                    toBuffer[xDestinationIndex + 0] = fromBuffer[xOriginIndex + 0];
                    toBuffer[xDestinationIndex + 1] = fromBuffer[xOriginIndex + 1];
                    toBuffer[xDestinationIndex + 2] = fromBuffer[xOriginIndex + 2];
                    toBuffer[xDestinationIndex + 3] = fromBuffer[xOriginIndex + 3];
                }
            }
        }
Example #2
0
        public RemoteDesktopDataInfo CaptureScreen(IStreamCodec streamCodec, ICursorStreamCodec cursorStreamCodec, bool updateCursor)
        {
            //Debug.Print("_desktopDupl == null: " + (_deskDupl == null));
            if (!RetrieveFrame())
            {
                return(null);
            }

            // Get the desktop capture texture
            var mapSource = _device.ImmediateContext.MapSubresource(_desktopImageTexture, 0, MapMode.Read,
                                                                    MapFlags.None);

            try
            {
                if (updateCursor)
                {
                    _screenHelper.UpdateCursor(cursorStreamCodec, _currentMonitor);
                }
#if FALSE
                if (updateCursor)
                {
                    cursorStreamCodec.UpdateCursorInfo(_frameInfo.PointerPosition.Position.X,
                                                       _frameInfo.PointerPosition.Position.Y, _frameInfo.PointerPosition.Visible);

                    if (_frameInfo.LastMouseUpdateTime != 0 && _frameInfo.PointerShapeBufferSize > 0)
                    {
                        var buffer = new byte[_frameInfo.PointerShapeBufferSize];

                        unsafe
                        {
                            fixed(byte *ptrShapeBufferPtr = buffer)
                            {
                                int bufferSize;
                                OutputDuplicatePointerShapeInformation shapeInfo;

                                _deskDupl.GetFramePointerShape(_frameInfo.PointerShapeBufferSize,
                                                               (IntPtr)ptrShapeBufferPtr, out bufferSize, out shapeInfo);

                                switch (shapeInfo.Type)
                                {
                                case 0x1:     //DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME
                                    var size = Image.GetPixelFormatSize(PixelFormat.Format1bppIndexed);
                                    //var bitmap = new Bitmap(32, 32, 4, PixelFormat.Format1bppIndexed, (IntPtr)ptrShapeBufferPtr);
                                    cursorStreamCodec.UpdateCursorImage((IntPtr)ptrShapeBufferPtr,
                                                                        shapeInfo.Pitch, 32, 32,
                                                                        PixelFormat.Format1bppIndexed);
                                    Debug.Print("DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MONOCHROME");
                                    break;

                                case 0x2:     //DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR
                                    cursorStreamCodec.UpdateCursorImage((IntPtr)ptrShapeBufferPtr,
                                                                        shapeInfo.Pitch, shapeInfo.Width, shapeInfo.Height,
                                                                        PixelFormat.Format32bppArgb);
                                    Debug.Print("DXGI_OUTDUPL_POINTER_SHAPE_TYPE_COLOR");
                                    break;

                                case 0x4:     //DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR
                                    Debug.Print("DXGI_OUTDUPL_POINTER_SHAPE_TYPE_MASKED_COLOR");
                                    break;
                                }
                            }
                        }
                    }
                }
#endif

                if (_frameInfo.TotalMetadataBufferSize > 0)
                {
                    int movedRegionsLength;
                    OutputDuplicateMoveRectangle[] movedRectangles =
                        new OutputDuplicateMoveRectangle[_frameInfo.TotalMetadataBufferSize];
                    _deskDupl.GetFrameMoveRects(movedRectangles.Length, movedRectangles, out movedRegionsLength);
                    var movedRegions =
                        new MovedRegion[movedRegionsLength / Marshal.SizeOf(typeof(OutputDuplicateMoveRectangle))];

                    for (int i = 0; i < movedRegions.Length; i++)
                    {
                        var moveRectangle = movedRectangles[i];
                        movedRegions[i] = new MovedRegion
                        {
                            Source      = new Point(moveRectangle.SourcePoint.X, moveRectangle.SourcePoint.Y),
                            Destination =
                                new Rectangle(moveRectangle.DestinationRect.Left,
                                              moveRectangle.DestinationRect.Top,
                                              moveRectangle.DestinationRect.GetWidth(),
                                              moveRectangle.DestinationRect.GetHeight())
                        };
                    }

                    int dirtyRegionsLength;
                    var dirtyRectangles = new RawRectangle[_frameInfo.TotalMetadataBufferSize - movedRegionsLength];
                    _deskDupl.GetFrameDirtyRects(dirtyRectangles.Length, dirtyRectangles, out dirtyRegionsLength);
                    var updatedAreas = new Rectangle[dirtyRegionsLength / Marshal.SizeOf(typeof(Rectangle))];

                    for (int i = 0; i < updatedAreas.Length; i++)
                    {
                        var dirtyRectangle = dirtyRectangles[i];
                        updatedAreas[i] = new Rectangle(dirtyRectangle.Left, dirtyRectangle.Top,
                                                        dirtyRectangle.GetWidth(), dirtyRectangle.GetHeight());
                    }

                    return(streamCodec.CodeImage(mapSource.DataPointer, updatedAreas, movedRegions,
                                                 new Size(_outputDesc.DesktopBounds.GetWidth(), _outputDesc.DesktopBounds.GetHeight()),
                                                 PixelFormat.Format32bppArgb));
                }
                else
                {
                    return(streamCodec.CodeImage(mapSource.DataPointer,
                                                 new Rectangle(0, 0, _outputDesc.DesktopBounds.GetWidth(), _outputDesc.DesktopBounds.GetHeight()),
                                                 new Size(_outputDesc.DesktopBounds.GetWidth(), _outputDesc.DesktopBounds.GetHeight()),
                                                 PixelFormat.Format32bppArgb));
                }
            }
            finally
            {
                _device.ImmediateContext.UnmapSubresource(_desktopImageTexture, 0);
                ReleaseFrame();
            }
        }
Example #3
0
        private static unsafe void ProcessDelta(Bitmap bitmap, byte[] buffer, int offset, int count)
        {
            var imageBoundaries = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            var imageData = bitmap.LockBits(imageBoundaries, ImageLockMode.WriteOnly, bitmap.PixelFormat);

            var reader = new QuickBinaryReader(buffer);
            var imagePointer = (byte*)imageData.Scan0;

            // Moved Regions
            var movedRegions = reader.ReadUnsignedVariableLength();
            if (movedRegions != 0)
            {
                var tempBuffer = new byte[bitmap.Width * bitmap.Height * 4];

                fixed (byte* tempBufferPointer = &tempBuffer[0])
                {
                    for (var n = 0; n < movedRegions; n++)
                    {
                        var fromX = reader.ReadUnsignedVariableLength();
                        var fromY = reader.ReadUnsignedVariableLength();
                        var toX = reader.ReadUnsignedVariableLength();
                        var toY = reader.ReadUnsignedVariableLength();
                        var width = reader.ReadUnsignedVariableLength();
                        var height = reader.ReadUnsignedVariableLength();
                        var region = new MovedRegion
                        { FromX = fromX, FromY = fromY, Height = height, ToX = toX, ToY = toY, Width = width };

                        CopyRegion(imagePointer, tempBufferPointer, bitmap.Width, region);
                        CopyRegion(tempBufferPointer, imagePointer, bitmap.Width, region);
                    }
                }
            }

            // Modified Regions
            var s = 0;
            while (reader.Position < count)
            {
                var i = reader.ReadSignedVariableLength();
                var pointer = imagePointer + s + i;

                var bg = reader.ReadByte();
                var gr = reader.ReadByte();
                pointer[0] = (byte)(bg & 248);
                pointer[1] = (byte)((bg & 7) << 5 | (gr & 7) << 2);
                pointer[2] = (byte)(gr & 248);

                s += i;
            }

            bitmap.UnlockBits(imageData);
        }