コード例 #1
0
 public int Write(Frame frame, int inputNo)
 {
     _currentFramePts = frame.Properties.Pts;
     _currentFrame?.Dispose();
     _currentFrame = _uploader.Upload(frame.Properties.DataPtr0, frame.Properties.DataPtr1, frame.Properties.DataPtr2);
     return(0);
 }
コード例 #2
0
 public int Write(Frame frame, int inputNo)
 {
     _currentFramePts = frame.Properties.Pts;
     _currentFrame?.Dispose();
     _currentFrame = _transform.Process(frame);
     return(0);
 }
コード例 #3
0
        // the code below failing due to GC

        /*public static SharpDX.WIC.BitmapSource LoadBitmap(DirectXContext directXContext, Stream stream)
         * {
         *  var bitmapDecoder = new SharpDX.WIC.BitmapDecoder(
         *      directXContext.ImagingFactory2,
         *      stream,
         *      SharpDX.WIC.DecodeOptions.CacheOnLoad);
         *
         *  var formatConverter = new SharpDX.WIC.FormatConverter(directXContext.ImagingFactory2);
         *
         *  formatConverter.Initialize(
         *      bitmapDecoder.GetFrame(0),
         *      SharpDX.WIC.PixelFormat.Format32bppPRGBA,
         *      SharpDX.WIC.BitmapDitherType.None,
         *      null,
         *      0.0,
         *      SharpDX.WIC.BitmapPaletteType.Custom);
         *
         *  return formatConverter;
         * }*/

        public static DirectXResource CreateTexture2DFromBitmap(DirectXContext directXContext, SharpDX.WIC.BitmapSource bitmapSource)
        {
            // Allocate DataStream to receive the WIC image pixels
            int stride = bitmapSource.Size.Width * 4;

            using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
            {
                try
                {
                    // Copy the content of the WIC to the buffer
                    bitmapSource.CopyPixels(stride, buffer);
                }
                catch (Exception e)
                {
                    Core.LogError(e, "Failed to load image into Dx");
                }

                return(directXContext.Pool.Get("loadbitmap", DirectXResource.Desc(bitmapSource.Size.Width,
                                                                                  bitmapSource.Size.Height,
                                                                                  SharpDX.DXGI.Format.R8G8B8A8_UNorm,
                                                                                  SharpDX.Direct3D11.BindFlags.ShaderResource,
                                                                                  SharpDX.Direct3D11.ResourceUsage.Immutable),
                                               new SharpDX.DataRectangle(buffer.DataPointer, stride)));
            }
        }
コード例 #4
0
 public void Dispose()
 {
     _currentFrame?.Dispose();
     _dx?.RemoveRef();
     _currentFrame = null;
     _dx           = null;
 }
コード例 #5
0
        private void DisplayAsTexture(DirectXResource res)
        {
            if (res.Texture2D == null)
            {
                Core.LogWarning("DisplayAsTexture failed as Texture2D == null");
                return;
            }

            res.GetDx().RunOnContext(ctx =>
            {
                ctx.CopyResource(res.Texture2D, _sharedResource);
                ctx.Flush();
            }, "CopyToUI");

            if (_d3dimage.TryLock(TimeSpan.FromMilliseconds(1500)))
            {
                _d3dimage.AddDirtyRect(new Int32Rect(0, 0, res.Texture2D.Description.Width, res.Texture2D.Description.Height));
                _d3dimage.Unlock();
            }
            else
            {
                Core.LogWarning("Failed to Lock DirectXPresenter/d3dimage");
            }

            if (Source != _d3dimage)
            {
                Core.LogInfo("Assigning new D3DImage");
                Source = _d3dimage;
            }
        }
コード例 #6
0
        public void Back(DirectXResource resource)
        {
            if (resource != null)
            {
                Interlocked.Decrement(ref _countInField);

                if (resource.CommandList != null)
                {
                    resource.CommandList.Dispose();
                    resource.CommandList = null;
                }

                if (!resource.Cachable)
                {
                    resource.CleanInternalResources();
                    return;
                }

                resource.InPoolTime = DateTime.UtcNow;

                lock (this)
                {
                    if (_active)
                    {
                        _perType[resource.Texture2D.Description].AddLast(resource);
                        return;
                    }
                }

                if (resource != null)
                {
                    resource.CleanInternalResources();
                }
            }
        }
