mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-04-20 19:45:00 +00:00
Replace layout stack option with better device id option.
This allows the correct geometry to be grabbed and the layout stack to be derived from the display info itself.
This commit is contained in:
parent
792fd0e07b
commit
4afca06635
12 changed files with 58 additions and 34 deletions
|
@ -41,8 +41,8 @@ scrcpy_print_usage(const char *arg0) {
|
|||
" -h, --help\n"
|
||||
" Print this help.\n"
|
||||
"\n"
|
||||
" --layer-stack value\n"
|
||||
" Specifies the Android layer stack to mirror\n"
|
||||
" --display-id value\n"
|
||||
" Specifies the Android display to mirror\n"
|
||||
" Default is 0\n"
|
||||
"\n"
|
||||
" --max-fps value\n"
|
||||
|
@ -264,14 +264,14 @@ parse_max_fps(const char *s, uint16_t *max_fps) {
|
|||
}
|
||||
|
||||
static bool
|
||||
parse_layer_stack(const char *s, uint16_t *layer_stack) {
|
||||
parse_display_id(const char *s, uint16_t *display_id) {
|
||||
long value;
|
||||
bool ok = parse_integer_arg(s, &value, false, 0, 1000, "layer stack");
|
||||
bool ok = parse_integer_arg(s, &value, false, 0, 1000, "display id");
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*layer_stack = (uint16_t) value;
|
||||
*display_id = (uint16_t) value;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -356,7 +356,7 @@ guess_record_format(const char *filename) {
|
|||
#define OPT_WINDOW_HEIGHT 1010
|
||||
#define OPT_WINDOW_BORDERLESS 1011
|
||||
#define OPT_MAX_FPS 1012
|
||||
#define OPT_LAYER_STACK 1013
|
||||
#define OPT_DISPLAY_ID 1013
|
||||
|
||||
bool
|
||||
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||
|
@ -367,7 +367,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
|||
{"fullscreen", no_argument, NULL, 'f'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"max-fps", required_argument, NULL, OPT_MAX_FPS},
|
||||
{"layer-stack", required_argument, NULL, OPT_LAYER_STACK},
|
||||
{"display-id", required_argument, NULL, OPT_DISPLAY_ID},
|
||||
{"max-size", required_argument, NULL, 'm'},
|
||||
{"no-control", no_argument, NULL, 'n'},
|
||||
{"no-display", no_argument, NULL, 'N'},
|
||||
|
@ -430,8 +430,8 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
case OPT_LAYER_STACK:
|
||||
if (!parse_layer_stack(optarg, &opts->layer_stack)) {
|
||||
case OPT_DISPLAY_ID:
|
||||
if (!parse_display_id(optarg, &opts->display_id)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -285,7 +285,7 @@ scrcpy(const struct scrcpy_options *options) {
|
|||
.bit_rate = options->bit_rate,
|
||||
.max_fps = options->max_fps,
|
||||
.control = options->control,
|
||||
.layer_stack = options->layer_stack,
|
||||
.display_id = options->display_id,
|
||||
};
|
||||
if (!server_start(&server, options->serial, ¶ms)) {
|
||||
return false;
|
||||
|
|
|
@ -32,7 +32,7 @@ struct scrcpy_options {
|
|||
bool render_expired_frames;
|
||||
bool prefer_text;
|
||||
bool window_borderless;
|
||||
uint16_t layer_stack;
|
||||
uint16_t display_id;
|
||||
};
|
||||
|
||||
#define SCRCPY_OPTIONS_DEFAULT { \
|
||||
|
@ -59,7 +59,7 @@ struct scrcpy_options {
|
|||
.render_expired_frames = false, \
|
||||
.prefer_text = false, \
|
||||
.window_borderless = false, \
|
||||
.layer_stack = 0, \
|
||||
.display_id = 0, \
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -124,12 +124,12 @@ execute_server(struct server *server, const struct server_params *params) {
|
|||
char max_size_string[6];
|
||||
char bit_rate_string[11];
|
||||
char max_fps_string[6];
|
||||
char layer_stack_string[6];
|
||||
char display_id_string[6];
|
||||
|
||||
sprintf(max_size_string, "%"PRIu16, params->max_size);
|
||||
sprintf(bit_rate_string, "%"PRIu32, params->bit_rate);
|
||||
sprintf(max_fps_string, "%"PRIu16, params->max_fps);
|
||||
sprintf(layer_stack_string, "%"PRIu16, params->layer_stack);
|
||||
sprintf(display_id_string, "%"PRIu16, params->display_id);
|
||||
const char *const cmd[] = {
|
||||
"shell",
|
||||
"CLASSPATH=" DEVICE_SERVER_PATH,
|
||||
|
@ -149,7 +149,7 @@ execute_server(struct server *server, const struct server_params *params) {
|
|||
params->crop ? params->crop : "-",
|
||||
"true", // always send frame meta (packet boundaries + timestamp)
|
||||
params->control ? "true" : "false",
|
||||
layer_stack_string
|
||||
display_id_string
|
||||
};
|
||||
#ifdef SERVER_DEBUGGER
|
||||
LOGI("Server debugger waiting for a client on device port "
|
||||
|
|
|
@ -37,7 +37,7 @@ struct server_params {
|
|||
uint32_t bit_rate;
|
||||
uint16_t max_fps;
|
||||
bool control;
|
||||
uint16_t layer_stack;
|
||||
uint16_t display_id;
|
||||
};
|
||||
|
||||
// init default values
|
||||
|
|
|
@ -26,7 +26,7 @@ public final class Device {
|
|||
private RotationListener rotationListener;
|
||||
|
||||
public Device(Options options) {
|
||||
screenInfo = computeScreenInfo(options.getCrop(), options.getMaxSize());
|
||||
screenInfo = computeScreenInfo(options.getDisplayId(), options.getCrop(), options.getMaxSize());
|
||||
registerRotationWatcher(new IRotationWatcher.Stub() {
|
||||
@Override
|
||||
public void onRotationChanged(int rotation) throws RemoteException {
|
||||
|
@ -46,8 +46,8 @@ public final class Device {
|
|||
return screenInfo;
|
||||
}
|
||||
|
||||
private ScreenInfo computeScreenInfo(Rect crop, int maxSize) {
|
||||
DisplayInfo displayInfo = serviceManager.getDisplayManager().getDisplayInfo();
|
||||
private ScreenInfo computeScreenInfo(int displayId, Rect crop, int maxSize) {
|
||||
DisplayInfo displayInfo = serviceManager.getDisplayManager().getDisplayInfo(displayId);
|
||||
boolean rotated = (displayInfo.getRotation() & 1) != 0;
|
||||
Size deviceSize = displayInfo.getSize();
|
||||
Rect contentRect = new Rect(0, 0, deviceSize.getWidth(), deviceSize.getHeight());
|
||||
|
@ -64,7 +64,7 @@ public final class Device {
|
|||
}
|
||||
|
||||
Size videoSize = computeVideoSize(contentRect.width(), contentRect.height(), maxSize);
|
||||
return new ScreenInfo(contentRect, videoSize, rotated);
|
||||
return new ScreenInfo(contentRect, videoSize, rotated, displayInfo.getLayerStack());
|
||||
}
|
||||
|
||||
private static String formatCrop(Rect rect) {
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
package com.genymobile.scrcpy;
|
||||
|
||||
public final class DisplayInfo {
|
||||
private final int displayId;
|
||||
private final Size size;
|
||||
private final int rotation;
|
||||
private final int layerStack;
|
||||
|
||||
public DisplayInfo(Size size, int rotation) {
|
||||
public DisplayInfo(int displayId, Size size, int rotation, int layerStack) {
|
||||
this.displayId = displayId;
|
||||
this.size = size;
|
||||
this.rotation = rotation;
|
||||
this.layerStack = layerStack;
|
||||
}
|
||||
|
||||
public int getDisplayId() {
|
||||
return displayId;
|
||||
}
|
||||
|
||||
public Size getSize() {
|
||||
|
@ -16,5 +24,9 @@ public final class DisplayInfo {
|
|||
public int getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
public int getLayerStack() {
|
||||
return layerStack;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ public class Options {
|
|||
private Rect crop;
|
||||
private boolean sendFrameMeta; // send PTS so that the client may record properly
|
||||
private boolean control;
|
||||
private int layerStack;
|
||||
private int displayId;
|
||||
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
|
@ -68,11 +68,11 @@ public class Options {
|
|||
this.control = control;
|
||||
}
|
||||
|
||||
public int getLayerStack() {
|
||||
return layerStack;
|
||||
public int getDisplayId() {
|
||||
return displayId;
|
||||
}
|
||||
|
||||
public void setLayerStack(int layerStack) {
|
||||
this.layerStack = layerStack;
|
||||
public void setDisplayId(int displayId) {
|
||||
this.displayId = displayId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
return rotationChanged.getAndSet(false);
|
||||
}
|
||||
|
||||
public void streamScreen(Device device, FileDescriptor fd, int layerStack) throws IOException {
|
||||
public void streamScreen(Device device, FileDescriptor fd) throws IOException {
|
||||
Workarounds.prepareMainLooper();
|
||||
Workarounds.fillAppInfo();
|
||||
|
||||
|
@ -64,6 +64,7 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
IBinder display = createDisplay();
|
||||
Rect contentRect = device.getScreenInfo().getContentRect();
|
||||
Rect videoRect = device.getScreenInfo().getVideoSize().toRect();
|
||||
int layerStack = device.getScreenInfo().getLayerStack();
|
||||
setSize(format, videoRect.width(), videoRect.height());
|
||||
configure(codec, format);
|
||||
Surface surface = codec.createInputSurface();
|
||||
|
|
|
@ -6,11 +6,13 @@ public final class ScreenInfo {
|
|||
private final Rect contentRect; // device size, possibly cropped
|
||||
private final Size videoSize;
|
||||
private final boolean rotated;
|
||||
private final int layerStack;
|
||||
|
||||
public ScreenInfo(Rect contentRect, Size videoSize, boolean rotated) {
|
||||
public ScreenInfo(Rect contentRect, Size videoSize, boolean rotated, int layerStack) {
|
||||
this.contentRect = contentRect;
|
||||
this.videoSize = videoSize;
|
||||
this.rotated = rotated;
|
||||
this.layerStack = layerStack;
|
||||
}
|
||||
|
||||
public Rect getContentRect() {
|
||||
|
@ -21,11 +23,15 @@ public final class ScreenInfo {
|
|||
return videoSize;
|
||||
}
|
||||
|
||||
public int getLayerStack() {
|
||||
return layerStack;
|
||||
}
|
||||
|
||||
public ScreenInfo withRotation(int rotation) {
|
||||
boolean newRotated = (rotation & 1) != 0;
|
||||
if (rotated == newRotated) {
|
||||
return this;
|
||||
}
|
||||
return new ScreenInfo(Device.flipRect(contentRect), videoSize.rotate(), newRotated);
|
||||
return new ScreenInfo(Device.flipRect(contentRect), videoSize.rotate(), newRotated, layerStack);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public final class Server {
|
|||
|
||||
try {
|
||||
// synchronous
|
||||
screenEncoder.streamScreen(device, connection.getVideoFd(), options.getLayerStack());
|
||||
screenEncoder.streamScreen(device, connection.getVideoFd());
|
||||
} catch (IOException e) {
|
||||
// this is expected on close
|
||||
Ln.d("Screen streaming stopped");
|
||||
|
@ -107,8 +107,8 @@ public final class Server {
|
|||
boolean control = Boolean.parseBoolean(args[7]);
|
||||
options.setControl(control);
|
||||
|
||||
int layerStack = Integer.parseInt(args[8]);
|
||||
options.setLayerStack(layerStack);
|
||||
int displayId = Integer.parseInt(args[8]);
|
||||
options.setDisplayId(displayId);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
|
|
@ -13,14 +13,19 @@ public final class DisplayManager {
|
|||
}
|
||||
|
||||
public DisplayInfo getDisplayInfo() {
|
||||
return getDisplayInfo(0);
|
||||
}
|
||||
|
||||
public DisplayInfo getDisplayInfo(int displayId) {
|
||||
try {
|
||||
Object displayInfo = manager.getClass().getMethod("getDisplayInfo", int.class).invoke(manager, 0);
|
||||
Object displayInfo = manager.getClass().getMethod("getDisplayInfo", int.class).invoke(manager, displayId);
|
||||
Class<?> cls = displayInfo.getClass();
|
||||
// width and height already take the rotation into account
|
||||
int width = cls.getDeclaredField("logicalWidth").getInt(displayInfo);
|
||||
int height = cls.getDeclaredField("logicalHeight").getInt(displayInfo);
|
||||
int rotation = cls.getDeclaredField("rotation").getInt(displayInfo);
|
||||
return new DisplayInfo(new Size(width, height), rotation);
|
||||
int layerStack = cls.getDeclaredField("layerStack").getInt(displayInfo);
|
||||
return new DisplayInfo(displayId, new Size(width, height), rotation, layerStack);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue