private void streamLoop_inner(object objArgs) { Stopwatch frameTimer = new Stopwatch(); frameTimer.Start(); long nextFrameStart = 0; StreamThreadArgs args = (StreamThreadArgs)objArgs; while (!args.abortFlag.abort) { try { int sleepTime = (int)(nextFrameStart - frameTimer.ElapsedMilliseconds); while (sleepTime > 0 || (Interlocked.Read(ref args.numSentFrames) >= Interlocked.Read(ref args.numAcknowledgedFrames) + maxUnacknowledgedFrames)) { if (args.abortFlag.abort) { return; } Thread.Sleep(BPMath.Clamp(sleepTime, 1, 10)); sleepTime = (int)(nextFrameStart - frameTimer.ElapsedMilliseconds); } if (args.abortFlag.abort) { return; } nextFrameStart = frameTimer.ElapsedMilliseconds + (1000 / maxFPS); if (streamerController == null) { return; } FragmentedImage fragmentedImage = streamerController.GetRawDesktopCapture(imgFlags, jpegQuality, args.abortFlag); if (args.abortFlag.abort) { return; } if (fragmentedImage == null) { fragmentedImage = new FragmentedImage(); } fragmentedImage.streamId = (byte)args.myStreamNumber; using (MemoryDataStream mds = new MemoryDataStream(fragmentedImage.GetMaximumRequiredBufferSize())) { byte[] compressionBuffer = null; fragmentedImage.WriteToDataStream(mds, ref compressionBuffer); Interlocked.Increment(ref args.numSentFrames); Send(mds.ToArray()); } } catch (ThreadAbortException) { throw; } catch (Exception ex) { Logger.Debug(ex); } } }
private void readSharedMemory(object args) { SharedMemoryStream mySm = (SharedMemoryStream)args; try { while (sm == mySm) { try { byte cmdByte = (byte)sm.ReadByte(); Command cmd = (Command)cmdByte; // Handle message from Streamer process. // TODO: Refactor the responses to use a generic wrapper class, e.g. // AsyncLoadingObject<FragmentedImage> newFrame = ...; // newFrame.Loaded(img); // if (newFrame.Wait(abortFlag, out ...)) // return ...; switch (cmd) { case Command.GetScreenCapture: FragmentedImage img = new FragmentedImage(sm); newFrame.Produce(img); break; case Command.GetDesktopInfo: DesktopInfo di = new DesktopInfo(sm); newDesktopInfo.Produce(di); break; case Command.Error_SyntaxError: case Command.Error_CommandCodeUnknown: case Command.Error_Unspecified: case Command.StartStreaming: case Command.StopStreaming: case Command.AcknowledgeFrame: case Command.ReproduceUserInput: case Command.SetStreamSettings: case Command.GetStreamSettings: default: Logger.Info("Received unexpected byte from Streamer process: " + cmd); // TODO: End the Streamer process now and start a new one, because we have just entered an undefined state. break; } } catch (ThreadAbortException) { throw; } catch (StreamDisconnectedException) { throw; } catch (Exception ex) { Logger.Debug(ex); } } } catch (ThreadAbortException) { } catch (StreamDisconnectedException) { Logger.Info("Read Shared Memory thread detected stream close (" + mySm.uniqueId + ")"); } catch (Exception ex) { Logger.Debug(ex); } finally { Try.Catch(() => { mySm?.Dispose(); }); RaiseOnCloseEvent(); } }