Skip to content

Commit 24eb298

Browse files
committed
Remove AutoQuality and simplify caster throttling.
1 parent 849a4b7 commit 24eb298

32 files changed

+44
-217
lines changed

Desktop.Core/Services/DtoMessageHandler.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,6 @@ public async Task ParseMessage(Viewer viewer, byte[] message)
9191
case BaseDtoType.CtrlAltDel:
9292
await viewer.SendCtrlAltDel();
9393
break;
94-
case BaseDtoType.ToggleAutoQuality:
95-
ToggleAutoQuality(message, viewer);
96-
break;
9794
case BaseDtoType.ToggleAudio:
9895
ToggleAudio(message);
9996
break;
@@ -264,11 +261,6 @@ private void ToggleAudio(byte[] message)
264261
var dto = MessagePackSerializer.Deserialize<ToggleAudioDto>(message);
265262
AudioCapturer.ToggleAudio(dto.ToggleOn);
266263
}
267-
private void ToggleAutoQuality(byte[] message, Viewer viewer)
268-
{
269-
var dto = MessagePackSerializer.Deserialize<ToggleAutoQualityDto>(message);
270-
viewer.AutoQuality = dto.ToggleOn;
271-
}
272264

273265
private void ToggleBlockInput(byte[] message)
274266
{

Desktop.Core/Services/ScreenCaster.cs

Lines changed: 16 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ public class ScreenCaster : IScreenCaster
2121
{
2222
private readonly Conductor _conductor;
2323
private readonly ICursorIconWatcher _cursorIconWatcher;
24-
private readonly int _maxQuality = 75;
25-
private readonly int _minQuality = 10;
2624
private readonly ISessionIndicator _sessionIndicator;
2725
private readonly IShutdownService _shutdownService;
2826

@@ -42,13 +40,8 @@ public async Task BeginScreenCasting(ScreenCastRequest screenCastRequest)
4240
{
4341
try
4442
{
45-
var sendFramesLock = new SemaphoreSlim(1, 1);
46-
var refreshTimer = Stopwatch.StartNew();
47-
var refreshNeeded = false;
48-
var currentQuality = _maxQuality;
4943
Bitmap currentFrame = null;
5044
Bitmap previousFrame = null;
51-
var sw = Stopwatch.StartNew();
5245

5346
var viewer = ServiceContainer.Instance.GetRequiredService<Viewer>();
5447
viewer.Name = screenCastRequest.RequesterName;
@@ -96,7 +89,7 @@ await viewer.SendScreenData(
9689
{
9790
await viewer.SendScreenCapture(new CaptureFrame()
9891
{
99-
EncodedImageBytes = ImageUtils.EncodeJpeg(initialFrame, _maxQuality),
92+
EncodedImageBytes = ImageUtils.EncodeJpeg(initialFrame),
10093
Left = screenBounds.Left,
10194
Top = screenBounds.Top,
10295
Width = screenBounds.Width,
@@ -118,9 +111,6 @@ await viewer.SendScreenCapture(new CaptureFrame()
118111
{
119112
try
120113
{
121-
TaskHelper.DelayUntil(() => sw.Elapsed.TotalMilliseconds > 40, TimeSpan.FromSeconds(5));
122-
sw.Restart();
123-
124114
if (viewer.IsUsingWebRtcVideo)
125115
{
126116
Thread.Sleep(100);
@@ -149,62 +139,19 @@ await viewer.SendScreenCapture(new CaptureFrame()
149139
continue;
150140
}
151141

152-
if (refreshNeeded && refreshTimer.Elapsed.TotalSeconds > 5)
153-
{
154-
viewer.Capturer.CaptureFullscreen = true;
155-
}
156-
157-
158142
var diffArea = ImageUtils.GetDiffArea(currentFrame, previousFrame, viewer.Capturer.CaptureFullscreen);
159143

160144
if (diffArea.IsEmpty)
161145
{
162146
continue;
163147
}
164148

165-
166-
if (viewer.Capturer.CaptureFullscreen)
167-
{
168-
refreshTimer.Restart();
169-
refreshNeeded = false;
170-
}
171-
172-
byte[] encodedImageBytes;
173-
if (viewer.Capturer.CaptureFullscreen)
174-
{
175-
// Recalculate Bps.
176-
viewer.AverageBytesPerSecond = 0;
177-
encodedImageBytes = ImageUtils.EncodeJpeg(currentFrame, _maxQuality);
178-
}
179-
else
180-
{
181-
if (!viewer.AutoQuality)
182-
{
183-
currentQuality = _maxQuality;
184-
}
185-
else if (viewer.AverageBytesPerSecond > 0)
186-
{
187-
var expectedSize = diffArea.Height * diffArea.Width * 4 * .1;
188-
var timeToSend = expectedSize / viewer.AverageBytesPerSecond;
189-
currentQuality = Math.Max(_minQuality, Math.Min(_maxQuality, (int)(.1 / timeToSend * _maxQuality)));
190-
if (currentQuality < _maxQuality - 5)
191-
{
192-
refreshNeeded = true;
193-
Debug.WriteLine($"Quality Reduced: {currentQuality}");
194-
}
195-
}
196-
197-
using var clone = currentFrame.Clone(diffArea, currentFrame.PixelFormat);
198-
//var resizeW = diffArea.Width * currentQuality / _maxQuality;
199-
//var resizeH = diffArea.Height * currentQuality / _maxQuality;
200-
//using var resized = new Bitmap(clone, new Size(resizeW, resizeH));
201-
encodedImageBytes = ImageUtils.EncodeJpeg(clone, currentQuality);
202-
}
203-
204149
viewer.Capturer.CaptureFullscreen = false;
205150

206-
await sendFramesLock.WaitAsync();
207-
SendFrame(encodedImageBytes, diffArea, viewer, sendFramesLock);
151+
using var croppedFrame = currentFrame.Clone(diffArea, currentFrame.PixelFormat);
152+
var encodedImageBytes = ImageUtils.EncodeJpeg(croppedFrame);
153+
await SendFrame(encodedImageBytes, diffArea, viewer);
154+
208155
}
209156
catch (Exception ex)
210157
{
@@ -237,32 +184,20 @@ await viewer.SendScreenCapture(new CaptureFrame()
237184
}
238185
}
239186

240-
private static void SendFrame(byte[] encodedImageBytes, Rectangle diffArea, Viewer viewer, SemaphoreSlim sendFramesLock)
187+
private static async Task SendFrame(byte[] encodedImageBytes, Rectangle diffArea, Viewer viewer)
241188
{
242-
_ = Task.Run(async () =>
189+
if (encodedImageBytes.Length == 0)
243190
{
244-
try
245-
{
246-
247-
if (encodedImageBytes.Length == 0)
248-
{
249-
return;
250-
}
251-
252-
await viewer.SendScreenCapture(new CaptureFrame()
253-
{
254-
EncodedImageBytes = encodedImageBytes,
255-
Top = diffArea.Top,
256-
Left = diffArea.Left,
257-
Width = diffArea.Width,
258-
Height = diffArea.Height,
259-
});
191+
return;
192+
}
260193

261-
}
262-
finally
263-
{
264-
sendFramesLock.Release();
265-
}
194+
await viewer.SendScreenCapture(new CaptureFrame()
195+
{
196+
EncodedImageBytes = encodedImageBytes,
197+
Top = diffArea.Top,
198+
Left = diffArea.Left,
199+
Width = diffArea.Width,
200+
Height = diffArea.Height,
266201
});
267202
}
268203
}

Desktop.Core/Services/Viewer.cs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ namespace Remotely.Desktop.Core.Services
1919
{
2020
public class Viewer : IDisposable
2121
{
22-
private long _bytesSent;
23-
private TimeSpan _timeSpentSending = TimeSpan.Zero;
24-
2522
public Viewer(ICasterSocket casterSocket,
2623
IScreenCapturer screenCapturer,
2724
IClipboardService clipboardService,
@@ -42,7 +39,6 @@ public Viewer(ICasterSocket casterSocket,
4239
public bool DisconnectRequested { get; set; }
4340
public EncoderParameters EncoderParams { get; private set; }
4441
public bool HasControl { get; set; } = true;
45-
public bool AutoQuality { get; set; } = true;
4642
public bool IsConnected => CasterSocket.IsConnected;
4743

4844
public bool IsStalled
@@ -71,7 +67,6 @@ public bool IsUsingWebRtcVideo
7167

7268
public string Name { get; set; }
7369

74-
public double AverageBytesPerSecond { get; set; }
7570
public ConcurrentQueue<SentFrame> PendingSentFrames { get; } = new();
7671

7772
public WebRtcSession RtcSession { get; set; }
@@ -228,8 +223,6 @@ public async Task SendScreenCapture(CaptureFrame screenFrame)
228223
var width = screenFrame.Width;
229224
var height = screenFrame.Height;
230225

231-
var sw = Stopwatch.StartNew();
232-
233226
for (var i = 0; i < screenFrame.EncodedImageBytes.Length; i += 50_000)
234227
{
235228
var dto = new CaptureFrameDto()
@@ -260,16 +253,6 @@ await SendToViewer(() => RtcSession.SendDto(dto),
260253
await SendToViewer(
261254
() => RtcSession.SendDto(endOfFrameDto),
262255
() => CasterSocket.SendDtoToViewer(endOfFrameDto, ViewerConnectionID));
263-
264-
sw.Stop();
265-
266-
_bytesSent += screenFrame.EncodedImageBytes.Length;
267-
_timeSpentSending += sw.Elapsed;
268-
269-
270-
AverageBytesPerSecond = _bytesSent / _timeSpentSending.TotalSeconds;
271-
272-
Debug.WriteLine($"Mbps: {AverageBytesPerSecond / 1024 / 1024 * 8}");
273256
}
274257

275258
public async Task SendScreenData(string selectedScreen, string[] displayNames)
@@ -302,9 +285,15 @@ await SendToViewer(() => RtcSession.SendDto(dto),
302285

303286
public void ThrottleIfNeeded()
304287
{
288+
// Limit to 20 FPS.
289+
TaskHelper.DelayUntil(() =>
290+
!PendingSentFrames.TryPeek(out var result) || DateTimeOffset.Now - result.Timestamp > TimeSpan.FromMilliseconds(50),
291+
TimeSpan.FromSeconds(5));
292+
293+
// Wait for pending frames to be received.
305294
TaskHelper.DelayUntil(() =>
306295
!PendingSentFrames.TryPeek(out var result) || DateTimeOffset.Now - result.Timestamp < TimeSpan.FromSeconds(1),
307-
TimeSpan.FromSeconds(10));
296+
TimeSpan.FromSeconds(5));
308297
}
309298

310299
public void ToggleWebRtcVideo(bool toggleOn)

Desktop.Core/Utilities/ImageUtils.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ public class ImageUtils
2929
// return ms.ToArray();
3030
//}
3131

32+
public static byte[] EncodeJpeg(Bitmap bitmap)
33+
{
34+
using var ms = new MemoryStream();
35+
bitmap.Save(ms, ImageFormat.Jpeg);
36+
return ms.ToArray();
37+
}
38+
3239
public static byte[] EncodeJpeg(Bitmap bitmap, int quality)
3340
{
3441
using var ms = new MemoryStream();

Server/Pages/RemoteControl.cshtml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,6 @@
132132
</div>
133133

134134
<div>
135-
<button id="autoQualityButton" class="toggled option-button" title="Automatically reduce image quality on slower connections.">
136-
Auto Quality <i class="fas fa-image"></i>
137-
</button>
138-
139135
<button id="streamVideoButton" class="option-button" hidden title="Reduce bandwidth and increase FPS, but increase input delay.">
140136
Stream Mode <i class="fas fa-video"></i>
141137
</button>

Server/wwwroot/src/RemoteControl/App.js

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Server/wwwroot/src/RemoteControl/App.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Server/wwwroot/src/RemoteControl/App.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ export const ViewerApp = {
3737

3838
ApplyInputHandlers();
3939

40-
UI.UpdateAutoQualityToggled(ViewerApp.Settings.autoQuality);
41-
4240
if (UI.RequesterNameInput.value) {
4341
ViewerApp.RequesterName = UI.RequesterNameInput.value;
4442
}

Server/wwwroot/src/RemoteControl/DtoMessageHandler.js

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)