Compute all screen info from ScreenInfo
Screen information was partially initialized from Device. Move this initialization to ScreenInfo.
This commit is contained in:
parent
da18c9cdab
commit
63286424bb
2 changed files with 70 additions and 59 deletions
|
@ -28,7 +28,8 @@ public final class Device {
|
||||||
|
|
||||||
public Device(Options options) {
|
public Device(Options options) {
|
||||||
lockedVideoOrientation = options.getLockedVideoOrientation();
|
lockedVideoOrientation = options.getLockedVideoOrientation();
|
||||||
screenInfo = computeScreenInfo(options.getCrop(), options.getMaxSize());
|
DisplayInfo displayInfo = serviceManager.getDisplayManager().getDisplayInfo();
|
||||||
|
screenInfo = ScreenInfo.computeScreenInfo(displayInfo, options.getCrop(), options.getMaxSize());
|
||||||
registerRotationWatcher(new IRotationWatcher.Stub() {
|
registerRotationWatcher(new IRotationWatcher.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void onRotationChanged(int rotation) throws RemoteException {
|
public void onRotationChanged(int rotation) throws RemoteException {
|
||||||
|
@ -48,59 +49,6 @@ public final class Device {
|
||||||
return screenInfo;
|
return screenInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScreenInfo computeScreenInfo(Rect crop, int maxSize) {
|
|
||||||
DisplayInfo displayInfo = serviceManager.getDisplayManager().getDisplayInfo();
|
|
||||||
int rotation = displayInfo.getRotation();
|
|
||||||
Size deviceSize = displayInfo.getSize();
|
|
||||||
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 = computeVideoSize(contentRect.width(), contentRect.height(), maxSize);
|
|
||||||
return new ScreenInfo(contentRect, videoSize, rotation);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String formatCrop(Rect rect) {
|
|
||||||
return rect.width() + ":" + rect.height() + ":" + rect.left + ":" + rect.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("checkstyle:MagicNumber")
|
|
||||||
private static Size computeVideoSize(int w, int h, int maxSize) {
|
|
||||||
// Compute the video size and the padding of the content inside this video.
|
|
||||||
// Principle:
|
|
||||||
// - scale down the great side of the screen to maxSize (if necessary);
|
|
||||||
// - scale down the other side so that the aspect ratio is preserved;
|
|
||||||
// - round this value to the nearest multiple of 8 (H.264 only accepts multiples of 8)
|
|
||||||
w &= ~7; // in case it's not a multiple of 8
|
|
||||||
h &= ~7;
|
|
||||||
if (maxSize > 0) {
|
|
||||||
if (BuildConfig.DEBUG && maxSize % 8 != 0) {
|
|
||||||
throw new AssertionError("Max size must be a multiple of 8");
|
|
||||||
}
|
|
||||||
boolean portrait = h > w;
|
|
||||||
int major = portrait ? h : w;
|
|
||||||
int minor = portrait ? w : h;
|
|
||||||
if (major > maxSize) {
|
|
||||||
int minorExact = minor * maxSize / major;
|
|
||||||
// +4 to round the value to the nearest multiple of 8
|
|
||||||
minor = (minorExact + 4) & ~7;
|
|
||||||
major = maxSize;
|
|
||||||
}
|
|
||||||
w = portrait ? minor : major;
|
|
||||||
h = portrait ? major : minor;
|
|
||||||
}
|
|
||||||
return new Size(w, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the rotation to apply to the device rotation to get the requested locked video orientation
|
* Return the rotation to apply to the device rotation to get the requested locked video orientation
|
||||||
*
|
*
|
||||||
|
@ -227,8 +175,4 @@ public final class Device {
|
||||||
wm.thawRotation();
|
wm.thawRotation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Rect flipRect(Rect crop) {
|
|
||||||
return new Rect(crop.top, crop.left, crop.bottom, crop.right);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,19 @@ package com.genymobile.scrcpy;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
|
||||||
public final class ScreenInfo {
|
public final class ScreenInfo {
|
||||||
|
/**
|
||||||
|
* Device (physical) size, possibly cropped
|
||||||
|
*/
|
||||||
private final Rect contentRect; // device 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
|
||||||
|
*/
|
||||||
private final Size videoSize;
|
private final Size videoSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device rotation, related to the natural device orientation (0, 1, 2 or 3)
|
||||||
|
*/
|
||||||
private final int rotation;
|
private final int rotation;
|
||||||
|
|
||||||
public ScreenInfo(Rect contentRect, Size videoSize, int rotation) {
|
public ScreenInfo(Rect contentRect, Size videoSize, int rotation) {
|
||||||
|
@ -34,7 +45,7 @@ public final class ScreenInfo {
|
||||||
Rect newContentRect;
|
Rect newContentRect;
|
||||||
Size newVideoSize;
|
Size newVideoSize;
|
||||||
if (orientationChanged) {
|
if (orientationChanged) {
|
||||||
newContentRect = Device.flipRect(contentRect);
|
newContentRect = flipRect(contentRect);
|
||||||
newVideoSize = videoSize.rotate();
|
newVideoSize = videoSize.rotate();
|
||||||
} else {
|
} else {
|
||||||
newContentRect = contentRect;
|
newContentRect = contentRect;
|
||||||
|
@ -42,4 +53,60 @@ public final class ScreenInfo {
|
||||||
}
|
}
|
||||||
return new ScreenInfo(newContentRect, newVideoSize, newRotation);
|
return new ScreenInfo(newContentRect, newVideoSize, newRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ScreenInfo computeScreenInfo(DisplayInfo displayInfo, Rect crop, int maxSize) {
|
||||||
|
int rotation = displayInfo.getRotation();
|
||||||
|
Size deviceSize = displayInfo.getSize();
|
||||||
|
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 = computeVideoSize(contentRect.width(), contentRect.height(), maxSize);
|
||||||
|
return new ScreenInfo(contentRect, videoSize, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String formatCrop(Rect rect) {
|
||||||
|
return rect.width() + ":" + rect.height() + ":" + rect.left + ":" + rect.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("checkstyle:MagicNumber")
|
||||||
|
private static Size computeVideoSize(int w, int h, int maxSize) {
|
||||||
|
// Compute the video size and the padding of the content inside this video.
|
||||||
|
// Principle:
|
||||||
|
// - scale down the great side of the screen to maxSize (if necessary);
|
||||||
|
// - scale down the other side so that the aspect ratio is preserved;
|
||||||
|
// - round this value to the nearest multiple of 8 (H.264 only accepts multiples of 8)
|
||||||
|
w &= ~7; // in case it's not a multiple of 8
|
||||||
|
h &= ~7;
|
||||||
|
if (maxSize > 0) {
|
||||||
|
if (BuildConfig.DEBUG && maxSize % 8 != 0) {
|
||||||
|
throw new AssertionError("Max size must be a multiple of 8");
|
||||||
|
}
|
||||||
|
boolean portrait = h > w;
|
||||||
|
int major = portrait ? h : w;
|
||||||
|
int minor = portrait ? w : h;
|
||||||
|
if (major > maxSize) {
|
||||||
|
int minorExact = minor * maxSize / major;
|
||||||
|
// +4 to round the value to the nearest multiple of 8
|
||||||
|
minor = (minorExact + 4) & ~7;
|
||||||
|
major = maxSize;
|
||||||
|
}
|
||||||
|
w = portrait ? minor : major;
|
||||||
|
h = portrait ? major : minor;
|
||||||
|
}
|
||||||
|
return new Size(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Rect flipRect(Rect crop) {
|
||||||
|
return new Rect(crop.top, crop.left, crop.bottom, crop.right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue