Do not parse --max-fps float in the client

Many parsing and formatting C functions like strtof() and asprintf() are
locale-dependent. Forcing a C locale just for the conversions in a way
that works on all platforms is a mess.

In practice, this is not a problem, scrcpy always uses the C locale,
because it never calls:

    setlocale(LC_ALL, "");

But the max-fps option should not depend on the locale configuration
anyway.

Since the value is parsed by the client in Java anyway, just forward the
string value as is.
This commit is contained in:
Romain Vimont 2024-09-14 14:32:32 +02:00
parent 265a15e0b1
commit 1d713d7598
8 changed files with 7 additions and 67 deletions

View File

@ -1447,26 +1447,6 @@ parse_integers_arg(const char *s, const char sep, size_t max_items, long *out,
return count;
}
static bool
parse_float_arg(const char *s, float *out, float min, float max,
const char *name) {
float value;
bool ok = sc_str_parse_float(s, &value);
if (!ok) {
LOGE("Could not parse %s: %s", name, s);
return false;
}
if (value < min || value > max) {
LOGE("Could not parse %s: value (%f) out-of-range (%f; %f)",
name, value, min, max);
return false;
}
*out = value;
return true;
}
static bool
parse_bit_rate(const char *s, uint32_t *bit_rate) {
long value;
@ -1493,18 +1473,6 @@ parse_max_size(const char *s, uint16_t *max_size) {
return true;
}
static bool
parse_max_fps(const char *s, float *max_fps) {
float value;
bool ok = parse_float_arg(s, &value, 0, (float) (1 << 16), "max fps");
if (!ok) {
return false;
}
*max_fps = value;
return true;
}
static bool
parse_buffering_time(const char *s, sc_tick *tick) {
long value;
@ -2252,9 +2220,7 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
"--keyboard=uhid instead.");
return false;
case OPT_MAX_FPS:
if (!parse_max_fps(optarg, &opts->max_fps)) {
return false;
}
opts->max_fps = optarg;
break;
case 'm':
if (!parse_max_size(optarg, &opts->max_size)) {

View File

@ -48,7 +48,7 @@ const struct scrcpy_options scrcpy_options_default = {
.max_size = 0,
.video_bit_rate = 0,
.audio_bit_rate = 0,
.max_fps = 0,
.max_fps = NULL,
.lock_video_orientation = SC_LOCK_VIDEO_ORIENTATION_UNLOCKED,
.display_orientation = SC_ORIENTATION_0,
.record_orientation = SC_ORIENTATION_0,

View File

@ -240,7 +240,7 @@ struct scrcpy_options {
uint16_t max_size;
uint32_t video_bit_rate;
uint32_t audio_bit_rate;
float max_fps;
const char *max_fps; // float to be parsed by the server
enum sc_lock_video_orientation lock_video_orientation;
enum sc_orientation display_orientation;
enum sc_orientation record_orientation;

View File

@ -321,7 +321,8 @@ execute_server(struct sc_server *server,
ADD_PARAM("max_size=%" PRIu16, params->max_size);
}
if (params->max_fps) {
ADD_PARAM("max_fps=%f" , params->max_fps);
VALIDATE_STRING(params->max_fps);
ADD_PARAM("max_fps=%s", params->max_fps);
}
if (params->lock_video_orientation != SC_LOCK_VIDEO_ORIENTATION_UNLOCKED) {
ADD_PARAM("lock_video_orientation=%" PRIi8,

View File

@ -44,7 +44,7 @@ struct sc_server_params {
uint16_t max_size;
uint32_t video_bit_rate;
uint32_t audio_bit_rate;
float max_fps;
const char *max_fps; // float to be parsed by the server
int8_t lock_video_orientation;
bool control;
uint32_t display_id;

View File

@ -147,25 +147,6 @@ sc_str_parse_integer_with_suffix(const char *s, long *out) {
return true;
}
bool
sc_str_parse_float(const char *s, float *out) {
char *endptr;
if (*s == '\0') {
return false;
}
errno = 0;
float value = strtof(s, &endptr);
if (errno == ERANGE) {
return false;
}
if (*endptr != '\0') {
return false;
}
*out = value;
return true;
}
bool
sc_str_list_contains(const char *list, char sep, const char *s) {
char *p;

View File

@ -66,14 +66,6 @@ sc_str_parse_integers(const char *s, const char sep, size_t max_items,
bool
sc_str_parse_integer_with_suffix(const char *s, long *out);
/**
* `Parse `s` as a float into `out`
*
* Return true if the conversion succeeded, false otherwise.
*/
bool
sc_str_parse_float(const char *s, float *out);
/**
* Search `s` in the list separated by `sep`
*

View File

@ -78,7 +78,7 @@ static void test_options(void) {
assert(opts->video_bit_rate == 5000000);
assert(!strcmp(opts->crop, "100:200:300:400"));
assert(opts->fullscreen);
assert(opts->max_fps == 30);
assert(!strcmp(opts->max_fps, "30"));
assert(opts->max_size == 1024);
assert(opts->lock_video_orientation == 2);
assert(opts->port_range.first == 1234);