コード例 #7
0
        internal DirectXResource Render(DirectXContext dx, VideoFilterChainDescriptor filterChain, DeviceContext ctx, DirectXResource texture)
        {
            DirectXResource current = texture;

            try
            {
                if (dx != _dx || !Equals(filterChain, _filterChain))
                {
                    TearDown();
                    _dx          = dx;
                    _filterChain = filterChain;
                    Setup(dx, filterChain);
                }

                foreach (var stage in _stages)
                {
                    var next = stage.Render(ctx, current);
                    if (current != next && current != texture)
                    {
                        dx.Pool.Back(current);
                    }
                    current = next;
                    dx.Flush(ctx, "Filter stage");
                }
            }
            catch (SharpDXException e)
            {
                _dx.Broken(e);
            }

            return(current);
        }
コード例 #8
0
 private void Render(DirectXResource input, DirectXDownloaderPlaneData plane, DeviceContext ctx)
 {
     using (var srv = input.GetShaderResourceView())
         using (var rtv = plane.GpuTexture.GetRenderTargetView())
         {
             plane.Pipeline.Render(ctx, rtv, srv);
         }
 }
コード例 #9
0
        private FramePlaneDesc Map(DirectXResource input, DirectXDownloaderPlaneData plane, DeviceContext ctx)
        {
            ctx.CopyResource(plane.GpuTexture.Texture2D, plane.CpuTexture.Texture2D);
            var db = ctx.MapSubresource(plane.CpuTexture.Texture2D, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None);

            return(new FramePlaneDesc {
                Data = db.DataPointer, Stride = db.RowPitch, StrideCount = _height / plane.Format.HeightFactor
            });
        }
コード例 #10
0
 private void Render(DirectXResource input, DirectXResource output, DirectXTransformerPlaneData plane, DeviceContext ctx)
 {
     using (var srv = input.GetShaderResourceView())
         using (var rtv = new RenderTargetView(ctx.Device, output.Texture2D, new RenderTargetViewDescription {
             Format = plane.Format, Dimension = RenderTargetViewDimension.Texture2D
         }))
         {
             plane.Pipeline.Render(ctx, rtv, srv);
         }
 }
コード例 #11
0
        public virtual DirectXResource Render(DeviceContext ctx, DirectXResource source)
        {
            var target = Dx.Pool.Get("FilterStage", DirectXResource.Desc(source.Texture2D.Description.Width, source.Texture2D.Description.Height));

            using var rtv = target.GetRenderTargetView();
            using var srv = source.GetShaderResourceView();

            Pipeline.SetPosition(DirectXPipelineConfig.FullRectangle, new Viewport(0, 0, source.Texture2D.Description.Width, source.Texture2D.Description.Height));
            Render(ctx, rtv, srv, source.Texture2D.Description.Width, source.Texture2D.Description.Height);

            return(target);
        }
コード例 #12
0
 public int Write(Frame frame, int inputNo)
 {
     _currentFramePts = frame.Properties.Pts;
     _currentFrame?.Dispose();
     _currentFrame = _dx.Pool.Get("passthru2", DirectXResource.Desc(_width,
                                                                    _height,
                                                                    SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                                                                    SharpDX.Direct3D11.BindFlags.ShaderResource,
                                                                    SharpDX.Direct3D11.ResourceUsage.Immutable),
                                  new SharpDX.DataRectangle(frame.Properties.DataPtr0, _width * 4));
     return(0);
 }
コード例 #13
0
 public ErrorCodes Read(Frame frame)
 {
     if (_currentFrame == null)
     {
         return(ErrorCodes.TryAgainLater);
     }
     else
     {
         frame.InitFromDirectX(_currentFrame, _currentFramePts);
         _currentFrame = null;
         return(ErrorCodes.Ok);
     }
 }
コード例 #14
0
        public DirectXResource Process(Frame input)
        {
            var texOut = _dx.Pool.Get("transfer out", DirectXResource.Desc(_width, _height, Format.NV12,
                                                                           BindFlags.RenderTarget, ResourceUsage.Default, ResourceOptionFlags.Shared, CpuAccessFlags.None));

            _dx.RunOnContext(ctx =>
            {
                for (int q = 0; q < _planes.Count; q++)
                {
                    Render(input.DirectXResourceRef.Instance, texOut, _planes[q], ctx);
                }
            }, "Transfer Render");

            return(texOut);
        }
