Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
2d40a7ffde |
@ -22,14 +22,12 @@ public final class Device {
|
|||||||
|
|
||||||
private final ServiceManager serviceManager = new ServiceManager();
|
private final ServiceManager serviceManager = new ServiceManager();
|
||||||
|
|
||||||
private final int lockedVideoOrientation;
|
|
||||||
private ScreenInfo screenInfo;
|
private ScreenInfo screenInfo;
|
||||||
private RotationListener rotationListener;
|
private RotationListener rotationListener;
|
||||||
|
|
||||||
public Device(Options options) {
|
public Device(Options options) {
|
||||||
lockedVideoOrientation = options.getLockedVideoOrientation();
|
|
||||||
DisplayInfo displayInfo = serviceManager.getDisplayManager().getDisplayInfo();
|
DisplayInfo displayInfo = serviceManager.getDisplayManager().getDisplayInfo();
|
||||||
screenInfo = ScreenInfo.computeScreenInfo(displayInfo, options.getCrop(), options.getMaxSize());
|
screenInfo = ScreenInfo.computeScreenInfo(displayInfo, options.getCrop(), options.getMaxSize(), options.getLockedVideoOrientation());
|
||||||
registerRotationWatcher(new IRotationWatcher.Stub() {
|
registerRotationWatcher(new IRotationWatcher.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void onRotationChanged(int rotation) throws RemoteException {
|
public void onRotationChanged(int rotation) throws RemoteException {
|
||||||
@ -49,55 +47,28 @@ public final class Device {
|
|||||||
return screenInfo;
|
return screenInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the rotation to apply to the device rotation to get the requested locked video orientation
|
|
||||||
*
|
|
||||||
* @param deviceRotation the device rotation
|
|
||||||
* @return the rotation offset
|
|
||||||
*/
|
|
||||||
public int getVideoRotation(int deviceRotation) {
|
|
||||||
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
|
|
||||||
*
|
|
||||||
* @param deviceRotation the device rotation
|
|
||||||
* @return the (reverse) rotation offset
|
|
||||||
*/
|
|
||||||
private int getReverseVideoRotation(int deviceRotation) {
|
|
||||||
if (lockedVideoOrientation == -1) {
|
|
||||||
// no offset
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return (lockedVideoOrientation + 4 - deviceRotation) % 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Point getPhysicalPoint(Position position) {
|
public Point getPhysicalPoint(Position position) {
|
||||||
// it hides the field on purpose, to read it with a lock
|
// it hides the field on purpose, to read it with a lock
|
||||||
@SuppressWarnings("checkstyle:HiddenField")
|
@SuppressWarnings("checkstyle:HiddenField")
|
||||||
ScreenInfo screenInfo = getScreenInfo(); // read with synchronization
|
ScreenInfo screenInfo = getScreenInfo(); // read with synchronization
|
||||||
Size videoSize = screenInfo.getVideoSize();
|
|
||||||
|
|
||||||
int deviceRotation = screenInfo.getDeviceRotation();
|
// ignore the locked video orientation, the events will apply in coordinates considered in the physical device orientation
|
||||||
int reverseVideoRotation = getReverseVideoRotation(deviceRotation);
|
Size unlockedVideoSize = screenInfo.getUnlockedVideoSize();
|
||||||
|
|
||||||
|
int reverseVideoRotation = screenInfo.getReverseVideoRotation();
|
||||||
// reverse the video rotation to apply the events
|
// reverse the video rotation to apply the events
|
||||||
Position devicePosition = position.rotate(reverseVideoRotation);
|
Position devicePosition = position.rotate(reverseVideoRotation);
|
||||||
|
|
||||||
Size clientVideoSize = devicePosition.getScreenSize();
|
Size clientVideoSize = devicePosition.getScreenSize();
|
||||||
if (!videoSize.equals(clientVideoSize)) {
|
if (!unlockedVideoSize.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;
|
||||||
}
|
}
|
||||||
Rect contentRect = screenInfo.getContentRect();
|
Rect contentRect = screenInfo.getContentRect();
|
||||||
Point point = devicePosition.getPoint();
|
Point point = devicePosition.getPoint();
|
||||||
int convertedX = contentRect.left + point.getX() * contentRect.width() / videoSize.getWidth();
|
int convertedX = contentRect.left + point.getX() * contentRect.width() / unlockedVideoSize.getWidth();
|
||||||
int convertedY = contentRect.top + point.getY() * contentRect.height() / videoSize.getHeight();
|
int convertedY = contentRect.top + point.getY() * contentRect.height() / unlockedVideoSize.getHeight();
|
||||||
return new Point(convertedX, convertedY);
|
return new Point(convertedX, convertedY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,12 +66,15 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||||||
IBinder display = createDisplay();
|
IBinder display = createDisplay();
|
||||||
ScreenInfo screenInfo = device.getScreenInfo();
|
ScreenInfo screenInfo = device.getScreenInfo();
|
||||||
Rect contentRect = screenInfo.getContentRect();
|
Rect contentRect = screenInfo.getContentRect();
|
||||||
|
/// include the locked video orientation
|
||||||
Rect videoRect = screenInfo.getVideoSize().toRect();
|
Rect videoRect = screenInfo.getVideoSize().toRect();
|
||||||
int videoRotation = device.getVideoRotation(screenInfo.getDeviceRotation());
|
// does not include the locked video orientation
|
||||||
setSize(format, videoRotation, videoRect.width(), videoRect.height());
|
Rect unlockedVideoRect = screenInfo.getUnlockedVideoSize().toRect();
|
||||||
|
int videoRotation = screenInfo.getVideoRotation();
|
||||||
|
setSize(format, videoRect.width(), videoRect.height());
|
||||||
configure(codec, format);
|
configure(codec, format);
|
||||||
Surface surface = codec.createInputSurface();
|
Surface surface = codec.createInputSurface();
|
||||||
setDisplaySurface(display, surface, videoRotation, contentRect, videoRect);
|
setDisplaySurface(display, surface, videoRotation, contentRect, unlockedVideoRect);
|
||||||
codec.start();
|
codec.start();
|
||||||
try {
|
try {
|
||||||
alive = encode(codec, fd);
|
alive = encode(codec, fd);
|
||||||
@ -170,14 +173,9 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||||||
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
|
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setSize(MediaFormat format, int orientation, int width, int height) {
|
private static void setSize(MediaFormat format, int width, int height) {
|
||||||
if (orientation % 2 == 0) {
|
format.setInteger(MediaFormat.KEY_WIDTH, width);
|
||||||
format.setInteger(MediaFormat.KEY_WIDTH, width);
|
format.setInteger(MediaFormat.KEY_HEIGHT, height);
|
||||||
format.setInteger(MediaFormat.KEY_HEIGHT, height);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
format.setInteger(MediaFormat.KEY_WIDTH, height);
|
|
||||||
format.setInteger(MediaFormat.KEY_HEIGHT, width);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setDisplaySurface(IBinder display, Surface surface, int orientation, Rect deviceRect, Rect displayRect) {
|
private static void setDisplaySurface(IBinder display, Surface surface, int orientation, Rect deviceRect, Rect displayRect) {
|
||||||
|
@ -9,27 +9,53 @@ public final class ScreenInfo {
|
|||||||
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
|
* 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 videoSize;
|
private final Size unlockedVideoSize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Device rotation, related to the natural device orientation (0, 1, 2 or 3)
|
* Device rotation, related to the natural device orientation (0, 1, 2 or 3)
|
||||||
*/
|
*/
|
||||||
private final int deviceRotation;
|
private final int deviceRotation;
|
||||||
|
|
||||||
public ScreenInfo(Rect contentRect, Size videoSize, 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.contentRect = contentRect;
|
||||||
this.videoSize = videoSize;
|
this.unlockedVideoSize = unlockedVideoSize;
|
||||||
this.deviceRotation = deviceRotation;
|
this.deviceRotation = deviceRotation;
|
||||||
|
this.lockedVideoOrientation = lockedVideoOrientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rect getContentRect() {
|
public Rect getContentRect() {
|
||||||
return contentRect;
|
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() {
|
public Size getVideoSize() {
|
||||||
return videoSize;
|
if (getVideoRotation() % 2 == 0) {
|
||||||
|
return unlockedVideoSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return unlockedVideoSize.rotate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDeviceRotation() {
|
public int getDeviceRotation() {
|
||||||
@ -43,18 +69,18 @@ public final class ScreenInfo {
|
|||||||
// true if changed between portrait and landscape
|
// true if changed between portrait and landscape
|
||||||
boolean orientationChanged = (deviceRotation + newDeviceRotation) % 2 != 0;
|
boolean orientationChanged = (deviceRotation + newDeviceRotation) % 2 != 0;
|
||||||
Rect newContentRect;
|
Rect newContentRect;
|
||||||
Size newVideoSize;
|
Size newUnlockedVideoSize;
|
||||||
if (orientationChanged) {
|
if (orientationChanged) {
|
||||||
newContentRect = flipRect(contentRect);
|
newContentRect = flipRect(contentRect);
|
||||||
newVideoSize = videoSize.rotate();
|
newUnlockedVideoSize = unlockedVideoSize.rotate();
|
||||||
} else {
|
} else {
|
||||||
newContentRect = contentRect;
|
newContentRect = contentRect;
|
||||||
newVideoSize = videoSize;
|
newUnlockedVideoSize = unlockedVideoSize;
|
||||||
}
|
}
|
||||||
return new ScreenInfo(newContentRect, newVideoSize, newDeviceRotation);
|
return new ScreenInfo(newContentRect, newUnlockedVideoSize, newDeviceRotation, lockedVideoOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ScreenInfo computeScreenInfo(DisplayInfo displayInfo, Rect crop, int maxSize) {
|
public static ScreenInfo computeScreenInfo(DisplayInfo displayInfo, Rect crop, int maxSize, int lockedVideoOrientation) {
|
||||||
int rotation = displayInfo.getRotation();
|
int rotation = displayInfo.getRotation();
|
||||||
Size deviceSize = displayInfo.getSize();
|
Size deviceSize = displayInfo.getSize();
|
||||||
Rect contentRect = new Rect(0, 0, deviceSize.getWidth(), deviceSize.getHeight());
|
Rect contentRect = new Rect(0, 0, deviceSize.getWidth(), deviceSize.getHeight());
|
||||||
@ -71,7 +97,7 @@ public final class ScreenInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Size videoSize = computeVideoSize(contentRect.width(), contentRect.height(), maxSize);
|
Size videoSize = computeVideoSize(contentRect.width(), contentRect.height(), maxSize);
|
||||||
return new ScreenInfo(contentRect, videoSize, rotation);
|
return new ScreenInfo(contentRect, videoSize, rotation, lockedVideoOrientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formatCrop(Rect rect) {
|
private static String formatCrop(Rect rect) {
|
||||||
@ -109,4 +135,30 @@ public final class ScreenInfo {
|
|||||||
private static Rect flipRect(Rect crop) {
|
private static Rect flipRect(Rect crop) {
|
||||||
return new Rect(crop.top, crop.left, crop.bottom, crop.right);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user