/// <summary> /// Copy the screen, block for up to 2 seconds if nothing changes. /// </summary> void CopyScreen(RemoteEvents request, FrameCollector collector, CollectRequest collectRequest) { if (mOptions.FullThrottle) { // Need the lock to wait for previous throttle (if any) to end mLastScreenHash = 0; // Ask CopyScreen blocking to end early lock (mLockScreenCopy) mLastScreenHash = 0; collector.CopyScreen(); } else { // Block until screen changes or timeout // NOTE: Holding this lock (even without the hash function // in the while loop) incurs a time penalty. This // code is the big bottleneck causing a slow frame // rate. And most of the time is spent in CopyScreen. lock (mLockScreenCopy) { long hash = 0; var screenCopyTimeout = DateTime.Now; while ((DateTime.Now - screenCopyTimeout).TotalMilliseconds < WAIT_FOR_SCREEN_CHANGE_TIMEOUT_MS) { collector.CopyScreen(); using (var bm = new Bitmap32Bits(collector.Screen, System.Drawing.Imaging.ImageLockMode.ReadOnly)) hash = bm.HashLong(0, 0, bm.Width, bm.Height); if (hash != mLastScreenHash) { break; } Thread.Sleep(20); } mLastScreenHash = hash; } } collector.ScaleScreen(mOptions.Width, mOptions.Height); }
void GetFrame(FrameCollector collector, FrameInfo frame) { // Set analyzer options mAnalyzer.FullFrame = mOptions.FullFrame; mAnalyzer.Compression = mOptions.Compression; mAnalyzer.Output = mOptions.Output; // Compress the frame var compressStartTime = DateTime.Now; var frames = mAnalyzer.Compress(collector.Screen); Debug.Assert(frames.Length != 0); var compressTime = DateTime.Now - compressStartTime; // Generate stats Stats stats = new Stats(); stats.CopyTime = (int)collector.CopyTime.TotalMilliseconds; stats.ShrinkTime = (int)collector.ShrinkTime.TotalMilliseconds; stats.CompressTime = (int)compressTime.TotalMilliseconds; stats.Duplicates = mAnalyzer.Duplicates; stats.Collisions = mAnalyzer.HashCollisionsEver; int size = 0; foreach (var compressorFrame in frames) { size += compressorFrame.Draw.Length + compressorFrame.Image.Length; } stats.Size = "" + size / 1000 + "Kb"; // Generate the frame buffer frame.Stats = stats; foreach (var compressorFrame in frames) { frame.Frames.Add(compressorFrame); } }