コード例 #15
0
        private static DirectXDownloaderPlaneData CreatePlane(DirectXContext dx, int width, int height, DirectXDownloaderFormatPlane plane)
        {
            var config = new DirectXPipelineConfig
            {
                VertexShaderFile     = "format_conversion.hlsl",
                VertexShaderFunction = plane.VS,
                PixelShaderFile      = "format_conversion.hlsl",
                PixelShaderFunction  = plane.PS,
            };

            var pipeline = new DirectXPipeline <ConverterFilterConstantBuffer>(config, dx);

            pipeline.SetDebugColor(0, 0, 0, 1);
            pipeline.SetPosition(DirectXPipelineConfig.FullRectangle, new Viewport(0, 0, width / plane.WidthFactor, height / plane.HeightFactor));
            var colorMatrix = ColorMatrices.GetInverted(ColorMatrices.Full709);
            var cm          = colorMatrix.Values;
            var cb          = new ConverterFilterConstantBuffer
            {
                width      = width,
                height     = height,
                width_i    = 1.0f / width,
                width_d2   = width / 2,
                height_d2  = height / 2,
                width_x2_i = 0.5f / width,

                color_vec0      = new Vector4(cm[0], cm[1], cm[2], cm[3]),
                color_vec1      = new Vector4(cm[4], cm[5], cm[6], cm[7]),
                color_vec2      = new Vector4(cm[8], cm[9], cm[10], cm[11]),
                color_range_min = new Vector3(0.0f, 0.0f, 0.0f),
                color_range_max = new Vector3(1.0f, 1.0f, 1.0f),
            };

            pipeline.SetConstantBuffer(cb, false);

            return(new DirectXDownloaderPlaneData
            {
                Format = plane,
                Pipeline = pipeline,
                GpuTexture = dx.Pool.Get("downloadGpu", DirectXResource.Desc(width / plane.WidthFactor, height / plane.HeightFactor, plane.Format)),
                CpuTexture = dx.Pool.Get("downloadCpu", DirectXResource.Desc(width / plane.WidthFactor, height / plane.HeightFactor, plane.Format, BindFlags.None, ResourceUsage.Staging, ResourceOptionFlags.None, CpuAccessFlags.Read))
            });
        }
コード例 #16
0
        private void DownloadAndDisplayAsBitmap(DirectXResource res)
        {
            int width  = res.Texture2D.Description.Width;
            int height = res.Texture2D.Description.Height;
            var dx     = res.GetDx();

            PrepareSoftwareImage(width, height, PixelFormats.Bgra32);

            if (_cpuTexture == null ||
                _cpuTexture.Texture2D == null ||
                _cpuTexture.Texture2D.Description.Width != width ||
                _cpuTexture.Texture2D.Description.Height != height ||
                _cpuTextureOwner != dx)
            {
                _cpuTexture?.Dispose();
                _cpuTextureOwner = dx;
                _cpuTexture      = dx.Pool.Get("uiCpu", DirectXResource.Desc(width, height, SharpDX.DXGI.Format.B8G8R8A8_UNorm, BindFlags.None, ResourceUsage.Staging, ResourceOptionFlags.None, CpuAccessFlags.Read));
            }

            DataBox db = new DataBox();

            dx.RunOnContext(ctx =>
            {
                ctx.CopyResource(res.Texture2D, _cpuTexture.Texture2D);
                ctx.Flush();
                db = ctx.MapSubresource(_cpuTexture.Texture2D, 0, MapMode.Read, MapFlags.None);
            }, "Download for ui");

            if (db.SlicePitch > 0)
            {
                _softwareImage.WritePixels(new Int32Rect(0, 0, width, height), db.DataPointer, db.SlicePitch, db.RowPitch);
            }
            dx.RunOnContext(ctx => ctx.UnmapSubresource(_cpuTexture.Texture2D, 0), "Unmap for ui");

            if (Source != _softwareImage)
            {
                Source = _softwareImage;
            }
        }
