Beispiel #1
0
        protected override void OnDispose(bool isDisposing)
        {
            if (isDisposing)
            {
                if (_queue.Count != VideoFrameQueueSize)
                {
                    Debug.WriteLine("VideoRenderer is being disposed while frames are still being encoded.");
                }

                var videoTrack = VideoTrack;
                if (videoTrack != null)
                {
                    videoTrack.LocalVideoFrameProcessed -= OnLocalVideoFrameProcessed;
                }

                _frameTable.Values.DisposeAll();

                ThreadLock3D?.Dispose();
                DeviceDXGI?.Dispose();
                Device3D?.Dispose();
                FactoryDXGI?.Dispose();

                _sdlWindow?.Dispose();
            }
        }
Beispiel #2
0
        public VideoRenderer(VideoTrack videoTrack, RendererOptions options)
        {
            VideoTrack = videoTrack;

            VideoFrameWidth     = options.VideoFrameWidth;
            VideoFrameHeight    = options.VideoFrameHeight;
            VideoFrameQueueSize = options.VideoFrameQueueSize;

            videoTrack.LocalVideoFrameProcessed += OnLocalVideoFrameProcessed;

            // _onMissedFrame = options.OnMissedFrame ?? OnMissedFrame;

            bool debug = options.CreationFlags.HasFlag(D3D11.DeviceCreationFlags.Debug);

            FactoryDXGI = new DXGI.Factory2(debug);

            // Find the requested adapter.
            using (var adapters = FactoryDXGI.Adapters.ToDisposableList())
            {
                var adapter = adapters.First(a => a.Description.VendorId == options.AdapterVendorId);

                Device3D = new D3D11.Device(adapter, options.CreationFlags, options.FeatureLevels);

                DeviceDXGI = Device3D.QueryInterface <DXGI.Device>();

                // We need to access D3D11 on multiple threads, so enable multi-threading
                ThreadLock3D = Device3D.ImmediateContext.QueryInterface <D3D11.Multithread>();
                ThreadLock3D.SetMultithreadProtected(true);

                if (options.PreviewWindowOptions != null)
                {
                    var width  = options.PreviewWindowOptions.Width ?? VideoFrameWidth;
                    var height = options.PreviewWindowOptions.Height ?? width * VideoFrameHeight / VideoFrameWidth;

                    _sdlWindow = new SdlWindow("WebRTC server preview", width, height);


                    // SwapChain description
                    var desc = new DXGI.SwapChainDescription1()
                    {
                        BufferCount       = 2,
                        AlphaMode         = DXGI.AlphaMode.Unspecified,
                        Format            = DXGI.Format.B8G8R8A8_UNorm,
                        Width             = VideoFrameWidth,
                        Height            = VideoFrameHeight,
                        Scaling           = DXGI.Scaling.Stretch,
                        Stereo            = false,
                        Flags             = DXGI.SwapChainFlags.AllowTearing | DXGI.SwapChainFlags.FrameLatencyWaitAbleObject,
                        Usage             = DXGI.Usage.RenderTargetOutput,
                        SampleDescription = new DXGI.SampleDescription(1, 0),
                        SwapEffect        = DXGI.SwapEffect.FlipDiscard,
                    };

                    SwapChain = new DXGI.SwapChain1(FactoryDXGI, Device3D, _sdlWindow.NativeHandle, ref desc);

                    using (var swapChain2 = SwapChain.QueryInterface <DXGI.SwapChain2>())
                    {
                        var value = swapChain2.MaximumFrameLatency;
                        swapChain2.MaximumFrameLatency = 1;
                    }
                }
            }
        }