diff --git a/README.md b/README.md index a19aec0f..4b898d26 100644 --- a/README.md +++ b/README.md @@ -258,9 +258,9 @@ The video codec can be selected. The possible values are `h264` (default), `h265` and `av1`: ```bash -scrcpy --codec=h264 # default -scrcpy --codec=h265 -scrcpy --codec=av1 +scrcpy --video-codec=h264 # default +scrcpy --video-codec=h265 +scrcpy --video-codec=av1 ``` @@ -277,8 +277,8 @@ To list the available encoders, you can pass an invalid encoder name; the error will give the available encoders: ```bash -scrcpy --encoder=_ # for the default codec -scrcpy --codec=h265 --encoder=_ # for a specific codec +scrcpy --encoder=_ # for the default codec +scrcpy --video-codec=h265 --encoder=_ # for a specific codec ``` ### Capture diff --git a/app/data/bash-completion/scrcpy b/app/data/bash-completion/scrcpy index 22dc4cee..d92cf009 100644 --- a/app/data/bash-completion/scrcpy +++ b/app/data/bash-completion/scrcpy @@ -3,7 +3,6 @@ _scrcpy() { local opts=" --always-on-top -b --bit-rate= - --codec= --codec-options= --crop= -d --select-usb @@ -55,6 +54,7 @@ _scrcpy() { --v4l2-sink= -V --verbosity= -v --version + --video-codec= -w --stay-awake --window-borderless --window-title= @@ -66,7 +66,7 @@ _scrcpy() { _init_completion -s || return case "$prev" in - --codec) + --video-codec) COMPREPLY=($(compgen -W 'h264 h265 av1' -- "$cur")) return ;; diff --git a/app/data/zsh-completion/_scrcpy b/app/data/zsh-completion/_scrcpy index 17e1de9f..b9c94e1e 100644 --- a/app/data/zsh-completion/_scrcpy +++ b/app/data/zsh-completion/_scrcpy @@ -10,7 +10,6 @@ local arguments arguments=( '--always-on-top[Make scrcpy window always on top \(above other windows\)]' {-b,--bit-rate=}'[Encode the video at the given bit-rate]' - '--codec=[Select the video codec]:codec:(h264 h265 av1)' '--codec-options=[Set a list of comma-separated key\:type=value options for the device encoder]' '--crop=[\[width\:height\:x\:y\] Crop the device screen on the server]' {-d,--select-usb}'[Use USB device]' @@ -60,6 +59,7 @@ arguments=( '--v4l2-sink=[\[\/dev\/videoN\] Output to v4l2loopback device]' {-V,--verbosity=}'[Set the log level]:verbosity:(verbose debug info warn error)' {-v,--version}'[Print the version of scrcpy]' + '--video-codec=[Select the video codec]:codec:(h264 h265 av1)' {-w,--stay-awake}'[Keep the device on while scrcpy is running, when the device is plugged in]' '--window-borderless[Disable window decorations \(display borderless window\)]' '--window-title=[Set a custom window title]' diff --git a/app/scrcpy.1 b/app/scrcpy.1 index 186d8ad5..32bb8464 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -25,12 +25,6 @@ Encode the video at the given bit\-rate, expressed in bits/s. Unit suffixes are Default is 8M (8000000). -.TP -.BI "\-\-codec " name -Select a video codec (h264, h265 or av1). - -Default is h264. - .TP .BI "\-\-codec\-options " key\fR[:\fItype\fR]=\fIvalue\fR[,...] Set a list of comma-separated key:type=value options for the device encoder. @@ -82,7 +76,7 @@ Also see \fB\-d\fR (\fB\-\-select\-usb\fR). .TP .BI "\-\-encoder " name -Use a specific MediaCodec encoder (depending on the codec provided by \fB\-\-codec\fR). +Use a specific MediaCodec encoder (depending on the codec provided by \fB\-\-video\-codec\fR). .TP .B \-\-force\-adb\-forward @@ -329,6 +323,12 @@ Default is "info" for release builds, "debug" for debug builds. .B \-v, \-\-version Print the version of scrcpy. +.TP +.BI "\-\-video\-codec " name +Select a video codec (h264, h265 or av1). + +Default is h264. + .TP .B \-w, \-\-stay-awake Keep the device on while scrcpy is running, when the device is plugged in. diff --git a/app/src/cli.c b/app/src/cli.c index d7a0a7ae..9163ba60 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -59,6 +59,7 @@ enum { OPT_PRINT_FPS, OPT_NO_POWER_ON, OPT_CODEC, + OPT_VIDEO_CODEC, OPT_NO_AUDIO, }; @@ -110,11 +111,13 @@ static const struct sc_option options[] = { "Default is 8M (8000000).", }, { + // Not really deprecated (--codec has never been released), but without + // declaring an explicit --codec option, getopt_long() partial matching + // behavior would consider --codec to be equivalent to --codec-options, + // which would be confusing. .longopt_id = OPT_CODEC, .longopt = "codec", - .argdesc = "name", - .text = "Select a video codec (h264, h265 or av1).\n" - "Default is h264.", + .argdesc = "value", }, { .longopt_id = OPT_CODEC_OPTIONS, @@ -177,7 +180,7 @@ static const struct sc_option options[] = { .longopt = "encoder", .argdesc = "name", .text = "Use a specific MediaCodec encoder (depending on the codec " - "provided by --codec).", + "provided by --video-codec).", }, { .longopt_id = OPT_FORCE_ADB_FORWARD, @@ -519,6 +522,13 @@ static const struct sc_option options[] = { .longopt = "version", .text = "Print the version of scrcpy.", }, + { + .longopt_id = OPT_VIDEO_CODEC, + .longopt = "video-codec", + .argdesc = "name", + .text = "Select a video codec (h264, h265 or av1).\n" + "Default is h264.", + }, { .shortopt = 'w', .longopt = "stay-awake", @@ -1395,7 +1405,7 @@ guess_record_format(const char *filename) { } static bool -parse_codec(const char *optarg, enum sc_codec *codec) { +parse_video_codec(const char *optarg, enum sc_codec *codec) { if (!strcmp(optarg, "h264")) { *codec = SC_CODEC_H264; return true; @@ -1408,7 +1418,7 @@ parse_codec(const char *optarg, enum sc_codec *codec) { *codec = SC_CODEC_AV1; return true; } - LOGE("Unsupported codec: %s (expected h264, h265 or av1)", optarg); + LOGE("Unsupported video codec: %s (expected h264, h265 or av1)", optarg); return false; } @@ -1649,7 +1659,10 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], opts->start_fps_counter = true; break; case OPT_CODEC: - if (!parse_codec(optarg, &opts->codec)) { + LOGW("--codec is deprecated, use --video-codec instead."); + // fall through + case OPT_VIDEO_CODEC: + if (!parse_video_codec(optarg, &opts->video_codec)) { return false; } break; diff --git a/app/src/options.c b/app/src/options.c index 64ec5b3b..0368ffcc 100644 --- a/app/src/options.c +++ b/app/src/options.c @@ -13,7 +13,7 @@ const struct scrcpy_options scrcpy_options_default = { .v4l2_device = NULL, #endif .log_level = SC_LOG_LEVEL_INFO, - .codec = SC_CODEC_H264, + .video_codec = SC_CODEC_H264, .record_format = SC_RECORD_FORMAT_AUTO, .keyboard_input_mode = SC_KEYBOARD_INPUT_MODE_INJECT, .mouse_input_mode = SC_MOUSE_INPUT_MODE_INJECT, diff --git a/app/src/options.h b/app/src/options.h index 7bf30011..f6ba324b 100644 --- a/app/src/options.h +++ b/app/src/options.h @@ -99,7 +99,7 @@ struct scrcpy_options { const char *v4l2_device; #endif enum sc_log_level log_level; - enum sc_codec codec; + enum sc_codec video_codec; enum sc_record_format record_format; enum sc_keyboard_input_mode keyboard_input_mode; enum sc_mouse_input_mode mouse_input_mode; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 6750f6a1..35b999a8 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -314,7 +314,7 @@ scrcpy(struct scrcpy_options *options) { .select_usb = options->select_usb, .select_tcpip = options->select_tcpip, .log_level = options->log_level, - .codec = options->codec, + .video_codec = options->video_codec, .crop = options->crop, .port_range = options->port_range, .tunnel_host = options->tunnel_host, diff --git a/app/src/server.c b/app/src/server.c index 6bf0eb6e..20433ea0 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -222,8 +222,9 @@ execute_server(struct sc_server *server, if (!params->audio) { ADD_PARAM("audio=false"); } - if (params->codec != SC_CODEC_H264) { - ADD_PARAM("codec=%s", sc_server_get_codec_name(params->codec)); + if (params->video_codec != SC_CODEC_H264) { + ADD_PARAM("video_codec=%s", + sc_server_get_codec_name(params->video_codec)); } if (params->max_size) { ADD_PARAM("max_size=%" PRIu16, params->max_size); diff --git a/app/src/server.h b/app/src/server.h index 3005ebd2..8914349f 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -25,7 +25,7 @@ struct sc_server_params { uint32_t scid; const char *req_serial; enum sc_log_level log_level; - enum sc_codec codec; + enum sc_codec video_codec; const char *crop; const char *codec_options; const char *encoder_name; diff --git a/server/src/main/java/com/genymobile/scrcpy/Options.java b/server/src/main/java/com/genymobile/scrcpy/Options.java index 07789974..73a303d8 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Options.java +++ b/server/src/main/java/com/genymobile/scrcpy/Options.java @@ -10,7 +10,7 @@ public class Options { private int scid = -1; // 31-bit non-negative value, or -1 private boolean audio = true; private int maxSize; - private VideoCodec codec = VideoCodec.H264; + private VideoCodec videoCodec = VideoCodec.H264; private int bitRate = 8000000; private int maxFps; private int lockVideoOrientation = -1; @@ -66,12 +66,12 @@ public class Options { this.maxSize = maxSize; } - public VideoCodec getCodec() { - return codec; + public VideoCodec getVideoCodec() { + return videoCodec; } - public void setCodec(VideoCodec codec) { - this.codec = codec; + public void setVideoCodec(VideoCodec videoCodec) { + this.videoCodec = videoCodec; } public int getBitRate() { diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index fdd23bf3..30e988f0 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -231,7 +231,7 @@ public class ScreenEncoder implements Device.RotationListener { if (encoders != null && encoders.length > 0) { msg.append("\nTry to use one of the available encoders:"); for (MediaCodecInfo encoder : encoders) { - msg.append("\n scrcpy --codec=").append(codec.getName()).append(" --encoder='").append(encoder.getName()).append("'"); + msg.append("\n scrcpy --video-codec=").append(codec.getName()).append(" --encoder='").append(encoder.getName()).append("'"); } } return msg.toString(); diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index eb0c1384..a926f443 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -96,7 +96,6 @@ public final class Server { AudioEncoder audioEncoder = null; try (DesktopConnection connection = DesktopConnection.open(scid, tunnelForward, audio, control, sendDummyByte)) { - VideoCodec codec = options.getCodec(); if (options.getSendDeviceMeta()) { Size videoSize = device.getScreenInfo().getVideoSize(); connection.sendDeviceMeta(Device.getDeviceName(), videoSize.getWidth(), videoSize.getHeight()); @@ -116,9 +115,10 @@ public final class Server { audioEncoder.start(); } - Streamer videoStreamer = new Streamer(connection.getVideoFd(), codec, options.getSendCodecId(), options.getSendFrameMeta()); - ScreenEncoder screenEncoder = new ScreenEncoder(device, videoStreamer, options.getBitRate(), options.getMaxFps(), - codecOptions, options.getEncoderName(), options.getDownsizeOnError()); + Streamer videoStreamer = new Streamer(connection.getVideoFd(), options.getVideoCodec(), options.getSendCodecId(), + options.getSendFrameMeta()); + ScreenEncoder screenEncoder = new ScreenEncoder(device, videoStreamer, options.getBitRate(), options.getMaxFps(), codecOptions, + options.getEncoderName(), options.getDownsizeOnError()); try { // synchronous screenEncoder.streamScreen(); @@ -195,12 +195,12 @@ public final class Server { boolean audio = Boolean.parseBoolean(value); options.setAudio(audio); break; - case "codec": - VideoCodec codec = VideoCodec.findByName(value); - if (codec == null) { + case "video_codec": + VideoCodec videoCodec = VideoCodec.findByName(value); + if (videoCodec == null) { throw new IllegalArgumentException("Video codec " + value + " not supported"); } - options.setCodec(codec); + options.setVideoCodec(videoCodec); break; case "max_size": int maxSize = Integer.parseInt(value) & ~7; // multiple of 8