コード例 #17
0
        public void Enqueue(IntPtr buffer, int size)
        {
            lock (_queueLock)
            {
                if (_queue.Count == _maxPackets)
                {
                    _streamer.PacketPool.Back(_queue.Dequeue());
                    Core.LogWarning($"Queue '{_name}' reached maximum");
                }

                var packet = _streamer.PacketPool.Rent();
                var now    = Core.GetCurrentTime();

                if (_dx == null)
                {
                    packet.InitFromBuffer(buffer, size, now);
                }
                else
                {
                    var dx = _dx.Pool.Get("WebBrowserQueue", DirectXResource.Desc(_width,
                                                                                  _height,
                                                                                  SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                                                                                  SharpDX.Direct3D11.BindFlags.ShaderResource,
                                                                                  SharpDX.Direct3D11.ResourceUsage.Immutable),
                                          new SharpDX.DataRectangle(buffer, _width * 4));
                    packet.InitFromDirectX(dx, now);
                }
                _queue.Enqueue(packet);

                // update last
                _streamer.PacketPool.Back(_last);
                _last = _streamer.PacketPool.Rent();
                _last.CopyContentFrom(packet);
                _lastEnqueueTime = now;

                Monitor.PulseAll(_queueLock);
            }
        }
コード例 #18
0
 private DirectXPipeline <BlendingConstantBuffer> GetPipeline(VideoBlenderInputRuntime runtime, DirectXResource canvas, DirectXResource image)
 {
     if (_directXPipelineLowRes != null)
     {
         if (runtime.Description.Ptz.Width > 0 && runtime.Description.Ptz.Height > 0)
         {
             var heightScale = runtime.Description.Rect.Height / runtime.Description.Ptz.Height;
             var widthScale  = runtime.Description.Rect.Width / runtime.Description.Ptz.Width;
             if (heightScale * canvas.Texture2D.Description.Height < 0.8 * image.Texture2D.Description.Height ||
                 widthScale * canvas.Texture2D.Description.Width < 0.8 * image.Texture2D.Description.Width)
             {
                 return(_directXPipelineLowRes);
             }
         }
     }
     return(_directXPipeline);
 }
コード例 #19
0
        public int Write(Packet packet)
        {
            RemoveCurrent();

            _currentFramePts = packet.Properties.Pts;

            if (_dx != null)
            {
                _currentResource = new RefCounted <DirectXResource>(_dx.Pool.Get("passthru", DirectXResource.Desc(_width,
                                                                                                                  _height,
                                                                                                                  SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                                                                                                                  SharpDX.Direct3D11.BindFlags.ShaderResource,
                                                                                                                  SharpDX.Direct3D11.ResourceUsage.Immutable),
                                                                                 new SharpDX.DataRectangle(packet.Properties.DataPtr, _width * 4)));
            }
            else
            {
                _currentResource = packet.DirectXResourceRef.AddRef();
            }
            return(0);
        }
コード例 #20
0
        private bool RenderDirectX(Frame resultPayload, out PayloadTrace trace)
        {
            trace = null;
            bool hasAnyContent = false;
            var  dx            = _setup.Dx;

            try
            {
                if (dx.IsBrokenAndLog("Blender"))
                {
                    return(false);
                }

                var texture = dx.Pool.Get("Blender", DirectXResource.Desc(_setup.Width, _setup.Height, SharpDX.DXGI.Format.B8G8R8A8_UNorm, BindFlags.ShaderResource | BindFlags.RenderTarget, ResourceUsage.Default, ResourceOptionFlags.None));

                _defferedContext = _defferedContext ?? new DeviceContext(dx.Device);
                //using
                using (var rtv = texture.GetRenderTargetView())
                {
                    int counter = 0;

                    foreach (var runtime in _inputRuntimesSorted)
                    {
                        var frameData = GetRuntimeOrFixedFrame(runtime);
                        if (frameData != null && runtime.Description.Visible)
                        {
                            hasAnyContent = true;

                            UpdateTrace(frameData, ref trace);

                            var xResource = frameData.Payload.DirectXResourceRef.Instance;

                            if (xResource.CommandList != null)
                            {
                                _defferedContext.ExecuteCommandList(xResource.CommandList, false);
                                xResource.CommandList.Dispose();
                                xResource.CommandList = null;
                            }

                            var pipeline = GetPipeline(runtime, texture, xResource);
                            SetDebugColor(pipeline, counter++);
                            UpdatePositionInDxPipeline(runtime, pipeline, xResource.Texture2D.Description.Width, xResource.Texture2D.Description.Height);

                            var filteredResource = runtime.DirectXFilterRuntime.Render(dx, runtime.Description.FilterChain, _defferedContext, xResource);
                            if (ReferenceEquals(filteredResource, xResource))
                            {
                                using (var srv = filteredResource.GetShaderResourceView())
                                    pipeline.Render(_defferedContext, rtv, srv);
                                dx.Flush(_defferedContext, "Blender Flush All");
                            }
                            else
                            {
                                dx.Flush(_defferedContext, "Blender Flush All");
                                using (var srvFiltered = filteredResource.GetShaderResourceView())
                                    pipeline.Render(_defferedContext, rtv, srvFiltered);
                                dx.Flush(_defferedContext, "Blender Flush All");
                                filteredResource.Dispose();
                            }
                        }
                    }
                }

                if (hasAnyContent)
                {
                    if (trace != null)
                    {
                        trace = PayloadTrace.Create(_name, trace);
                    }

                    dx.Flush(_defferedContext, "Blender Flush All");
                    var allFilteredResource = _dxFilterRuntime.Render(dx, _setup.WeakOptions.FilterChain, _defferedContext, texture);
                    dx.Flush(_defferedContext, "Blender Flush All");

                    resultPayload.InitFromDirectX(allFilteredResource, _currentFpsTicks);

                    if (allFilteredResource != texture)
                    {
                        dx.Pool.Back(texture);
                    }
                }
            }
            catch (Exception e)
            {
                dx.Broken(e);
            }

            return(hasAnyContent);
        }
