Ejemplo n.º 1
0
        private void ResetFramePool(SizeInt32 size, bool recreateDevice)
        {
            do
            {
                try
                {
                    if (recreateDevice)
                    {
                        _canvasDevice = new CanvasDevice();
                    }

                    _framePool.Recreate(
                        _canvasDevice,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        2,
                        size);
                }
                // This is the device-lost convention for Win2D.
                catch (Exception e) when(_canvasDevice.IsDeviceLost(e.HResult))
                {
                    _canvasDevice  = null;
                    recreateDevice = true;
                }
            } while (_canvasDevice == null);
        }
Ejemplo n.º 2
0
        private void ResetFramePool(SizeInt32 size, bool recreateDevice)
        {
            Logger.Debug("Screen", "ResetFramePool");
            do
            {
                try
                {
                    if (recreateDevice)
                    {
                        canvasDevice = new CanvasDevice();
                    }

                    framePool.Recreate(
                        canvasDevice,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        2,
                        size);
                }
                catch (Exception e) when(canvasDevice.IsDeviceLost(e.HResult))
                {
                    canvasDevice   = null;
                    recreateDevice = true;
                }
            } while (canvasDevice == null);
        }
Ejemplo n.º 3
0
        protected virtual void ResetFramePool(SizeInt32 size, bool recreateDevice)
        {
            do
            {
                try
                {
                    if (recreateDevice)
                    {
                        _device = Direct3D11Helper.CreateDevice(!PresentationToNDIAddIn.Properties.Settings.Default.UseHw);
                    }
                }
                catch
                {
                    _device        = null;
                    recreateDevice = true;
                }
            } while (_device == null);

            // detect change from or to fullscreen --> captureItem needs to be recreated
            if ((_wasFullscreenBefore && !IsFullscreen) || (!_wasFullscreenBefore && IsFullscreen))
            {
                _wasFullscreenBefore = IsFullscreen;
                DisposeCaptureItemDependentStuff();
                _item = GetItem();
                CreateCaptureItemDependendStuff();
            }
            else
            {
                _framePool.Recreate(_device, PixelFormat, 2, size);
            }
        }
Ejemplo n.º 4
0
        private void ResetFramePool(SizeInt32 size, bool recreateDevice)
        {
            do
            {
                try
                {
                    if (recreateDevice)
                    {
                        _canvasDevice = new CanvasDevice();
                        foreach (var clip in ClipImages.Values)
                        {
                            clip.Resize(_canvasDevice, true);
                        }
                    }

                    _framePool.Recreate(
                        _canvasDevice,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        2,
                        size);
                    renderTarget.Dispose();
                    renderTarget = new CanvasRenderTarget(_canvasDevice, size.Width, size.Height, 96);
                }
                // This is the device-lost convention for Win2D.
                catch (Exception e) when(_canvasDevice.IsDeviceLost(e.HResult))
                {
                    _canvasDevice  = null;
                    recreateDevice = true;
                }
            } while (_canvasDevice == null);
        }
