From 5789a83ea2b7600882f9dd64aa02d559983df9e2 Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 14 Oct 2026 21:06:07 +0200 Subject: [PATCH] =?UTF-8?q?Define=20atomic=20call=20video=20bitrate=20rang?= =?UTF-8?q?e=20with=20300=E2=80=934000=20kbps=20defaults?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/call/call_video_rate.c | 17 +++++++++++++++++ src/call/call_video_rate.h | 6 ++++++ src/chat/chat_setting.c | 12 ++++++++++++ 3 files changed, 35 insertions(+) diff --git a/src/call/call_video_rate.c b/src/call/call_video_rate.c index a43d4f7c..7a92054b 100644 --- a/src/call/call_video_rate.c +++ b/src/call/call_video_rate.c @@ -1,10 +1,27 @@ #include "call_video_rate.h" #include "../../lib/debug_config.h" #include +#include #define WINDOW_US 500000u #define MAX_BITRATE 100000000u +/* Обе границы проверяются до записи: частично применённого диапазона не бывает. */ +int call_video_rate_parse_range(const char *text, uint32_t *minimum_bps, uint32_t *maximum_bps) { + char *end = NULL; + if (!text || !minimum_bps || !maximum_bps || *text < '0' || *text > '9') goto invalid; + unsigned long minimum = strtoul(text, &end, 10); + if (*end != ':' || end[1] < '0' || end[1] > '9') goto invalid; + unsigned long maximum = strtoul(end + 1, &end, 10); + if (*end || minimum < CALL_VIDEO_RATE_MIN_BPS / 1000 || minimum > maximum + || maximum > CALL_VIDEO_RATE_MAX_BPS / 1000) goto invalid; + *minimum_bps = (uint32_t)minimum * 1000; *maximum_bps = (uint32_t)maximum * 1000; + return 0; +invalid: + DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video bitrate range invalid value='%s' expected=300..4000 min:max", text ? text : "(null)"); + return -1; +} + void call_video_rate_init(struct call_video_rate *rate, uint64_t now_us) { if (!rate) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video rate init without state"); return; } memset(rate, 0, sizeof(*rate)); diff --git a/src/call/call_video_rate.h b/src/call/call_video_rate.h index b8bb2835..84692058 100644 --- a/src/call/call_video_rate.h +++ b/src/call/call_video_rate.h @@ -5,6 +5,9 @@ #ifndef CALL_VIDEO_RATE_H #define CALL_VIDEO_RATE_H #include +#define CALL_VIDEO_RATE_MIN_BPS 300000u +#define CALL_VIDEO_RATE_MAX_BPS 4000000u +#define CALL_VIDEO_RATE_DEFAULT_RANGE "300:4000" #ifdef __cplusplus extern "C" { #endif @@ -37,6 +40,9 @@ struct call_video_rate { }; void call_video_rate_init(struct call_video_rate *rate, uint64_t now_us); +/* Атомарная настройка min:max в десятичных кбит/с, 300 <= min <= max <= 4000. + * На ошибке выходные значения не меняются; результат 0/-1. */ +int call_video_rate_parse_range(const char *text, uint32_t *minimum_bps, uint32_t *maximum_bps); /* 0 — результат получен, -1 — недопустимый снимок (состояние не меняется). * target != applied — рекомендация, не подтверждение применения. Pending запрещает новую команду. */ int call_video_rate_step(struct call_video_rate *rate, const struct call_video_rate_sample *sample, diff --git a/src/chat/chat_setting.c b/src/chat/chat_setting.c index fca49dee..f45ab5c9 100644 --- a/src/chat/chat_setting.c +++ b/src/chat/chat_setting.c @@ -6,6 +6,7 @@ */ #include "chat_setting.h" +#include "../call/call_video_rate.h" #include "../utun_instance.h" #include "../../lib/debug_config.h" @@ -63,6 +64,7 @@ static const struct chat_setting_def g_setting_defs[] = { {"group_autoconnect", CHAT_SETTING_BOOL, 1, 0, 1}, {"aec_enabled", CHAT_SETTING_BOOL, 1, 0, 1}, /* AEC (SpeexDSP) в звонке, desktop GUI */ {"call_jitter_max_reserve_ms", CHAT_SETTING_INT, 1000, 500, 2000}, + {"call_video_bitrate_range_kbps", CHAT_SETTING_STRING, 0, 0, 0}, {"call_compressor_enabled", CHAT_SETTING_BOOL, 1, 0, 1}, {"call_compressor_max_gain_db",CHAT_SETTING_INT, 15, 1, 60}, {"member_files_enabled", CHAT_SETTING_BOOL, 1, 0, 1}, @@ -111,6 +113,10 @@ int chat_setting_set_state(struct chat_setting_state* s, const char* name, const int v; if (def->type == CHAT_SETTING_STRING) { + if (strcmp(name, "call_video_bitrate_range_kbps") == 0) { + uint32_t minimum, maximum; + if (call_video_rate_parse_range(value, &minimum, &maximum)) return -2; + } if (strlen(value) >= sizeof(s->string_val[0])) { DEBUG_ERROR(CS_ID, "chat_setting: '%s' string too long bytes=%zu limit=%zu", name, strlen(value), sizeof(s->string_val[0]) - 1); return -2; @@ -159,6 +165,12 @@ int chat_setting_set_state(struct chat_setting_state* s, const char* name, const } const char* chat_setting_get_state(const struct chat_setting_state* s, const char* name) { + if (s && name && strcmp(name, "call_video_bitrate_range_kbps") == 0) { + int idx = chat_setting_find(name); + for (int i = 0; s->initialized && i < s->string_count; i++) + if (s->string_idx[i] == idx) return s->string_val[i]; + return CALL_VIDEO_RATE_DEFAULT_RANGE; + } if (!s || !s->initialized) return NULL; int idx = chat_setting_find(name); if (idx < 0) return NULL;