public VideoRenderer(VideoTrack videoTrack, RendererOptions options) { VideoTrack = videoTrack; VideoFrameWidth = options.VideoFrameWidth; VideoFrameHeight = options.VideoFrameHeight; VideoFrameQueueSize = options.VideoFrameQueueSize; videoTrack.LocalVideoFrameEncoded += OnLocalVideoFrameEncoded; // _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); } }
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; } } } }