From b60e1747809cce58793a8c0d54b499df87a6a975 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sat, 12 Oct 2024 09:23:31 +0200 Subject: [PATCH] Add capture prepare() step Add a function called before each capture starts (before getSize() is called). This allows to compute the ScreenInfo instance once exactly when needed. PR #5370 --- .../scrcpy/video/ScreenCapture.java | 58 ++++++------------- .../genymobile/scrcpy/video/ScreenInfo.java | 22 ------- .../scrcpy/video/SurfaceCapture.java | 11 +++- .../scrcpy/video/SurfaceEncoder.java | 1 + 4 files changed, 28 insertions(+), 64 deletions(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java index 05d349da..f71ff020 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java @@ -26,9 +26,8 @@ public class ScreenCapture extends SurfaceCapture { private int maxSize; private final Rect crop; private final int lockVideoOrientation; - private int layerStack; - private Size deviceSize; + private DisplayInfo displayInfo; private ScreenInfo screenInfo; private IBinder display; @@ -46,27 +45,11 @@ public class ScreenCapture extends SurfaceCapture { } @Override - public void init() throws ConfigurationException { - DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId); - if (displayInfo == null) { - Ln.e("Display " + displayId + " not found\n" + LogUtils.buildDisplayListMessage()); - throw new ConfigurationException("Unknown display id: " + displayId); - } - - deviceSize = displayInfo.getSize(); - ScreenInfo si = ScreenInfo.computeScreenInfo(displayInfo.getRotation(), deviceSize, crop, maxSize, lockVideoOrientation); - setScreenInfo(si); - layerStack = displayInfo.getLayerStack(); - + public void init() { if (displayId == 0) { rotationWatcher = new IRotationWatcher.Stub() { @Override public void onRotationChanged(int rotation) { - synchronized (ScreenCapture.this) { - ScreenInfo si = screenInfo.withDeviceRotation(rotation); - setScreenInfo(si); - } - requestReset(); } }; @@ -91,27 +74,26 @@ public class ScreenCapture extends SurfaceCapture { return; } - synchronized (ScreenCapture.this) { - DisplayInfo displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId); - if (displayInfo == null) { - Ln.e("Display " + displayId + " not found\n" + LogUtils.buildDisplayListMessage()); - return; - } - - deviceSize = displayInfo.getSize(); - ScreenInfo si = ScreenInfo.computeScreenInfo(displayInfo.getRotation(), deviceSize, crop, maxSize, lockVideoOrientation); - setScreenInfo(si); - } - requestReset(); } }; ServiceManager.getWindowManager().registerDisplayFoldListener(displayFoldListener); } + } + + @Override + public void prepare() throws ConfigurationException { + displayInfo = ServiceManager.getDisplayManager().getDisplayInfo(displayId); + if (displayInfo == null) { + Ln.e("Display " + displayId + " not found\n" + LogUtils.buildDisplayListMessage()); + throw new ConfigurationException("Unknown display id: " + displayId); + } if ((displayInfo.getFlags() & DisplayInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) == 0) { Ln.w("Display doesn't have FLAG_SUPPORTS_PROTECTED_BUFFERS flag, mirroring can be restricted"); } + + screenInfo = ScreenInfo.computeScreenInfo(displayInfo.getRotation(), displayInfo.getSize(), crop, maxSize, lockVideoOrientation); } @Override @@ -139,6 +121,7 @@ public class ScreenCapture extends SurfaceCapture { // does not include the locked video orientation Rect unlockedVideoRect = screenInfo.getUnlockedVideoSize().toRect(); int videoRotation = screenInfo.getVideoRotation(); + int layerStack = displayInfo.getLayerStack(); setDisplaySurface(display, surface, videoRotation, contentRect, unlockedVideoRect, layerStack); Ln.d("Display: using SurfaceControl API"); @@ -148,6 +131,8 @@ public class ScreenCapture extends SurfaceCapture { throw new AssertionError("Could not create display"); } } + + device.setScreenInfo(screenInfo); } @Override @@ -169,15 +154,13 @@ public class ScreenCapture extends SurfaceCapture { } @Override - public synchronized Size getSize() { + public Size getSize() { return screenInfo.getVideoSize(); } @Override - public synchronized boolean setMaxSize(int newMaxSize) { + public boolean setMaxSize(int newMaxSize) { maxSize = newMaxSize; - ScreenInfo si = ScreenInfo.computeScreenInfo(screenInfo.getReverseVideoRotation(), deviceSize, crop, newMaxSize, lockVideoOrientation); - setScreenInfo(si); return true; } @@ -199,9 +182,4 @@ public class ScreenCapture extends SurfaceCapture { SurfaceControl.closeTransaction(); } } - - private void setScreenInfo(ScreenInfo si) { - screenInfo = si; - device.setScreenInfo(si); - } } diff --git a/server/src/main/java/com/genymobile/scrcpy/video/ScreenInfo.java b/server/src/main/java/com/genymobile/scrcpy/video/ScreenInfo.java index bd0a3b62..1f74ce34 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/ScreenInfo.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/ScreenInfo.java @@ -63,28 +63,6 @@ public final class ScreenInfo { return unlockedVideoSize.rotate(); } - public int getDeviceRotation() { - return deviceRotation; - } - - public ScreenInfo withDeviceRotation(int newDeviceRotation) { - if (newDeviceRotation == deviceRotation) { - return this; - } - // true if changed between portrait and landscape - boolean orientationChanged = (deviceRotation + newDeviceRotation) % 2 != 0; - Rect newContentRect; - Size newUnlockedVideoSize; - if (orientationChanged) { - newContentRect = flipRect(contentRect); - newUnlockedVideoSize = unlockedVideoSize.rotate(); - } else { - newContentRect = contentRect; - newUnlockedVideoSize = unlockedVideoSize; - } - return new ScreenInfo(newContentRect, newUnlockedVideoSize, newDeviceRotation, lockedVideoOrientation); - } - public static ScreenInfo computeScreenInfo(int rotation, Size deviceSize, Rect crop, int maxSize, int lockedVideoOrientation) { if (lockedVideoOrientation == Device.LOCK_VIDEO_ORIENTATION_INITIAL) { // The user requested to lock the video orientation to the current orientation diff --git a/server/src/main/java/com/genymobile/scrcpy/video/SurfaceCapture.java b/server/src/main/java/com/genymobile/scrcpy/video/SurfaceCapture.java index fe679beb..0ee93c92 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/SurfaceCapture.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/SurfaceCapture.java @@ -33,15 +33,22 @@ public abstract class SurfaceCapture { } /** - * Called once before the capture starts. + * Called once before the first capture starts. */ public abstract void init() throws ConfigurationException, IOException; /** - * Called after the capture ends (if and only if {@link #init()} has been called). + * Called after the last capture ends (if and only if {@link #init()} has been called). */ public abstract void release(); + /** + * Called once before each capture starts, before {@link #getSize()}. + */ + public void prepare() throws ConfigurationException { + // empty by default + } + /** * Start the capture to the target surface. * diff --git a/server/src/main/java/com/genymobile/scrcpy/video/SurfaceEncoder.java b/server/src/main/java/com/genymobile/scrcpy/video/SurfaceEncoder.java index 4da1454d..84bda1ce 100644 --- a/server/src/main/java/com/genymobile/scrcpy/video/SurfaceEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/video/SurfaceEncoder.java @@ -72,6 +72,7 @@ public class SurfaceEncoder implements AsyncProcessor { boolean headerWritten = false; do { + capture.prepare(); Size size = capture.getSize(); if (!headerWritten) { streamer.writeVideoHeader(size);