mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-04-20 19:45:00 +00:00
Added layerstack option
This commit is contained in:
parent
31bd95022b
commit
792fd0e07b
8 changed files with 50 additions and 7 deletions
|
@ -41,6 +41,10 @@ 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"
|
||||
" Default is 0\n"
|
||||
"\n"
|
||||
" --max-fps value\n"
|
||||
" Limit the frame rate of screen capture (only supported on\n"
|
||||
" devices with Android >= 10).\n"
|
||||
|
@ -259,6 +263,18 @@ parse_max_fps(const char *s, uint16_t *max_fps) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_layer_stack(const char *s, uint16_t *layer_stack) {
|
||||
long value;
|
||||
bool ok = parse_integer_arg(s, &value, false, 0, 1000, "layer stack");
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*layer_stack = (uint16_t) value;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_window_position(const char *s, int16_t *position) {
|
||||
long value;
|
||||
|
@ -340,6 +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
|
||||
|
||||
bool
|
||||
scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) {
|
||||
|
@ -350,6 +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},
|
||||
{"max-size", required_argument, NULL, 'm'},
|
||||
{"no-control", no_argument, NULL, 'n'},
|
||||
{"no-display", no_argument, NULL, 'N'},
|
||||
|
@ -412,6 +430,11 @@ 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)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
if (!parse_max_size(optarg, &opts->max_size)) {
|
||||
return false;
|
||||
|
|
|
@ -285,6 +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,
|
||||
};
|
||||
if (!server_start(&server, options->serial, ¶ms)) {
|
||||
return false;
|
||||
|
|
|
@ -32,6 +32,7 @@ struct scrcpy_options {
|
|||
bool render_expired_frames;
|
||||
bool prefer_text;
|
||||
bool window_borderless;
|
||||
uint16_t layer_stack;
|
||||
};
|
||||
|
||||
#define SCRCPY_OPTIONS_DEFAULT { \
|
||||
|
@ -58,6 +59,7 @@ struct scrcpy_options {
|
|||
.render_expired_frames = false, \
|
||||
.prefer_text = false, \
|
||||
.window_borderless = false, \
|
||||
.layer_stack = 0, \
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -124,9 +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];
|
||||
|
||||
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);
|
||||
const char *const cmd[] = {
|
||||
"shell",
|
||||
"CLASSPATH=" DEVICE_SERVER_PATH,
|
||||
|
@ -146,6 +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
|
||||
};
|
||||
#ifdef SERVER_DEBUGGER
|
||||
LOGI("Server debugger waiting for a client on device port "
|
||||
|
|
|
@ -37,6 +37,7 @@ struct server_params {
|
|||
uint32_t bit_rate;
|
||||
uint16_t max_fps;
|
||||
bool control;
|
||||
uint16_t layer_stack;
|
||||
};
|
||||
|
||||
// init default values
|
||||
|
|
|
@ -10,6 +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;
|
||||
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
|
@ -66,4 +67,12 @@ public class Options {
|
|||
public void setControl(boolean control) {
|
||||
this.control = control;
|
||||
}
|
||||
|
||||
public int getLayerStack() {
|
||||
return layerStack;
|
||||
}
|
||||
|
||||
public void setLayerStack(int layerStack) {
|
||||
this.layerStack = layerStack;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
return rotationChanged.getAndSet(false);
|
||||
}
|
||||
|
||||
public void streamScreen(Device device, FileDescriptor fd) throws IOException {
|
||||
public void streamScreen(Device device, FileDescriptor fd, int layerStack) throws IOException {
|
||||
Workarounds.prepareMainLooper();
|
||||
Workarounds.fillAppInfo();
|
||||
|
||||
|
@ -67,7 +67,7 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
setSize(format, videoRect.width(), videoRect.height());
|
||||
configure(codec, format);
|
||||
Surface surface = codec.createInputSurface();
|
||||
setDisplaySurface(display, surface, contentRect, videoRect);
|
||||
setDisplaySurface(display, surface, contentRect, videoRect, layerStack);
|
||||
codec.start();
|
||||
try {
|
||||
alive = encode(codec, fd);
|
||||
|
@ -172,12 +172,12 @@ public class ScreenEncoder implements Device.RotationListener {
|
|||
format.setInteger(MediaFormat.KEY_HEIGHT, height);
|
||||
}
|
||||
|
||||
private static void setDisplaySurface(IBinder display, Surface surface, Rect deviceRect, Rect displayRect) {
|
||||
private static void setDisplaySurface(IBinder display, Surface surface, Rect deviceRect, Rect displayRect, int layerStack) {
|
||||
SurfaceControl.openTransaction();
|
||||
try {
|
||||
SurfaceControl.setDisplaySurface(display, surface);
|
||||
SurfaceControl.setDisplayProjection(display, 0, deviceRect, displayRect);
|
||||
SurfaceControl.setDisplayLayerStack(display, 0);
|
||||
SurfaceControl.setDisplayLayerStack(display, layerStack);
|
||||
} finally {
|
||||
SurfaceControl.closeTransaction();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public final class Server {
|
|||
|
||||
try {
|
||||
// synchronous
|
||||
screenEncoder.streamScreen(device, connection.getVideoFd());
|
||||
screenEncoder.streamScreen(device, connection.getVideoFd(), options.getLayerStack());
|
||||
} catch (IOException e) {
|
||||
// this is expected on close
|
||||
Ln.d("Screen streaming stopped");
|
||||
|
@ -79,8 +79,8 @@ public final class Server {
|
|||
"The server version (" + clientVersion + ") does not match the client " + "(" + BuildConfig.VERSION_NAME + ")");
|
||||
}
|
||||
|
||||
if (args.length != 8) {
|
||||
throw new IllegalArgumentException("Expecting 8 parameters");
|
||||
if (args.length != 9) {
|
||||
throw new IllegalArgumentException("Expecting 9 parameters");
|
||||
}
|
||||
|
||||
Options options = new Options();
|
||||
|
@ -107,6 +107,9 @@ public final class Server {
|
|||
boolean control = Boolean.parseBoolean(args[7]);
|
||||
options.setControl(control);
|
||||
|
||||
int layerStack = Integer.parseInt(args[8]);
|
||||
options.setLayerStack(layerStack);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue