From 64930e71b9636544468646e61dac3d7a4a62896c Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Wed, 25 Oct 2023 00:18:05 +0200 Subject: [PATCH] Handle camera disconnection Stop mirroring on camera disconnection. PR #4213 --- .../java/com/genymobile/scrcpy/CameraCapture.java | 11 ++++++++++- .../java/com/genymobile/scrcpy/SurfaceCapture.java | 9 +++++++++ .../java/com/genymobile/scrcpy/SurfaceEncoder.java | 5 +++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/CameraCapture.java b/server/src/main/java/com/genymobile/scrcpy/CameraCapture.java index 3efd4cb28a..78ad0e09aa 100644 --- a/server/src/main/java/com/genymobile/scrcpy/CameraCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/CameraCapture.java @@ -22,6 +22,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; public class CameraCapture extends SurfaceCapture { @@ -33,6 +34,8 @@ public class CameraCapture extends SurfaceCapture { private CameraDevice cameraDevice; private Executor cameraExecutor; + private final AtomicBoolean disconnected = new AtomicBoolean(); + public CameraCapture(String explicitCameraId, Size explicitSize) { this.explicitCameraId = explicitCameraId; this.explicitSize = explicitSize; @@ -97,7 +100,8 @@ public void onOpened(CameraDevice camera) { @Override public void onDisconnected(CameraDevice camera) { Ln.w("Camera disconnected"); - // TODO + disconnected.set(true); + requestReset(); } @Override @@ -177,4 +181,9 @@ public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request } }, cameraHandler); } + + @Override + public boolean isClosed() { + return disconnected.get(); + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/SurfaceCapture.java b/server/src/main/java/com/genymobile/scrcpy/SurfaceCapture.java index 207cfad8d1..e300e4d65f 100644 --- a/server/src/main/java/com/genymobile/scrcpy/SurfaceCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/SurfaceCapture.java @@ -59,4 +59,13 @@ public boolean consumeReset() { * @param maxSize Maximum size */ public abstract boolean setMaxSize(int maxSize); + + /** + * Indicate if the capture has been closed internally. + * + * @return {@code true} is the capture is closed, {@code false} otherwise. + */ + public boolean isClosed() { + return false; + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/SurfaceEncoder.java b/server/src/main/java/com/genymobile/scrcpy/SurfaceEncoder.java index 9f90115a93..28435c0988 100644 --- a/server/src/main/java/com/genymobile/scrcpy/SurfaceEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/SurfaceEncoder.java @@ -181,6 +181,11 @@ private boolean encode(MediaCodec codec, Streamer streamer) throws IOException { } } + if (capture.isClosed()) { + // The capture might have been closed internally (for example if the camera is disconnected) + alive = false; + } + return !eof && alive; }