From 1947d6b26ea7593f615f918d12dc775282c87f40 Mon Sep 17 00:00:00 2001 From: Tzah Mazuz Date: Mon, 12 Oct 2020 12:23:06 +0300 Subject: [PATCH] Adding new option --encoder-name --- app/src/cli.c | 10 ++++++++++ app/src/scrcpy.c | 1 + app/src/scrcpy.h | 2 ++ app/src/server.c | 1 + app/src/server.h | 1 + .../main/java/com/genymobile/scrcpy/Options.java | 9 +++++++++ .../java/com/genymobile/scrcpy/ScreenEncoder.java | 13 ++++++++++--- .../src/main/java/com/genymobile/scrcpy/Server.java | 8 ++++++-- 8 files changed, 40 insertions(+), 5 deletions(-) diff --git a/app/src/cli.c b/app/src/cli.c index 41de8ca5..1c1b438a 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -60,6 +60,11 @@ scrcpy_print_usage(const char *arg0) { " -f, --fullscreen\n" " Start in fullscreen.\n" "\n" + " --encoder-name name\n" + " Attempts to create the MediaCodec encoder by its exact name.\n" + " Given encoder must be a h264 format encoder.\n" + " By default encoder is created by type and is choosen automatically by the device.\n" + "\n" " -h, --help\n" " Print this help.\n" "\n" @@ -651,6 +656,7 @@ guess_record_format(const char *filename) { #define OPT_DISABLE_SCREENSAVER 1020 #define OPT_SHORTCUT_MOD 1021 #define OPT_NO_KEY_REPEAT 1022 +#define OPT_ENCODER_NAME 1023 bool scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { @@ -658,6 +664,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { {"always-on-top", no_argument, NULL, OPT_ALWAYS_ON_TOP}, {"bit-rate", required_argument, NULL, 'b'}, {"codec-options", required_argument, NULL, OPT_CODEC_OPTIONS}, + {"encoder-name", required_argument, NULL, OPT_ENCODER_NAME}, {"crop", required_argument, NULL, OPT_CROP}, {"disable-screensaver", no_argument, NULL, OPT_DISABLE_SCREENSAVER}, @@ -845,6 +852,9 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { case OPT_CODEC_OPTIONS: opts->codec_options = optarg; break; + case OPT_ENCODER_NAME: + opts->encoder_name = optarg; + break; case OPT_FORCE_ADB_FORWARD: opts->force_adb_forward = true; break; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 45068cbb..fcd9ffdb 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -318,6 +318,7 @@ scrcpy(const struct scrcpy_options *options) { .show_touches = options->show_touches, .stay_awake = options->stay_awake, .codec_options = options->codec_options, + .encoder_name = options->encoder_name, .force_adb_forward = options->force_adb_forward, }; if (!server_start(&server, options->serial, ¶ms)) { diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h index 86a2b57b..33f4bbac 100644 --- a/app/src/scrcpy.h +++ b/app/src/scrcpy.h @@ -51,6 +51,7 @@ struct scrcpy_options { const char *push_target; const char *render_driver; const char *codec_options; + const char *encoder_name; enum sc_log_level log_level; enum sc_record_format record_format; struct sc_port_range port_range; @@ -89,6 +90,7 @@ struct scrcpy_options { .push_target = NULL, \ .render_driver = NULL, \ .codec_options = NULL, \ + .encoder_name = NULL, \ .log_level = SC_LOG_LEVEL_INFO, \ .record_format = SC_RECORD_FORMAT_AUTO, \ .port_range = { \ diff --git a/app/src/server.c b/app/src/server.c index 422bbfa5..9267356b 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -294,6 +294,7 @@ execute_server(struct server *server, const struct server_params *params) { params->show_touches ? "true" : "false", params->stay_awake ? "true" : "false", params->codec_options ? params->codec_options : "-", + params->encoder_name ? params->encoder_name : "-", }; #ifdef SERVER_DEBUGGER LOGI("Server debugger waiting for a client on device port " diff --git a/app/src/server.h b/app/src/server.h index 254afe30..30ce09bc 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -48,6 +48,7 @@ struct server_params { enum sc_log_level log_level; const char *crop; const char *codec_options; + const char *encoder_name; struct sc_port_range port_range; uint16_t max_size; uint32_t bit_rate; diff --git a/server/src/main/java/com/genymobile/scrcpy/Options.java b/server/src/main/java/com/genymobile/scrcpy/Options.java index 06312a37..150d06a8 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Options.java +++ b/server/src/main/java/com/genymobile/scrcpy/Options.java @@ -16,6 +16,7 @@ public class Options { private boolean showTouches; private boolean stayAwake; private String codecOptions; + private String encoderName; public Ln.Level getLogLevel() { return logLevel; @@ -120,4 +121,12 @@ public class Options { public void setCodecOptions(String codecOptions) { this.codecOptions = codecOptions; } + + public String getEncoderName() { + return encoderName; + } + + public void setEncoderName(String encoderName) { + this.encoderName = encoderName; + } } diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index d722388c..973b1cfb 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -26,17 +26,20 @@ public class ScreenEncoder implements Device.RotationListener { private final AtomicBoolean rotationChanged = new AtomicBoolean(); private final ByteBuffer headerBuffer = ByteBuffer.allocate(12); + private String encoderName; private List codecOptions; private int bitRate; private int maxFps; private boolean sendFrameMeta; private long ptsOrigin; - public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, List codecOptions) { + public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, + List codecOptions, String encoderName) { this.sendFrameMeta = sendFrameMeta; this.bitRate = bitRate; this.maxFps = maxFps; this.codecOptions = codecOptions; + this.encoderName = encoderName; } @Override @@ -69,7 +72,7 @@ public class ScreenEncoder implements Device.RotationListener { boolean alive; try { do { - MediaCodec codec = createCodec(); + MediaCodec codec = createCodec(encoderName); IBinder display = createDisplay(); ScreenInfo screenInfo = device.getScreenInfo(); Rect contentRect = screenInfo.getContentRect(); @@ -150,7 +153,11 @@ public class ScreenEncoder implements Device.RotationListener { IO.writeFully(fd, headerBuffer); } - private static MediaCodec createCodec() throws IOException { + private static MediaCodec createCodec(String encoderName) throws IOException { + if (encoderName != null) { + Ln.d("Creating encoder by name \"" + encoderName + "\""); + return MediaCodec.createByCodecName(encoderName); + } return MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC); } diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index 9b7f9de8..10412163 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -54,7 +54,8 @@ public final class Server { boolean tunnelForward = options.isTunnelForward(); try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) { - ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps(), codecOptions); + ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), + options.getBitRate(), options.getMaxFps(), codecOptions, options.getEncoderName()); if (options.getControl()) { final Controller controller = new Controller(device, connection); @@ -120,7 +121,7 @@ public final class Server { "The server version (" + BuildConfig.VERSION_NAME + ") does not match the client " + "(" + clientVersion + ")"); } - final int expectedParameters = 14; + final int expectedParameters = 15; if (args.length != expectedParameters) { throw new IllegalArgumentException("Expecting " + expectedParameters + " parameters"); } @@ -167,6 +168,9 @@ public final class Server { String codecOptions = args[13]; options.setCodecOptions(codecOptions); + String encoderName = "-".equals(args[14]) ? null : args[14]; + options.setEncoderName(encoderName); + return options; }