public static async Task Run(WebSocket webSocket) { var scaleNom = 1; var scaleDen = 1; var width = (1280 * scaleNom / scaleDen) | 0; var height = (720 * scaleNom / scaleDen) | 0; var frameSpec = new FrameSpec(width, height, 1); using (var jpegCompressor = new JpegCompressor()) { const int workerCount = 2; var receiveBuffer = new byte[1024 * 4]; var stats = new FrameStats(); var workers = Enumerable.Range(0, workerCount) .Select(index => new FrameWorker(frameSpec, "background-small.jpg", jpegCompressor, stats, webSocket)) .ToArray(); var requests = Enumerable.Repeat(FrameRequest.Completed, workerCount) .ToArray(); int workerIndex = 0; // Ready to start await webSocket.SendJsonAsync("READY", frameSpec); double lastFrameTimeMS = -1; int lastFrameId = -1; // Start render loop while (!webSocket.CloseStatus.HasValue) // && lastFrameTimeMS < 250) { var message = await webSocket.ReceiveJsonAsync(default, receiveBuffer);
public FrameWorker(FrameSpec spec, string backgroundPath, JpegCompressor jpegCompressor, FrameStats stats, WebSocket webSocket) { _spec = spec; _stats = stats; _background = backgroundPath == null ? null : Image.FromFile(backgroundPath); _jpegCompressor = jpegCompressor; _webSocket = webSocket; _cancellationSource = new CancellationTokenSource(); _cancellationToken = _cancellationSource.Token; _thread = new Thread(ThreadEntry) { Priority = ThreadPriority.AboveNormal }; _thread.Start(); }
public JpegFrame(JpegCompressor compressor, int width, int height, TJSubsamplingOptions subSampling) { _compressor = compressor; checked { Width = width; Height = height; SubSampling = subSampling; MaxBufferSize = (int)JpegLibrary.tjBufSize(width, height, (int)subSampling); } var bufferHandle = JpegLibrary.tjAlloc(MaxBufferSize); if (bufferHandle == IntPtr.Zero) { throw new OutOfMemoryException( $"Failed to allocate TurboJPEG buffer of size {width}x{height}, subSampling {subSampling}"); } SetResourceHandle(bufferHandle); }
protected override void Free(IntPtr handle) { _compressor = null; JpegLibrary.tjFree(handle); }