Skip to content

Commit

Permalink
Add capture prepare() step
Browse files Browse the repository at this point in the history
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 <#5370>
  • Loading branch information
rom1v committed Oct 28, 2024
1 parent 5851b62 commit b60e174
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 64 deletions.
58 changes: 18 additions & 40 deletions server/src/main/java/com/genymobile/scrcpy/video/ScreenCapture.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -46,27 +45,11 @@ public ScreenCapture(Device device, int displayId, int maxSize, Rect crop, int l
}

@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();
}
};
Expand All @@ -91,27 +74,26 @@ public void onDisplayFoldChanged(int displayId, boolean folded) {
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
Expand Down Expand Up @@ -139,6 +121,7 @@ public void start(Surface surface) {
// 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");
Expand All @@ -148,6 +131,8 @@ public void start(Surface surface) {
throw new AssertionError("Could not create display");
}
}

device.setScreenInfo(screenInfo);
}

@Override
Expand All @@ -169,15 +154,13 @@ public void release() {
}

@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;
}

Expand All @@ -199,9 +182,4 @@ private static void setDisplaySurface(IBinder display, Surface surface, int orie
SurfaceControl.closeTransaction();
}
}

private void setScreenInfo(ScreenInfo si) {
screenInfo = si;
device.setScreenInfo(si);
}
}
22 changes: 0 additions & 22 deletions server/src/main/java/com/genymobile/scrcpy/video/ScreenInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,6 @@ public Size getVideoSize() {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,22 @@ public boolean consumeReset() {
}

/**
* 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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ private void streamCapture() throws IOException, ConfigurationException {
boolean headerWritten = false;

do {
capture.prepare();
Size size = capture.getSize();
if (!headerWritten) {
streamer.writeVideoHeader(size);
Expand Down

0 comments on commit b60e174

Please sign in to comment.