diff options
Diffstat (limited to 'app/src/main/java/invalid/lena/scrcpy/Session.java')
| -rw-r--r-- | app/src/main/java/invalid/lena/scrcpy/Session.java | 104 |
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(); } } |