27
27
import java .util .concurrent .Executors ;
28
28
import java .util .concurrent .atomic .AtomicBoolean ;
29
29
import me .brandonli .mcav .media .image .StaticImage ;
30
+ import me .brandonli .mcav .media .player .PlayerException ;
30
31
import me .brandonli .mcav .media .player .metadata .VideoMetadata ;
31
32
import me .brandonli .mcav .media .player .pipeline .step .VideoPipelineStep ;
32
33
import me .brandonli .mcav .media .source .VNCSource ;
@@ -49,18 +50,16 @@ public class VNCPlayerImpl implements VNCPlayer {
49
50
private final AtomicBoolean running ;
50
51
private final Object lock = new Object ();
51
52
52
- private boolean connected ;
53
- private volatile BufferedImage current ;
54
53
private @ Nullable CompletableFuture <?> processingFuture ;
55
54
private @ Nullable VernacularClient vncClient ;
56
55
57
- private VideoPipelineStep videoPipeline ;
58
- private VideoMetadata videoMetadata ;
56
+ private volatile BufferedImage current ;
57
+ private volatile VideoPipelineStep videoPipeline ;
58
+ private volatile VideoMetadata videoMetadata ;
59
59
60
60
VNCPlayerImpl () {
61
61
this .frameProcessorExecutor = Executors .newFixedThreadPool (Runtime .getRuntime ().availableProcessors ());
62
62
this .running = new AtomicBoolean (false );
63
- this .connected = false ;
64
63
}
65
64
66
65
/**
@@ -69,7 +68,7 @@ public class VNCPlayerImpl implements VNCPlayer {
69
68
@ Override
70
69
public boolean start (final VideoPipelineStep videoPipeline , final VNCSource source ) {
71
70
synchronized (this .lock ) {
72
- if (this .connected ) {
71
+ if (this .running . get () ) {
73
72
return true ;
74
73
}
75
74
this .videoPipeline = videoPipeline ;
@@ -79,7 +78,6 @@ public boolean start(final VideoPipelineStep videoPipeline, final VNCSource sour
79
78
this .vncClient = new VernacularClient (config );
80
79
this .vncClient .start (source .getHost (), source .getPort ());
81
80
82
- this .connected = true ;
83
81
this .running .set (true );
84
82
85
83
this .processingFuture = CompletableFuture .runAsync (this ::processFrames , this .frameProcessorExecutor );
@@ -139,7 +137,7 @@ private void processFrames() {
139
137
@ Override
140
138
public boolean pause () {
141
139
synchronized (this .lock ) {
142
- if (this .connected && this . running .get ()) {
140
+ if (this .running .get ()) {
143
141
this .running .set (false );
144
142
return true ;
145
143
}
@@ -153,7 +151,7 @@ public boolean pause() {
153
151
@ Override
154
152
public boolean resume () {
155
153
synchronized (this .lock ) {
156
- if (this . connected && !this .running .get ()) {
154
+ if (!this .running .get ()) {
157
155
this .running .set (true );
158
156
if (this .processingFuture == null || this .processingFuture .isDone ()) {
159
157
this .processingFuture = CompletableFuture .runAsync (this ::processFrames , this .frameProcessorExecutor );
@@ -171,23 +169,15 @@ public boolean resume() {
171
169
public boolean release () {
172
170
synchronized (this .lock ) {
173
171
this .running .set (false );
174
-
175
- if (this .connected ) {
176
- if (this .processingFuture != null ) {
177
- this .processingFuture .cancel (true );
178
- this .processingFuture = null ;
179
- }
180
-
181
- if (this .vncClient != null ) {
182
- this .vncClient .stop ();
183
- this .vncClient = null ;
184
- }
185
-
186
- this .connected = false ;
172
+ if (this .processingFuture != null ) {
173
+ this .processingFuture .cancel (true );
174
+ this .processingFuture = null ;
175
+ }
176
+ if (this .vncClient != null ) {
177
+ this .vncClient .stop ();
178
+ this .vncClient = null ;
187
179
}
188
-
189
180
ExecutorUtils .shutdownExecutorGracefully (this .frameProcessorExecutor );
190
-
191
181
return true ;
192
182
}
193
183
}
@@ -197,9 +187,24 @@ public boolean release() {
197
187
*/
198
188
@ Override
199
189
public void moveMouse (final int x , final int y ) {
200
- if (this .vncClient != null ) {
201
- this .vncClient .moveMouse (x , y );
190
+ final VernacularClient client = this .vncClient ;
191
+ if (client != null ) {
192
+ final int [] translated = this .translateCoordinates (x , y );
193
+ client .moveMouse (translated [0 ], translated [1 ]);
194
+ }
195
+ }
196
+
197
+ private int [] translateCoordinates (final int x , final int y ) {
198
+ final int originWidth = this .videoMetadata .getVideoWidth ();
199
+ final int originHeight = this .videoMetadata .getVideoHeight ();
200
+ if (this .current == null ) {
201
+ throw new PlayerException ("VNC source not started!" );
202
202
}
203
+ final int targetWidth = this .current .getWidth ();
204
+ final int targetHeight = this .current .getHeight ();
205
+ final int newX = (int ) (((float ) x / originWidth ) * targetWidth );
206
+ final int newY = (int ) (((float ) y / originHeight ) * targetHeight );
207
+ return new int [] { newX , newY };
203
208
}
204
209
205
210
/**
0 commit comments