Ejemplo n.º 5
0
        public void RequestRender()
        {
            this.fpsCount++;
            using var frame = this.framePool.TryGetNextFrame();
            if (frame != null && this.IsFrontBufferAvailable && this.fpsCount % this.FpsDivider == 0)
            {
                if (this.TryLock(new Duration(TimeSpan.Zero)))
                {
                    var newSize = false;
                    if (frame.ContentSize.Width != lastSize.Width ||
                        frame.ContentSize.Height != lastSize.Height)
                    {
                        // The thing we have been capturing has changed size.
                        // We need to resize the swap chain first, then blit the pixels.
                        // After we do that, retire the frame and then recreate the frame pool.
                        newSize  = true;
                        lastSize = frame.ContentSize;
                        this.renderTargetDescription.Width  = lastSize.Width;
                        this.renderTargetDescription.Height = lastSize.Height;
                        this.renderTarget?.Dispose();
                        this.renderTarget = new Texture2D(d3dDevice, this.renderTargetDescription);
                        backBufferSetted  = false;
                    }

                    using (var bitmap = Direct3D11Helper.CreateSharpDXTexture2D(frame.Surface))
                    {
                        d3dDevice.ImmediateContext.CopyResource(bitmap, this.renderTarget);
                    }

                    if (newSize || !backBufferSetted)
                    {
                        using var resource = this.renderTarget.QueryInterface <SharpDX.DXGI.Resource>();
                        var handle = resource.SharedHandle;

                        using var texture = new Texture(
                                  this.d9device,
                                  this.renderTarget.Description.Width,
                                  this.renderTarget.Description.Height,
                                  1,
                                  SharpDX.Direct3D9.Usage.RenderTarget,
                                  SharpDX.Direct3D9.Format.A8R8G8B8,
                                  Pool.Default,
                                  ref handle);
                        using var surface = texture.GetSurfaceLevel(0);
                        this.SetBackBuffer(D3DResourceType.IDirect3DSurface9, surface.NativePointer, true);
                        backBufferSetted = true;
                    }

                    this.AddDirtyRect(new Int32Rect(0, 0, lastSize.Width, lastSize.Height));

                    if (newSize)
                    {
                        framePool.Recreate(device, DirectXPixelFormat.B8G8R8A8UIntNormalized, 2, lastSize);
                    }
                }

                this.Unlock();
            }
        }
