Temporarily ignore lock video orientation and crop

Get rid of old code implementing --lock-video-orientation and --crop
features on the device side.

They will be reimplemented differently.
This commit is contained in:
Romain Vimont 2024-11-10 10:04:01 +01:00
parent 829707057e
commit 18be0b5e28
4 changed files with 19 additions and 169 deletions

View File

@ -3,46 +3,28 @@ package com.genymobile.scrcpy.control;
import com.genymobile.scrcpy.device.Point; import com.genymobile.scrcpy.device.Point;
import com.genymobile.scrcpy.device.Position; import com.genymobile.scrcpy.device.Position;
import com.genymobile.scrcpy.device.Size; import com.genymobile.scrcpy.device.Size;
import com.genymobile.scrcpy.video.ScreenInfo;
import android.graphics.Rect;
public final class PositionMapper { public final class PositionMapper {
private final Size sourceSize;
private final Size videoSize; private final Size videoSize;
private final Rect contentRect;
private final int coordsRotation;
public PositionMapper(Size videoSize, Rect contentRect, int videoRotation) { public PositionMapper(Size sourceSize, Size videoSize) {
this.sourceSize = sourceSize;
this.videoSize = videoSize; this.videoSize = videoSize;
this.contentRect = contentRect;
this.coordsRotation = reverseRotation(videoRotation);
}
public static PositionMapper from(ScreenInfo screenInfo) {
// ignore the locked video orientation, the events will apply in coordinates considered in the physical device orientation
Size videoSize = screenInfo.getUnlockedVideoSize();
return new PositionMapper(videoSize, screenInfo.getContentRect(), screenInfo.getVideoRotation());
}
private static int reverseRotation(int rotation) {
return (4 - rotation) % 4;
} }
public Point map(Position position) { public Point map(Position position) {
// reverse the video rotation to apply the events Size clientVideoSize = position.getScreenSize();
Position devicePosition = position.rotate(coordsRotation);
Size clientVideoSize = devicePosition.getScreenSize();
if (!videoSize.equals(clientVideoSize)) { if (!videoSize.equals(clientVideoSize)) {
// The client sends a click relative to a video with wrong dimensions, // The client sends a click relative to a video with wrong dimensions,
// the device may have been rotated since the event was generated, so ignore the event // the device may have been rotated since the event was generated, so ignore the event
return null; return null;
} }
Point point = devicePosition.getPoint(); Point point = position.getPoint();
int convertedX = contentRect.left + point.getX() * contentRect.width() / videoSize.getWidth(); int convertedX = point.getX() * sourceSize.getWidth() / videoSize.getWidth();
int convertedY = contentRect.top + point.getY() * contentRect.height() / videoSize.getHeight(); int convertedY = point.getY() * sourceSize.getHeight() / videoSize.getHeight();
return new Point(convertedX, convertedY); return new Point(convertedX, convertedY);
} }
} }

View File

@ -9,7 +9,6 @@ import com.genymobile.scrcpy.device.Size;
import com.genymobile.scrcpy.util.Ln; import com.genymobile.scrcpy.util.Ln;
import com.genymobile.scrcpy.wrappers.ServiceManager; import com.genymobile.scrcpy.wrappers.ServiceManager;
import android.graphics.Rect;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay; import android.hardware.display.VirtualDisplay;
import android.os.Build; import android.os.Build;
@ -107,8 +106,7 @@ public class NewDisplayCapture extends SurfaceCapture {
} }
if (vdListener != null) { if (vdListener != null) {
Rect contentRect = new Rect(0, 0, size.getWidth(), size.getHeight()); PositionMapper positionMapper = new PositionMapper(size, size);
PositionMapper positionMapper = new PositionMapper(size, contentRect, 0);
vdListener.onNewVirtualDisplay(virtualDisplayId, positionMapper); vdListener.onNewVirtualDisplay(virtualDisplayId, positionMapper);
} }
} }

View File

