diff --git a/app/scrcpy.1 b/app/scrcpy.1 index 6920e9a4..0729bc23 100644 --- a/app/scrcpy.1 +++ b/app/scrcpy.1 @@ -154,6 +154,12 @@ It only shows physical touches (not clicks from scrcpy). .B \-v, \-\-version Print the version of scrcpy. +.TP +.BI "\-V, \-\-verbosity " value +Set the log level ("debug", "info", "warn" or "error"). + +Default is "info" for release builds, "debug" for debug builds. + .TP .B \-w, \-\-stay-awake Keep the device on while scrcpy is running. diff --git a/app/src/cli.c b/app/src/cli.c index 30272828..b19d9a58 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -145,6 +145,14 @@ scrcpy_print_usage(const char *arg0) { "\n" " -v, --version\n" " Print the version of scrcpy.\n" + "\n" + " -V, --verbosity value\n" + " Set the log level (debug, info, warn or error).\n" +#ifndef NDEBUG + " Default is debug.\n" +#else + " Default is info.\n" +#endif "\n" " -w, --stay-awake\n" " Keep the device on while scrcpy is running.\n" @@ -433,6 +441,32 @@ parse_display_id(const char *s, uint16_t *display_id) { return true; } +static bool +parse_log_level(const char *s, enum sc_log_level *log_level) { + if (!strcmp(s, "debug")) { + *log_level = SC_LOG_LEVEL_DEBUG; + return true; + } + + if (!strcmp(s, "info")) { + *log_level = SC_LOG_LEVEL_INFO; + return true; + } + + if (!strcmp(s, "warn")) { + *log_level = SC_LOG_LEVEL_WARN; + return true; + } + + if (!strcmp(s, "error")) { + *log_level = SC_LOG_LEVEL_ERROR; + return true; + } + + LOGE("Could not parse log level: %s", s); + return false; +} + static bool parse_record_format(const char *optarg, enum recorder_format *format) { if (!strcmp(optarg, "mp4")) { @@ -513,6 +547,7 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { {"show-touches", no_argument, NULL, 't'}, {"stay-awake", no_argument, NULL, 'w'}, {"turn-screen-off", no_argument, NULL, 'S'}, + {"verbosity", required_argument, NULL, 'V'}, {"version", no_argument, NULL, 'v'}, {"window-title", required_argument, NULL, OPT_WINDOW_TITLE}, {"window-x", required_argument, NULL, OPT_WINDOW_X}, @@ -529,8 +564,8 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { optind = 0; // reset to start from the first argument in tests int c; - while ((c = getopt_long(argc, argv, "b:c:fF:hm:nNp:r:s:StTvw", long_options, - NULL)) != -1) { + while ((c = getopt_long(argc, argv, "b:c:fF:hm:nNp:r:s:StTvV:w", + long_options, NULL)) != -1) { switch (c) { case 'b': if (!parse_bit_rate(optarg, &opts->bit_rate)) { @@ -609,6 +644,11 @@ scrcpy_parse_args(struct scrcpy_cli_args *args, int argc, char *argv[]) { case 'v': args->version = true; break; + case 'V': + if (!parse_log_level(optarg, &opts->log_level)) { + return false; + } + break; case 'w': opts->stay_awake = true; break; diff --git a/app/src/main.c b/app/src/main.c index d683c508..85e578ae 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -29,6 +29,24 @@ print_version(void) { LIBAVUTIL_VERSION_MICRO); } +static SDL_LogPriority +convert_log_level_to_sdl(enum sc_log_level level) { + switch (level) { + case SC_LOG_LEVEL_DEBUG: + return SDL_LOG_PRIORITY_DEBUG; + case SC_LOG_LEVEL_INFO: + return SDL_LOG_PRIORITY_INFO; + case SC_LOG_LEVEL_WARN: + return SDL_LOG_PRIORITY_WARN; + case SC_LOG_LEVEL_ERROR: + return SDL_LOG_PRIORITY_ERROR; + default: + assert(!"unexpected log level"); + return SC_LOG_LEVEL_INFO; + } +} + + int main(int argc, char *argv[]) { #ifdef __WINDOWS__ @@ -38,20 +56,23 @@ main(int argc, char *argv[]) { setbuf(stderr, NULL); #endif -#ifndef NDEBUG - SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG); -#endif - struct scrcpy_cli_args args = { .opts = SCRCPY_OPTIONS_DEFAULT, .help = false, .version = false, }; +#ifndef NDEBUG + args.opts.log_level = SC_LOG_LEVEL_DEBUG; +#endif + if (!scrcpy_parse_args(&args, argc, argv)) { return 1; } + SDL_LogPriority sdl_log = convert_log_level_to_sdl(args.opts.log_level); + SDL_LogSetAllPriority(sdl_log); + if (args.help) { scrcpy_print_usage(argv[0]); return 0; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 05960630..7a873391 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -293,6 +293,7 @@ bool scrcpy(const struct scrcpy_options *options) { bool record = !!options->record_filename; struct server_params params = { + .log_level = options->log_level, .crop = options->crop, .port_range = options->port_range, .max_size = options->max_size, diff --git a/app/src/scrcpy.h b/app/src/scrcpy.h index af2e3bf5..8d324378 100644 --- a/app/src/scrcpy.h +++ b/app/src/scrcpy.h @@ -8,6 +8,7 @@ #include "common.h" #include "input_manager.h" #include "recorder.h" +#include "util/log.h" struct scrcpy_options { const char *serial; @@ -17,6 +18,7 @@ struct scrcpy_options { const char *push_target; const char *render_driver; const char *codec_options; + enum sc_log_level log_level; enum recorder_format record_format; struct port_range port_range; uint16_t max_size; @@ -50,6 +52,7 @@ struct scrcpy_options { .push_target = NULL, \ .render_driver = NULL, \ .codec_options = NULL, \ + .log_level = SC_LOG_LEVEL_INFO, \ .record_format = RECORDER_FORMAT_AUTO, \ .port_range = { \ .first = DEFAULT_LOCAL_PORT_RANGE_FIRST, \ diff --git a/app/src/server.c b/app/src/server.c index 7cfbef0d..5ec2441c 100644 --- a/app/src/server.c +++ b/app/src/server.c @@ -229,6 +229,23 @@ enable_tunnel_any_port(struct server *server, struct port_range port_range) { return enable_tunnel_forward_any_port(server, port_range); } +static const char * +log_level_to_server_string(enum sc_log_level level) { + switch (level) { + case SC_LOG_LEVEL_DEBUG: + return "debug"; + case SC_LOG_LEVEL_INFO: + return "info"; + case SC_LOG_LEVEL_WARN: + return "warn"; + case SC_LOG_LEVEL_ERROR: + return "error"; + default: + assert(!"unexpected log level"); + return "(unknown)"; + } +} + static process_t execute_server(struct server *server, const struct server_params *params) { char max_size_string[6]; @@ -259,11 +276,7 @@ execute_server(struct server *server, const struct server_params *params) { "/", // unused "com.genymobile.scrcpy.Server", SCRCPY_VERSION, -#ifndef NDEBUG - "debug", -#else - "info", -#endif + log_level_to_server_string(params->log_level), max_size_string, bit_rate_string, max_fps_string, diff --git a/app/src/server.h b/app/src/server.h index 5b51695a..ff7acbdb 100644 --- a/app/src/server.h +++ b/app/src/server.h @@ -9,6 +9,7 @@ #include "config.h" #include "command.h" #include "common.h" +#include "util/log.h" #include "util/net.h" struct server { @@ -43,6 +44,7 @@ struct server { } struct server_params { + enum sc_log_level log_level; const char *crop; const char *codec_options; struct port_range port_range; diff --git a/app/src/util/log.h b/app/src/util/log.h index 5955c7fb..8c5c7dee 100644 --- a/app/src/util/log.h +++ b/app/src/util/log.h @@ -3,6 +3,13 @@ #include +enum sc_log_level { + SC_LOG_LEVEL_DEBUG, + SC_LOG_LEVEL_INFO, + SC_LOG_LEVEL_WARN, + SC_LOG_LEVEL_ERROR, +}; + #define LOGV(...) SDL_LogVerbose(SDL_LOG_CATEGORY_APPLICATION, __VA_ARGS__) #define LOGD(...) SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, __VA_ARGS__) #define LOGI(...) SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, __VA_ARGS__)