Ejemplo n.º 6
0
        private void OnFrameArrived(Direct3D11CaptureFramePool sender, object args)
        {
            var newSize = false;



            using (var frame = sender.TryGetNextFrame())
            {
                if (frame.ContentSize.Width != lastSize.Width ||
                    frame.ContentSize.Height != lastSize.Height)
                {
                    // The thing we have been capturing has changed size.
                    // We need to resize the swap chain first, then blit the pixels.
                    // After we do that, retire the frame and then recreate the frame pool.
                    newSize  = true;
                    lastSize = frame.ContentSize;

                    swapChain.ResizeBuffers(
                        2,
                        lastSize.Width,
                        lastSize.Height,
                        SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                        SharpDX.DXGI.SwapChainFlags.None);
                }

                if (!isWait)
                {
                    if (isStartCapture)
                    {
                        using (var backBuffer = swapChain.GetBackBuffer <SharpDX.Direct3D11.Texture2D>(0))
                            using (var bitmap = Direct3D11Helper.CreateSharpDXTexture2D(frame.Surface))
                            {
                                //d3dDevice.ImmediateContext.CopyResource(bitmap, backBuffer);
                                CopyBitmap(frame.Surface, bitmap, frame.ContentSize.Width, frame.ContentSize.Height);

                                Console.WriteLine("Capture");

                                bitmap.Dispose();
                            };

                        isStartCapture = false;
                    }
                }

                //using (var backBuffer = swapChain.GetBackBuffer<SharpDX.Direct3D11.Texture2D>(0))
            } // Retire the frame.

            swapChain.Present(0, SharpDX.DXGI.PresentFlags.None);

            if (newSize)
            {
                framePool.Recreate(
                    device,
                    DirectXPixelFormat.B8G8R8A8UIntNormalized,
                    2,
                    lastSize);
            }
        }
        public void Resize(SizeInt32 size)
        {
            _initSize = size;
            _screenTexture?.Dispose();
            _screenTexture = CreateTexture(size);

            ScreenCaptureManager.Instance.MainThreadExecutor.Execute(() =>
            {
                if (_framePool != null)
                {
                    _framePool.Recreate(
                        _device,
                        DirectXPixelFormat.B8G8R8A8UIntNormalized,
                        2,
                        size);
                }
            }, true);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 帧到达事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void OnFrameArrived(Direct3D11CaptureFramePool sender, object args)
        {
            var newSize = false;

            using Direct3D11CaptureFrame frame = sender.TryGetNextFrame();

            if (frame == null)
            {
                return;
            }

            if (frame.ContentSize.Width != lastSize.Width || frame.ContentSize.Height != lastSize.Height)
            {
                // 我们捕捉到的东西变大了。
                // 我们需要先调整交换链的大小,然后blit像素。
                // 完成此操作后,请注销帧,然后重新创建帧池。
                newSize  = true;
                lastSize = frame.ContentSize;
                swapChain.ResizeBuffers(
                    2,
                    lastSize.Width,
                    lastSize.Height,
                    SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                    SharpDX.DXGI.SwapChainFlags.None);
            }

            using Texture2D backBuffer = swapChain.GetBackBuffer <Texture2D>(0);
            using Texture2D tex        = Direct3D11Helper.CreateSharpDXTexture2D(frame.Surface);
            d3dDevice.ImmediateContext.CopyResource(tex, backBuffer);
            // 保存当前帧到位图
            if (GetOneFrameFromBitmapEvent != null)
            {
                TryGetOneFrameToBitmap(tex);
            }
            // GetOneFrameToBitmap(tex);

            swapChain.Present(0, SharpDX.DXGI.PresentFlags.None);

            if (newSize)
            {
                framePool.Recreate(device, Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, 2, lastSize);
            }
        }
Ejemplo n.º 9
0
        private void OnFrameArrived(Direct3D11CaptureFramePool sender, object args)
        {
            var newSize = false;

            using (var frame = sender.TryGetNextFrame())
            {
                if (frame.ContentSize.Width != _lastSize.Width ||
                    frame.ContentSize.Height != _lastSize.Height)
                {
                    // 源已改变,故需要变换抓取大小,首先改变swap chain,之后是Texture
                    newSize   = true;
                    _lastSize = frame.ContentSize;
                    _swapChain.ResizeBuffers(
                        2,
                        _lastSize.Width,
                        _lastSize.Height,
                        SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                        SharpDX.DXGI.SwapChainFlags.None);
                }

                using (var sourceTexture = Direct3D11Helpers.CreateSharpDXTexture2D(frame.Surface))
                    using (var backBuffer = _swapChain.GetBackBuffer <SharpDX.Direct3D11.Texture2D>(0))
                        using (var renderTargetView = new SharpDX.Direct3D11.RenderTargetView(_d3dDevice, backBuffer))
                        {
                            _d3dDevice.ImmediateContext.ClearRenderTargetView(renderTargetView, new SharpDX.Mathematics.Interop.RawColor4(0, 0, 0, 1));
                            _d3dDevice.ImmediateContext.CopyResource(sourceTexture, backBuffer);
                        }
            }

            _swapChain.Present(1, SharpDX.DXGI.PresentFlags.None);

            if (newSize)//帧池重构
            {
                _framePool.Recreate(
                    _device,
                    DirectXPixelFormat.B8G8R8A8UIntNormalized,
                    2,
                    _lastSize);
            }
        }
Ejemplo n.º 10
0
        private void OnFrameArrived(Direct3D11CaptureFramePool sender, object args)
        {
            var newSize = false;

            using (var frame = sender.TryGetNextFrame())
            {
                if (frame.ContentSize.Width != _lastSize.Width ||
                    frame.ContentSize.Height != _lastSize.Height)
                {
                    newSize   = true;
                    _lastSize = frame.ContentSize;
                }
                using (var bitmap = Direct3D11Helper.CreateSharpDXTexture2D(frame.Surface))
                {
                    FrameArrived?.Invoke(new CapturedBitmap(bitmap));
                }
            }
            if (newSize)
            {
                _framePool.Recreate(_device, DirectXPixelFormat.B8G8R8A8UIntNormalized, 2, _lastSize);
            }
        }
Ejemplo n.º 11
0
        private void ProcessFrame(Direct3D11CaptureFrame frame)
        {
            // Resize and device-lost leverage the same function on the
            // Direct3D11CaptureFramePool. Refactoring it this way avoids
            // throwing in the catch block below (device creation could always
            // fail) along with ensuring that resize completes successfully and
            // isn’t vulnerable to device-lost.
            bool needsReset = false;

            if ((frame.ContentSize.Width != _lastSize.Width) ||
                (frame.ContentSize.Height != _lastSize.Height))
            {
                needsReset = true;
                _lastSize  = frame.ContentSize;
            }

            try
            {
                // Convert our D3D11 surface into a Win2D object.
                var bitmap = CanvasBitmap.CreateFromDirect3D11Surface(
                    this.measureCanvas.Device,
                    frame.Surface);
                measureCanvas.Update(bitmap);
            }
            catch
            {
                needsReset = true;
            }

            if (needsReset)
            {
                _framePool.Recreate(
                    this.measureCanvas.Device,
                    DirectXPixelFormat.B8G8R8A8UIntNormalized,
                    2,
                    frame.ContentSize);
            }
        }
Ejemplo n.º 12
0
        private void OnFrameArrived(Direct3D11CaptureFramePool sender, object args)
        {
            var newSize = false;

            using (var frame = sender.TryGetNextFrame())
            {
                if (frame.ContentSize.Width != lastSize.Width ||
                    frame.ContentSize.Height != lastSize.Height)
                {
                    // The thing we have been capturing has changed size.
                    // We need to resize the swap chain first, then blit the pixels.
                    // After we do that, retire the frame and then recreate the frame pool.
                    newSize         = true;
                    lastSize        = frame.ContentSize;
                    lastSize.Width  = lastSize.Width / 8 * 8;
                    lastSize.Height = lastSize.Height / 8 * 8;
                    swapChain.ResizeBuffers(
                        2,
                        lastSize.Width,
                        lastSize.Height,
                        Format.B8G8R8A8_UNorm,
                        SwapChainFlags.None);
                }

                using (var backBuffer = swapChain.GetBackBuffer <SharpDX.Direct3D11.Texture2D>(0))
                    using (var bitmap = Direct3D11Helper.CreateSharpDXTexture2D(frame.Surface))
                    {
                        d3dDevice.ImmediateContext.CopyResource(bitmap, backBuffer);

                        if (lastFrame != null)
                        {
                            d3dDevice.ImmediateContext.UnmapSubresource(lastFrame, 0);
                            lastFrame.Dispose();
                        }

                        // Create texture copy
                        lastFrame = new SharpDX.Direct3D11.Texture2D(d3dDevice, new SharpDX.Direct3D11.Texture2DDescription
                        {
                            Width             = bitmap.Description.Width,
                            Height            = bitmap.Description.Height,
                            MipLevels         = 1,
                            ArraySize         = 1,
                            Format            = Format.B8G8R8A8_UNorm,
                            Usage             = ResourceUsage.Staging,
                            SampleDescription = new SampleDescription(1, 0),
                            BindFlags         = BindFlags.None,
                            CpuAccessFlags    = CpuAccessFlags.Read,
                            OptionFlags       = ResourceOptionFlags.None
                        });
                        d3dDevice.ImmediateContext.CopyResource(bitmap, lastFrame);

                        var dataBox = d3dDevice.ImmediateContext.MapSubresource(lastFrame, 0, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None, out DataStream stream);
                        var rect    = new DataRectangle
                        {
                            DataPointer = stream.DataPointer,
                            Pitch       = dataBox.RowPitch
                        };
                        lastMat = new Mat(lastFrame.Description.Height, lastFrame.Description.Width, MatType.CV_8UC4, stream.DataPointer); // width % 4 != 0

                        OnFrameReady(EventArgs.Empty);
                    }
            } // Retire the frame.

            // swapChain.Present(0, SharpDX.DXGI.PresentFlags.None);
            if (newSize)
            {
                framePool.Recreate(
                    device,
                    DirectXPixelFormat.B8G8R8A8UIntNormalized,
                    2,
                    lastSize);
            }
        }