From 15bf27afdddc64c2887085e075398f71d2748d06 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Sat, 15 Jan 2022 23:01:14 +0100 Subject: [PATCH] Make auto-downsize on error optional Add --no-downsize-on-error option to disable attempts to use a lower definition on MediaCodec error. PR #2947 --- app/scrcpy.1 | 6 ++++++ app/src/cli.c | 11 +++++++++++ app/src/options.c | 1 + app/src/options.h | 1 + app/src/scrcpy.c | 1 + app/src/server.c | 4 ++++ app/src/server.h | 1 + .../src/main/java/com/genymobile/scrcpy/Options.java | 9 +++++++++ .../java/com/genymobile/scrcpy/ScreenEncoder.java | 10 +++++++++- .../src/main/java/com/genymobile/scrcpy/Server.java | 6 +++++- 10 files changed, 48 insertions(+), 2 deletions(-) diff --git a/app/scrcpy.1 b/app/scrcpy.1 index 4d02982c..37431a91 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -140,6 +140,12 @@ By default, scrcpy automatically synchronizes the computer clipboard to the devi This option disables this automatic synchronization. +.TP +.B \-\-no\-downsize\-on\-error +By default, on MediaCodec error, scrcpy automatically tries again with a lower definition. + +This option disables this behavior. + .TP .B \-n, \-\-no\-control Disable device control (mirror the device in read\-only). diff --git a/app/src/cli.c b/app/src/cli.c index 3fcf94eb..76feb130 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -52,6 +52,7 @@ #define OPT_NO_CLIPBOARD_AUTOSYNC 1032 #define OPT_TCPIP 1033 #define OPT_RAW_KEY_EVENTS 1034 +#define OPT_NO_DOWNSIZE_ON_ERROR 1035 struct sc_option { char shortopt; @@ -236,6 +237,13 @@ static const struct sc_option options[] = { "is preserved.\n" "Default is 0 (unlimited).", }, + { + .longopt_id = OPT_NO_DOWNSIZE_ON_ERROR, + .longopt = "no-downsize-on-error", + .text = "By default, on MediaCodec error, scrcpy automatically tries " + "again with a lower definition.\n" + "This option disables this behavior.", + }, { .longopt_id = OPT_NO_CLIPBOARD_AUTOSYNC, .longopt = "no-clipboard-autosync", @@ -1489,6 +1497,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], opts->tcpip = true; opts->tcpip_dst = optarg; break; + case OPT_NO_DOWNSIZE_ON_ERROR: + opts->downsize_on_error = false; + break; case OPT_V4L2_SINK: #ifdef HAVE_V4L2 opts->v4l2_device = optarg; diff --git a/app/src/options.c b/app/src/options.c index 7a5b71af..b8560406 100644 --- a/app/src/options.c +++ b/app/src/options.c @@ -54,6 +54,7 @@ const struct scrcpy_options scrcpy_options_default = { .legacy_paste = false, .power_off_on_close = false, .clipboard_autosync = true, + .downsize_on_error = true, .tcpip = false, .tcpip_dst = NULL, }; diff --git a/app/src/options.h b/app/src/options.h index b2c69664..99f03d40 100644 --- a/app/src/options.h +++ b/app/src/options.h @@ -129,6 +129,7 @@ struct scrcpy_options { bool legacy_paste; bool power_off_on_close; bool clipboard_autosync; + bool downsize_on_error; bool tcpip; const char *tcpip_dst; }; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 86fdf984..e55fef80 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -364,6 +364,7 @@ scrcpy(struct scrcpy_options *options) { .force_adb_forward = options->force_adb_forward, .power_off_on_close = options->power_off_on_close, .clipboard_autosync = options->clipboard_autosync, + .downsize_on_error = options->downsize_on_error, .tcpip = options->tcpip, .tcpip_dst = options->tcpip_dst, }; diff --git a/app/src/server.c b/app/src/server.c index ea7e5377..b62a74f1 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -234,6 +234,10 @@ execute_server(struct sc_server *server, // By default, clipboard_autosync is true ADD_PARAM("clipboard_autosync=false"); } + if (!params->downsize_on_error) { + // By default, downsize_on_error is true + ADD_PARAM("downsize_on_error=false"); + } #undef ADD_PARAM #undef STRBOOL diff --git a/app/src/server.h b/app/src/server.h index 8ea20dc7..89cdc2f4 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -42,6 +42,7 @@ struct sc_server_params { bool force_adb_forward; bool power_off_on_close; bool clipboard_autosync; + bool downsize_on_error; bool tcpip; const char *tcpip_dst; }; diff --git a/server/src/main/java/com/genymobile/scrcpy/Options.java b/server/src/main/java/com/genymobile/scrcpy/Options.java index 1ac17176..ef7d8572 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Options.java +++ b/server/src/main/java/com/genymobile/scrcpy/Options.java @@ -21,6 +21,7 @@ public class Options { private String encoderName; private boolean powerOffScreenOnClose; private boolean clipboardAutosync = true; + private boolean downsizeOnError = true; public Ln.Level getLogLevel() { return logLevel; @@ -149,4 +150,12 @@ public class Options { public void setClipboardAutosync(boolean clipboardAutosync) { this.clipboardAutosync = clipboardAutosync; } + + public boolean getDownsizeOnError() { + return downsizeOnError; + } + + public void setDownsizeOnError(boolean downsizeOnError) { + this.downsizeOnError = downsizeOnError; + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index ba601a22..10ba9fac 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -38,14 +38,17 @@ public class ScreenEncoder implements Device.RotationListener { private final int bitRate; private final int maxFps; private final boolean sendFrameMeta; + private final boolean downsizeOnError; private long ptsOrigin; - public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, List codecOptions, String encoderName) { + public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, List codecOptions, String encoderName, + boolean downsizeOnError) { this.sendFrameMeta = sendFrameMeta; this.bitRate = bitRate; this.maxFps = maxFps; this.codecOptions = codecOptions; this.encoderName = encoderName; + this.downsizeOnError = downsizeOnError; } @Override @@ -96,6 +99,11 @@ public class ScreenEncoder implements Device.RotationListener { codec.stop(); } catch (Exception e) { Ln.e("Encoding error: " + e.getClass().getName() + ": " + e.getMessage()); + if (!downsizeOnError) { + // Fail immediately + throw e; + } + int newMaxSize = chooseMaxSizeFallback(screenInfo.getVideoSize()); if (newMaxSize == 0) { // Definitively fail diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index 4f9575ae..21e3fd92 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -70,7 +70,7 @@ public final class Server { try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward, control)) { ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps(), codecOptions, - options.getEncoderName()); + options.getEncoderName(), options.getDownsizeOnError()); Thread controllerThread = null; Thread deviceMessageSenderThread = null; @@ -237,6 +237,10 @@ public final class Server { boolean clipboardAutosync = Boolean.parseBoolean(value); options.setClipboardAutosync(clipboardAutosync); break; + case "downsize_on_error": + boolean downsizeOnError = Boolean.parseBoolean(value); + options.setDownsizeOnError(downsizeOnError); + break; default: Ln.w("Unknown server option: " + key); break;