-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathRenderLoop.cs
More file actions
117 lines (95 loc) · 4.71 KB
/
RenderLoop.cs
File metadata and controls
117 lines (95 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System;
using System.Linq;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
namespace MotionJpegLatencyTest
{
public class RenderLoop
{
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);
if (message == null)
break;
switch (message["action"].Value<string>())
{
case "MOUSE":
{
var k = message.SelectToken("payload.kind").Value<int>();
var x = message.SelectToken("payload.posX").Value<double>();
var y = message.SelectToken("payload.posY").Value<double>();
Console.WriteLine($"Mouse {k} {x} {y}");
break;
}
case "TICK":
{
var frameId = message.SelectToken("payload.frameId").Value<int>();
var frameTimeMS = message.SelectToken("payload.frameTime").Value<double>();
var circleTimeMs = message.SelectToken("payload.circleTime").Value<double>();
if (frameTimeMS == lastFrameTimeMS)
{
Console.WriteLine($"Error: received same incoming frame twice, {frameTimeMS:0000.00}ms#{frameId} after {lastFrameTimeMS:0000.00}ms#{lastFrameId}");
}
else if (frameTimeMS < lastFrameTimeMS)
{
Console.WriteLine($"Error: received on older incoming frame, {frameTimeMS:0000.00}ms#{frameId} after {lastFrameTimeMS:0000.00}ms#{lastFrameId}");
}
else
{
lastFrameTimeMS = frameTimeMS;
lastFrameId = frameId;
var worker = workers[workerIndex];
if (worker.IsCompleted)
{
var request = new FrameRequest(
frameId,
Duration.FromMilliseconds(frameTimeMS),
Duration.FromMilliseconds(circleTimeMs),
requests[(workerCount + workerIndex - 1) % workerCount]);
worker.PostRequest(request);
requests[workerIndex] = request;
workerIndex = (workerIndex + 1) % workerCount;
}
else
{
Console.WriteLine($"Skipping frame {frameTimeMS:0000.0}!");
}
}
break;
}
}
}
foreach (var worker in workers)
{
worker.Dispose();
}
Console.WriteLine("Exiting RenderLoop");
}
}
}
}