From 0fe9a779f050f5837e9666513b33181c8b3c9b44 Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 14 Oct 2026 21:07:50 +0200 Subject: [PATCH] Add call video bitrate range controls to desktop settings --- tools/chatgui/src/audiodevicesettingspage.cpp | 52 +++++++++++++++++-- tools/chatgui/src/audiodevicesettingspage.h | 2 + 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/tools/chatgui/src/audiodevicesettingspage.cpp b/tools/chatgui/src/audiodevicesettingspage.cpp index 4bd36750..17d90b8c 100644 --- a/tools/chatgui/src/audiodevicesettingspage.cpp +++ b/tools/chatgui/src/audiodevicesettingspage.cpp @@ -14,6 +14,7 @@ extern "C" { #include "../../lib/mem.h" extern "C" { #include "chat/chat_core.h" +#include "call/call_video_rate.h" } #include #include @@ -22,6 +23,8 @@ extern "C" { #include #include #include +#include +#include #include AudioDeviceSettingsPage::AudioDeviceSettingsPage(DbManager* db, AudioRecorder* recorder, QWidget* parent) @@ -163,7 +166,24 @@ AudioDeviceSettingsPage::AudioDeviceSettingsPage(DbManager* db, AudioRecorder* r m_jitterReserveSpin->setSuffix(QCoreApplication::translate("ChatGui", " s")); m_jitterReserveSpin->setToolTip(QCoreApplication::translate("ChatGui", "Maximum adaptive jitter reserve for calls. Applies to the next call.")); callForm->addRow(QCoreApplication::translate("ChatGui", "Call: maximum jitter reserve"), m_jitterReserveSpin); + m_videoMinimumSpin = new QSpinBox(this); + m_videoMaximumSpin = new QSpinBox(this); + for (auto* spin : {m_videoMinimumSpin, m_videoMaximumSpin}) { + spin->setRange(CALL_VIDEO_RATE_MIN_BPS / 1000, CALL_VIDEO_RATE_MAX_BPS / 1000); + spin->setSingleStep(100); + spin->setSuffix(QCoreApplication::translate("ChatGui", " kbit/s")); + } + m_videoMinimumSpin->setValue(CALL_VIDEO_RATE_MIN_BPS / 1000); + m_videoMaximumSpin->setValue(CALL_VIDEO_RATE_MAX_BPS / 1000); + connect(m_videoMinimumSpin, QOverload::of(&QSpinBox::valueChanged), m_videoMaximumSpin, &QSpinBox::setMinimum); + connect(m_videoMaximumSpin, QOverload::of(&QSpinBox::valueChanged), m_videoMinimumSpin, &QSpinBox::setMaximum); + callForm->addRow(QCoreApplication::translate("ChatGui", "Call video: minimum bitrate"), m_videoMinimumSpin); + callForm->addRow(QCoreApplication::translate("ChatGui", "Call video: maximum bitrate"), m_videoMaximumSpin); layout->addLayout(callForm); + auto* videoHint = new QLabel(QCoreApplication::translate("ChatGui", + "Video bitrate adapts to the connection within this range. Default: 300–4000 kbit/s."), this); + videoHint->setWordWrap(true); + layout->addWidget(videoHint); buildCompressorUI(layout); @@ -211,6 +231,12 @@ void AudioDeviceSettingsPage::loadFromDb() { m_savedCompressorMaxGainDb = m_db->getUiStateInt("compressor_max_gain_db", 25); m_savedCompressorRiseRate = m_db->getUiStateInt("compressor_rise_rate", 10); m_jitterReserveSpin->setValue(m_db->getUiStateInt("call_jitter_max_reserve_ms", 1000) / 1000.0); + QByteArray range = m_db->getUiState("call_video_bitrate_range_kbps").toUtf8(); + uint32_t minimum = CALL_VIDEO_RATE_MIN_BPS, maximum = CALL_VIDEO_RATE_MAX_BPS; + if (!range.isEmpty()) call_video_rate_parse_range(range.constData(), &minimum, &maximum); + m_videoMinimumSpin->setValue(CALL_VIDEO_RATE_MIN_BPS / 1000); + m_videoMaximumSpin->setValue(maximum / 1000); + m_videoMinimumSpin->setValue(minimum / 1000); m_savedAecEnabled = m_db->getUiStateInt("aec_enabled", 1); } @@ -245,6 +271,21 @@ void AudioDeviceSettingsPage::loadFromDb() { } void AudioDeviceSettingsPage::applyAndSave() { + const char* rangeKey = "call_video_bitrate_range_kbps"; + QString range = QStringLiteral("%1:%2").arg(m_videoMinimumSpin->value()).arg(m_videoMaximumSpin->value()); + if (!m_configPath.isEmpty() && !config_update_option(m_configPath, "chatserver", rangeKey, range)) { + DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video bitrate range config save failed path=%s", qPrintable(m_configPath)); + QMessageBox::warning(this, QCoreApplication::translate("ChatGui", "Settings"), + QCoreApplication::translate("ChatGui", "Could not save the call video bitrate range.")); + return; + } + auto* rangeArg = static_cast(u_calloc(1, sizeof(chat_setting_arg))); + if (!rangeArg) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video bitrate range command allocation failed"); return; } + rangeArg->inst = gui_bridge_get_inst(); + memcpy(rangeArg->data, rangeKey, strlen(rangeKey) + 1); + QByteArray rangeBytes = range.toUtf8(); + memcpy(rangeArg->data + strlen(rangeKey) + 1, rangeBytes.constData(), rangeBytes.size() + 1); + gui_bridge_post_uasync_fn(chat_core_set_setting_trampoline, rangeArg); QString outputId = m_outputCombo->currentData().toString(); QString inputId = m_inputCombo->currentData().toString(); int codecPreset = m_codecPresetCombo->currentData().toInt(); @@ -261,13 +302,13 @@ void AudioDeviceSettingsPage::applyAndSave() { memcpy(arg->data + klen + 1, v.constData(), vlen + 1); gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg); }; - auto saveDevice = [](const char* key, const QString& id) { + auto saveText = [](const char* key, const QString& id) { QByteArray value = id.toUtf8(); size_t keyLen = strlen(key), valueLen = value.size(); auto* arg = static_cast(u_calloc(1, sizeof(save_ui_state_arg))); - if (!arg) return; + if (!arg) { DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "settings save allocation failed key=%s", key); return; } if (keyLen + valueLen + 2 > sizeof(arg->data)) { - DEBUG_ERROR(DEBUG_CATEGORY_CALL, "audio: device ID too long bytes=%zu", valueLen); + DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "settings value too long key=%s bytes=%zu", key, valueLen); u_free(arg); return; } arg->inst = gui_bridge_get_inst(); @@ -275,8 +316,9 @@ void AudioDeviceSettingsPage::applyAndSave() { memcpy(arg->data + keyLen + 1, value.constData(), valueLen + 1); gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg); }; - saveDevice("audio_output_id", outputId); - saveDevice("audio_input_id", inputId); + saveText("audio_output_id", outputId); + saveText("audio_input_id", inputId); + saveText(rangeKey, range); SoundManager::instance()->setDevices(outputId, inputId); saveKey("opus_codec_preset", codecPreset); diff --git a/tools/chatgui/src/audiodevicesettingspage.h b/tools/chatgui/src/audiodevicesettingspage.h index 9ba0a4db..7d6b35a1 100644 --- a/tools/chatgui/src/audiodevicesettingspage.h +++ b/tools/chatgui/src/audiodevicesettingspage.h @@ -57,6 +57,8 @@ private: int m_savedCompressorRiseRate = 10; class QDoubleSpinBox* m_jitterReserveSpin; + class QSpinBox* m_videoMinimumSpin; + class QSpinBox* m_videoMaximumSpin; QCheckBox* m_aecEnabledCb; int m_savedAecEnabled = 1;