/// <summary> /// The serialized form of this object should fit within the returned buffer size. /// </summary> /// <param name="jpegQuality"></param> /// <param name="subsamp"></param> /// <returns></returns> public int GetMaximumRequiredBufferSize(int jpegQuality = 80, turbojpegCLI.SubsamplingOption subsamp = SubsamplingOption.SAMP_420) { // Calculate maximum size of buffer required to hold the entire command and all its data, starting from the initial command code int maxCommandSize = 1 + 1 + 2 + 2 + (13 * movedFragments.Length) + (13 * dirtyFragments.Length); foreach (DirtyImageFragment dirtyFrag in dirtyFragments) { if (dirtyFrag.screenshot.BufferIsCompressed) { maxCommandSize += dirtyFrag.screenshot.Buffer.Length; } else { maxCommandSize += turbojpegCLI.TJ.bufSize(dirtyFrag.screenshot.Width, dirtyFrag.screenshot.Height, subsamp); } } return(maxCommandSize); }
private static void desktopCaptureThreadRunner() { try { byte[] compressToBuffer = null; while (!isExiting && static_sm != null) { Thread.Sleep(1); DesktopCaptureTask task; while (!isExiting && static_sm != null && desktopCaptureTasks.TryDequeue(out task)) { turbojpegCLI.SubsamplingOption subsamp = GetSubsamplingOptionFromImgFlags(task.imgFlags); FragmentedImage img = CaptureRawDesktopImage(task.imgFlags.HasFlag(ImgFlags.Refresh)); SharedMemoryStream sm = static_sm; if (sm == null) { break; } lock (sm) { img.WriteToDataStream(static_sm, ref compressToBuffer, task.jpegQuality, subsamp); } } } } catch (ThreadAbortException) { } catch (StreamDisconnectedException ex) { Logger.Info("Exiting because: " + ex.Message); } catch (Exception ex) { Logger.Debug(ex); Logger.Info("Exiting due to main thread runner exception"); } finally { Try.Catch(() => { dxgiDuplicator?.Dispose(); }); Try.Catch(() => { screenCapturer?.Dispose(); }); //Try.Catch(() => { inputEmulator?.Dispose(); }); RobustExit(); } }
public void WriteToDataStream(IDataStream s, ref byte[] compressToBuffer, int jpegQuality = 80, turbojpegCLI.SubsamplingOption subsamp = turbojpegCLI.SubsamplingOption.SAMP_420) { if (movedFragments.Length > 65535) { throw new Exception("FragmentedImage has too many movedFragments: " + movedFragments.Length); } if (dirtyFragments.Length > 65535) { throw new Exception("FragmentedImage has too many dirtyFragments: " + dirtyFragments.Length); } s.WriteByte((byte)Command.GetScreenCapture); // Write command code s.WriteByte(streamId); // Write stream ID // Calculate buffer sizes s.WriteUInt16((ushort)movedFragments.Length); // Write number of fragments s.WriteUInt16((ushort)dirtyFragments.Length); // Write number of fragments if (movedFragments.Length == 0 && dirtyFragments.Length == 0) { return; } foreach (MovedImageFragment moveFrag in movedFragments) { moveFrag.WriteToDataStream(s); } if (dirtyFragments.Length > 0) { if (dirtyFragments[0].screenshot.BufferIsCompressed) { foreach (DirtyImageFragment dirtyFrag in dirtyFragments) { dirtyFrag.WriteToDataStream(s, null, ref compressToBuffer); } } else { using (turbojpegCLI.TJCompressor compressor = new turbojpegCLI.TJCompressor()) { compressor.setSubsamp(subsamp); compressor.setJPEGQuality(jpegQuality); int requiredBufferSize = 0; foreach (DirtyImageFragment dirtyFrag in dirtyFragments) { int thisBufferSize = turbojpegCLI.TJ.bufSize(dirtyFrag.screenshot.Width, dirtyFrag.screenshot.Height, subsamp); requiredBufferSize = Math.Max(requiredBufferSize, thisBufferSize); } if (compressToBuffer == null || compressToBuffer.Length < requiredBufferSize) { compressToBuffer = new byte[requiredBufferSize]; } foreach (DirtyImageFragment dirtyFrag in dirtyFragments) { dirtyFrag.WriteToDataStream(s, compressor, ref compressToBuffer); } } } } }