aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/invalid/lena/scrcpy/Session.java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/invalid/lena/scrcpy/Session.java')
-rw-r--r--app/src/main/java/invalid/lena/scrcpy/Session.java104
1 files changed, 63 insertions, 41 deletions
diff --git a/app/src/main/java/invalid/lena/scrcpy/Session.java b/app/src/main/java/invalid/lena/scrcpy/Session.java
index 774fdc1..947930b 100644
--- a/app/src/main/java/invalid/lena/scrcpy/Session.java
+++ b/app/src/main/java/invalid/lena/scrcpy/Session.java
@@ -238,48 +238,67 @@ public final class Session {
}
Log.i("adb connect ok");
- Server srv = new Server(ctx, adb);
- Server.Streams s = srv.bringUp();
-
- ControlStream cs = new ControlStream(s.controlIn, s.controlOut);
- Controller ctrl = new Controller(ctx, cs::send);
- cs.setInboundSink(ctrl);
-
- AudioSink ak = new AudioSink();
- AudioStream as = new AudioStream(s.audioIn, ak);
-
- VideoSink vk = new VideoSink(surface);
- final Controller ctrlRef = ctrl; // capture for SizeListener
- AtomicBoolean reported = new AtomicBoolean();
- VideoStream vs = new VideoStream(s.videoIn, vk, (w, h) -> {
- ctrlRef.setTargetSize(w, h);
- if (reported.compareAndSet(false, true) && listener != null) {
- listener.onConnected(w, h);
- }
- });
- vs.setOnEnd(this::onVideoEnded);
- MuxRecorder rec = new MuxRecorder();
- vs.setRecorder(rec);
+ Server srv = null;
+ ControlStream cs = null;
+ Controller ctrl = null;
+ AudioSink ak = null;
+ AudioStream as = null;
+ VideoSink vk = null;
+ VideoStream vs = null;
+ MuxRecorder rec = null;
+ boolean installed = false;
+ try {
+ srv = new Server(ctx, adb);
+ Server.Streams s = srv.bringUp();
+
+ cs = new ControlStream(s.controlIn, s.controlOut, this::onVideoEnded);
+ ctrl = new Controller(ctx, cs::send);
+ cs.setInboundSink(ctrl);
+
+ ak = new AudioSink(this::onVideoEnded);
+ as = new AudioStream(s.audioIn, ak);
+
+ vk = new VideoSink(surface, this::onVideoEnded);
+ Controller ctrlRef = ctrl;
+ AtomicBoolean reported = new AtomicBoolean();
+ vs = new VideoStream(s.videoIn, vk,
+ (w, h) -> reportConnected(ctrlRef, reported, w, h));
+ vs.setOnEnd(this::onVideoEnded);
+ rec = new MuxRecorder();
+ vs.setRecorder(rec);
+
+ // Start locals before publishing them. stop() either tears down
+ // a previously installed generation or marks this generation for
+ // rollback; it can never release objects that bringUp then starts.
+ cs.start();
+ as.start();
+ vs.start();
- synchronized (this) {
- if (stopped) {
- tearDownLocals(srv, cs, ctrl, ak, as, vk, vs, rec);
- throw new IOException("session: stopped during bring-up");
+ synchronized (this) {
+ if (stopped) throw new IOException("session: stopped during bring-up");
+ server = srv;
+ controlStream = cs;
+ controller = ctrl;
+ audioSink = ak;
+ audioStream = as;
+ videoSink = vk;
+ videoStream = vs;
+ recorder = rec;
+ if (pendingViewW > 0) ctrl.setViewSize(pendingViewW, pendingViewH);
+ installed = true;
}
- server = srv;
- controlStream = cs;
- controller = ctrl;
- audioSink = ak;
- audioStream = as;
- videoSink = vk;
- videoStream = vs;
- recorder = rec;
- if (pendingViewW > 0) ctrl.setViewSize(pendingViewW, pendingViewH);
+ } finally {
+ if (!installed) tearDownLocals(srv, cs, ctrl, ak, as, vk, vs, rec);
}
+ }
- cs.start();
- as.start();
- vs.start();
+ private synchronized void reportConnected(Controller ctrl, AtomicBoolean reported,
+ int w, int h) {
+ if (stopped) return;
+ ctrl.setTargetSize(w, h);
+ if (reported.compareAndSet(false, true) && listener != null) {
+ listener.onConnected(w, h);
+ }
}
// Fired on the video-reader thread when its read loop exits (EOF,
@@ -308,12 +327,15 @@ public final class Session {
AudioSink ak, AudioStream as,
VideoSink vk, VideoStream vs, MuxRecorder rec) {
if (rec != null) rec.close();
+ // Closing the owning ADB streams first unblocks readers. Join them
+ // before releasing their sinks so no callback can recreate resources
+ // after teardown.
+ if (srv != null) srv.close();
if (vs != null) vs.stop();
- if (vk != null) vk.release();
if (as != null) as.stop();
- if (ak != null) ak.release();
if (cs != null) cs.stop();
+ if (vk != null) vk.release();
+ if (ak != null) ak.release();
if (ctrl != null) ctrl.release();
- if (srv != null) srv.close();
}
}