@ -28,11 +28,9 @@ public class ScreenCapture extends SurfaceCapture {
private final VirtualDisplayListener vdListener; private final VirtualDisplayListener vdListener;
private final int displayId; private final int displayId;
private int maxSize; private int maxSize;
private final Rect crop;
private final int lockVideoOrientation;
private DisplayInfo displayInfo; private DisplayInfo displayInfo;
private ScreenInfo screenInfo; private Size videoSize;
// Source display size (before resizing/crop) for the current session // Source display size (before resizing/crop) for the current session
private Size sessionDisplaySize; private Size sessionDisplaySize;
@ -55,8 +53,6 @@ public class ScreenCapture extends SurfaceCapture {
this.displayId = options.getDisplayId(); this.displayId = options.getDisplayId();
assert displayId != Device.DISPLAY_ID_NONE; assert displayId != Device.DISPLAY_ID_NONE;
this.maxSize = options.getMaxSize(); this.maxSize = options.getMaxSize();
this.crop = options.getCrop();
this.lockVideoOrientation = options.getLockVideoOrientation();
} }
@Override @Override
@ -126,8 +122,9 @@ public class ScreenCapture extends SurfaceCapture {
Ln.w("Display doesn't have FLAG_SUPPORTS_PROTECTED_BUFFERS flag, mirroring can be restricted"); Ln.w("Display doesn't have FLAG_SUPPORTS_PROTECTED_BUFFERS flag, mirroring can be restricted");
} }
setSessionDisplaySize(displayInfo.getSize()); Size displaySize = displayInfo.getSize();
screenInfo = ScreenInfo.computeScreenInfo(displayInfo.getRotation(), displayInfo.getSize(), crop, maxSize, lockVideoOrientation); setSessionDisplaySize(displaySize);
videoSize = displaySize.limit(maxSize).round8();
} }
@Override @Override
@ -144,28 +141,22 @@ public class ScreenCapture extends SurfaceCapture {
int virtualDisplayId; int virtualDisplayId;
PositionMapper positionMapper; PositionMapper positionMapper;
try { try {
Size videoSize = screenInfo.getVideoSize();
virtualDisplay = ServiceManager.getDisplayManager() virtualDisplay = ServiceManager.getDisplayManager()
.createVirtualDisplay("scrcpy", videoSize.getWidth(), videoSize.getHeight(), displayId, surface); .createVirtualDisplay("scrcpy", videoSize.getWidth(), videoSize.getHeight(), displayId, surface);
virtualDisplayId = virtualDisplay.getDisplay().getDisplayId(); virtualDisplayId = virtualDisplay.getDisplay().getDisplayId();
Rect contentRect = new Rect(0, 0, videoSize.getWidth(), videoSize.getHeight());
// The position are relative to the virtual display, not the original display // The position are relative to the virtual display, not the original display
positionMapper = new PositionMapper(videoSize, contentRect, 0); positionMapper = new PositionMapper(videoSize, videoSize);
Ln.d("Display: using DisplayManager API"); Ln.d("Display: using DisplayManager API");
} catch (Exception displayManagerException) { } catch (Exception displayManagerException) {
try { try {
display = createDisplay(); display = createDisplay();
Rect contentRect = screenInfo.getContentRect(); Size deviceSize = displayInfo.getSize();
// does not include the locked video orientation
Rect unlockedVideoRect = screenInfo.getUnlockedVideoSize().toRect();
int videoRotation = screenInfo.getVideoRotation();
int layerStack = displayInfo.getLayerStack(); int layerStack = displayInfo.getLayerStack();
setDisplaySurface(display, surface, videoRotation, contentRect, unlockedVideoRect, layerStack); setDisplaySurface(display, surface, deviceSize.toRect(), videoSize.toRect(), layerStack);
virtualDisplayId = displayId; virtualDisplayId = displayId;
positionMapper = PositionMapper.from(screenInfo); positionMapper = new PositionMapper(deviceSize, videoSize);
Ln.d("Display: using SurfaceControl API"); Ln.d("Display: using SurfaceControl API");
} catch (Exception surfaceControlException) { } catch (Exception surfaceControlException) {
Ln.e("Could not create display using DisplayManager", displayManagerException); Ln.e("Could not create display using DisplayManager", displayManagerException);
@ -206,7 +197,7 @@ public class ScreenCapture extends SurfaceCapture {
@Override @Override
public Size getSize() { public Size getSize() {
return screenInfo.getVideoSize(); return videoSize;
} }
@Override @Override
@ -223,11 +214,11 @@ public class ScreenCapture extends SurfaceCapture {
return SurfaceControl.createDisplay("scrcpy", secure); return SurfaceControl.createDisplay("scrcpy", secure);
} }
private static void setDisplaySurface(IBinder display, Surface surface, int orientation, Rect deviceRect, Rect displayRect, int layerStack) { private static void setDisplaySurface(IBinder display, Surface surface, Rect deviceRect, Rect displayRect, int layerStack) {
SurfaceControl.openTransaction(); SurfaceControl.openTransaction();
try { try {
SurfaceControl.setDisplaySurface(display, surface); SurfaceControl.setDisplaySurface(display, surface);
SurfaceControl.setDisplayProjection(display, orientation, deviceRect, displayRect); SurfaceControl.setDisplayProjection(display, 0, deviceRect, displayRect);
SurfaceControl.setDisplayLayerStack(display, layerStack); SurfaceControl.setDisplayLayerStack(display, layerStack);
} finally { } finally {
SurfaceControl.closeTransaction(); SurfaceControl.closeTransaction();

View File

@ -1,121 +0,0 @@
package com.genymobile.scrcpy.video;
import com.genymobile.scrcpy.device.Device;
import com.genymobile.scrcpy.device.Size;
import com.genymobile.scrcpy.util.Ln;
import android.graphics.Rect;
public final class ScreenInfo {
/**
* Device (physical) size, possibly cropped
*/
private final Rect contentRect; // device size, possibly cropped
/**
* Video size, possibly smaller than the device size, already taking the device rotation and crop into account.
* <p>
* However, it does not include the locked video orientation.
*/
private final Size unlockedVideoSize;
/**
* Device rotation, related to the natural device orientation (0, 1, 2 or 3)
*/
private final int deviceRotation;
/**
* The locked video orientation (-1: disabled, 0: normal, 1: 90° CCW, 2: 180°, 3: 90° CW)
*/
private final int lockedVideoOrientation;
public ScreenInfo(Rect contentRect, Size unlockedVideoSize, int deviceRotation, int lockedVideoOrientation) {
this.contentRect = contentRect;
this.unlockedVideoSize = unlockedVideoSize;
this.deviceRotation = deviceRotation;
this.lockedVideoOrientation = lockedVideoOrientation;
}
public Rect getContentRect() {
return contentRect;
}
/**
* Return the video size as if locked video orientation was not set.
*
* @return the unlocked video size
*/
public Size getUnlockedVideoSize() {
return unlockedVideoSize;
}
/**
* Return the actual video size if locked video orientation is set.
*
* @return the actual video size
*/
public Size getVideoSize() {
if (getVideoRotation() % 2 == 0) {
return unlockedVideoSize;
}
return unlockedVideoSize.rotate();
}
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
lockedVideoOrientation = rotation;
}
Rect contentRect = new Rect(0, 0, deviceSize.getWidth(), deviceSize.getHeight());
if (crop != null) {
if (rotation % 2 != 0) { // 180s preserve dimensions
// the crop (provided by the user) is expressed in the natural orientation
crop = flipRect(crop);
}
if (!contentRect.intersect(crop)) {
// intersect() changes contentRect so that it is intersected with crop
Ln.w("Crop rectangle (" + formatCrop(crop) + ") does not intersect device screen (" + formatCrop(deviceSize.toRect()) + ")");
contentRect = new Rect(); // empty
}
}
Size videoSize = new Size(contentRect.width(), contentRect.height()).limit(maxSize).round8();
return new ScreenInfo(contentRect, videoSize, rotation, lockedVideoOrientation);
}
private static String formatCrop(Rect rect) {
return rect.width() + ":" + rect.height() + ":" + rect.left + ":" + rect.top;
}
private static Rect flipRect(Rect crop) {
return new Rect(crop.top, crop.left, crop.bottom, crop.right);
}
/**
* Return the rotation to apply to the device rotation to get the requested locked video orientation
*
* @return the rotation offset
*/
public int getVideoRotation() {
if (lockedVideoOrientation == -1) {
// no offset
return 0;
}
return (deviceRotation + 4 - lockedVideoOrientation) % 4;
}
/**
* Return the rotation to apply to the requested locked video orientation to get the device rotation
*
* @return the (reverse) rotation offset
*/
public int getReverseVideoRotation() {
if (lockedVideoOrientation == -1) {
// no offset
return 0;
}
return (lockedVideoOrientation + 4 - deviceRotation) % 4;
}
}