コード例 #21
0
        private void OpenSharedResourceIfNeeded(DirectXResource res)
        {
            try
            {
                bool reinit = false;
                _occludedCounter++;

                if (_occludedCounter % 1 == 0) // every 200 ms
                {
                    var  state         = _device?.CheckDeviceState(_windowHandle) ?? DeviceState.Ok;
                    bool occludedState = state == DeviceState.PresentOccluded; // happens when windows is locked; then we could get black screen in preview d3dImage

                    reinit = _occludedState && !occludedState;                 // reinit if change from bad -> good
                    if (reinit)
                    {
                        Core.LogInfo("occluded -> normal");

                        if (_windowStateManager.IsMinimized())
                        {
                            _windowStateManager.IsMinimizedChanged += OnwindowStateManagerIsMinimizedChanged;
                        }
                        else
                        {
                            _ = ReinitSurfacesWithDelay();
                        }
                    }

                    if (!_occludedState && occludedState)
                    {
                        Core.LogInfo("normal -> occluded");
                    }

                    _occludedState = occludedState;
                }

                if (_sharedResource == null ||
                    _sharedResource.Description.Width != res.Texture2D.Description.Width ||
                    _sharedResource.Description.Height != res.Texture2D.Description.Height ||
                    _sharedResourceOwner != res.GetDx() ||
                    _reinitSurfaces)
                {
                    Core.LogInfo("Initing DX Presenter surface");
                    Source          = null;
                    _reinitSurfaces = false;

                    _surfaceD9?.Dispose();
                    _sharedResource?.Dispose();

                    _surfaceD9           = null;
                    _sharedResource      = null;
                    _sharedResourceOwner = null;


                    IntPtr handle = IntPtr.Zero;
                    _surfaceD9 = Surface.CreateRenderTarget(_device, res.Texture2D.Description.Width, res.Texture2D.Description.Height, Format.A8R8G8B8, MultisampleType.None, 0, true, ref handle);
                    if (handle == IntPtr.Zero)
                    {
                        Core.LogWarning("DirectX 9 Device failed to create Surface. Reinit Devices");
                        _device?.Dispose();
                        _direct3d?.Dispose();
                        _device   = null;
                        _direct3d = null;
                        InitDx9();
                        _surfaceD9 = Surface.CreateRenderTarget(_device, res.Texture2D.Description.Width, res.Texture2D.Description.Height, Format.A8R8G8B8, MultisampleType.None, 0, true, ref handle);

                        if (handle == IntPtr.Zero)
                        {
                            Core.LogWarning("DirectX 9 Device failed to create Surface after recreation.");
                        }
                    }
                    _sharedResource      = res.GetDx().Device.OpenSharedResource <Texture2D>(handle);
                    _sharedResourceOwner = res.GetDx();

                    _d3dimage = new D3DImage();
                    _d3dimage.Lock();
                    _d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, _surfaceD9.NativePointer);
                    _d3dimage.Unlock();

                    Core.LogInfo("Inited DX Presenter surface");
                }
            }
            catch (Exception e)
            {
                Core.LogError(e, "Failed to open shared resource");
            }
        }