Make PositionMapper use affine transforms

This will allow applying transformations performed by video filters.

PR #5455 <https://github.com/Genymobile/scrcpy/pull/5455>
This commit is contained in:
Romain Vimont 2024-11-10 13:47:14 +01:00
parent 623c7a5cbb
commit 412dadc6e5
3 changed files with 14 additions and 9 deletions

View File

@ -3,15 +3,16 @@ 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.util.AffineMatrix;
public final class PositionMapper { public final class PositionMapper {
private final Size sourceSize;
private final Size videoSize; private final Size videoSize;
private final AffineMatrix videoToDeviceMatrix;
public PositionMapper(Size sourceSize, Size videoSize) { public PositionMapper(Size videoSize, AffineMatrix videoToDeviceMatrix) {
this.sourceSize = sourceSize;
this.videoSize = videoSize; this.videoSize = videoSize;
this.videoToDeviceMatrix = videoToDeviceMatrix;
} }
public Point map(Position position) { public Point map(Position position) {
@ -23,8 +24,9 @@ public final class PositionMapper {
} }
Point point = position.getPoint(); Point point = position.getPoint();
int convertedX = point.getX() * sourceSize.getWidth() / videoSize.getWidth(); if (videoToDeviceMatrix != null) {
int convertedY = point.getY() * sourceSize.getHeight() / videoSize.getHeight(); point = videoToDeviceMatrix.apply(point);
return new Point(convertedX, convertedY); }
return point;
} }
} }

View File

@ -106,7 +106,7 @@ public class NewDisplayCapture extends SurfaceCapture {
} }
if (vdListener != null) { if (vdListener != null) {
PositionMapper positionMapper = new PositionMapper(size, size); PositionMapper positionMapper = new PositionMapper(size, null);
vdListener.onNewVirtualDisplay(virtualDisplayId, positionMapper); vdListener.onNewVirtualDisplay(virtualDisplayId, positionMapper);
} }
} }

View File

@ -7,6 +7,7 @@ import com.genymobile.scrcpy.device.ConfigurationException;
import com.genymobile.scrcpy.device.Device; import com.genymobile.scrcpy.device.Device;
import com.genymobile.scrcpy.device.DisplayInfo; import com.genymobile.scrcpy.device.DisplayInfo;
import com.genymobile.scrcpy.device.Size; import com.genymobile.scrcpy.device.Size;
import com.genymobile.scrcpy.util.AffineMatrix;
import com.genymobile.scrcpy.util.Ln; import com.genymobile.scrcpy.util.Ln;
import com.genymobile.scrcpy.util.LogUtils; import com.genymobile.scrcpy.util.LogUtils;
import com.genymobile.scrcpy.wrappers.DisplayManager; import com.genymobile.scrcpy.wrappers.DisplayManager;
@ -145,7 +146,7 @@ public class ScreenCapture extends SurfaceCapture {
.createVirtualDisplay("scrcpy", videoSize.getWidth(), videoSize.getHeight(), displayId, surface); .createVirtualDisplay("scrcpy", videoSize.getWidth(), videoSize.getHeight(), displayId, surface);
virtualDisplayId = virtualDisplay.getDisplay().getDisplayId(); virtualDisplayId = virtualDisplay.getDisplay().getDisplayId();
// 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, videoSize); positionMapper = new PositionMapper(videoSize, null);
Ln.d("Display: using DisplayManager API"); Ln.d("Display: using DisplayManager API");
} catch (Exception displayManagerException) { } catch (Exception displayManagerException) {
try { try {
@ -156,7 +157,9 @@ public class ScreenCapture extends SurfaceCapture {
setDisplaySurface(display, surface, deviceSize.toRect(), videoSize.toRect(), layerStack); setDisplaySurface(display, surface, deviceSize.toRect(), videoSize.toRect(), layerStack);
virtualDisplayId = displayId; virtualDisplayId = displayId;
positionMapper = new PositionMapper(deviceSize, videoSize);
AffineMatrix videoToDeviceMatrix = videoSize.equals(deviceSize) ? null : AffineMatrix.scale(videoSize, deviceSize);
positionMapper = new PositionMapper(videoSize, videoToDeviceMatrix);
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);