diff --git a/apps/desktop/src/config_center/config_center.cpp b/apps/desktop/src/config_center/config_center.cpp
index 089f2f3a..297bf792 100644
--- a/apps/desktop/src/config_center/config_center.cpp
+++ b/apps/desktop/src/config_center/config_center.cpp
@@ -149,6 +149,14 @@ int ConfigCenter::Load() {
*ini_, section_, "direct_start_bitrate_bps", kDefaultDirectStartBitrateBps);
relay_start_bitrate_bps_ = ReadStartingBitrate(
*ini_, section_, "relay_start_bitrate_bps", kDefaultRelayStartBitrateBps);
+ disable_receiver_padding_probing_ = ini_->GetBoolValue(
+ section_, "disable_receiver_padding_probing",
+ kDefaultDisableReceiverPaddingProbing);
+ if (!ini_->GetValue(section_, "disable_receiver_padding_probing", nullptr)) {
+ ini_->SetBoolValue(section_, "disable_receiver_padding_probing",
+ disable_receiver_padding_probing_);
+ persist_config_migration = true;
+ }
// Populate old configurations and repair invalid values so the file shows
// the estimates that will actually be used for subsequent connections.
for (const auto& entry :
@@ -276,6 +284,8 @@ int ConfigCenter::Save() {
ini_->SetLongValue(section_, "turn_mode", static_cast(turn_mode_));
ini_->SetLongValue(section_, "direct_start_bitrate_bps", direct_start_bitrate_bps_);
ini_->SetLongValue(section_, "relay_start_bitrate_bps", relay_start_bitrate_bps_);
+ ini_->SetBoolValue(section_, "disable_receiver_padding_probing",
+ disable_receiver_padding_probing_);
ini_->SetBoolValue(section_, "enable_turn",
turn_mode_ != TURN_MODE::DISABLED);
ini_->SetBoolValue(section_, "enable_srtp", true);
@@ -326,6 +336,8 @@ std::string ConfigCenter::ExportSharedHostConfig() const {
host.SetLongValue(section_, "turn_mode", static_cast(turn_mode_));
host.SetLongValue(section_, "direct_start_bitrate_bps", direct_start_bitrate_bps_);
host.SetLongValue(section_, "relay_start_bitrate_bps", relay_start_bitrate_bps_);
+ host.SetBoolValue(section_, "disable_receiver_padding_probing",
+ disable_receiver_padding_probing_);
host.SetLongValue(section_, "video_encode_format", static_cast(video_encode_format_));
host.SetBoolValue(section_, "trusted_devices_only", trusted_devices_only_.load());
host.SetBoolValue(section_, "lock_on_disconnect", lock_on_disconnect_.load());
@@ -351,6 +363,9 @@ int ConfigCenter::ApplySharedHostConfig(const std::string& contents) {
host, section_, "direct_start_bitrate_bps", kDefaultDirectStartBitrateBps);
const int relay_bps = ReadStartingBitrate(
host, section_, "relay_start_bitrate_bps", kDefaultRelayStartBitrateBps);
+ const bool disable_receiver_padding_probing = host.GetBoolValue(
+ section_, "disable_receiver_padding_probing",
+ kDefaultDisableReceiverPaddingProbing);
const bool trusted = host.GetBoolValue(section_, "trusted_devices_only", false);
const bool lock = host.GetBoolValue(section_, "lock_on_disconnect", true);
MiniRtcSignalServerAddress address{};
@@ -362,6 +377,8 @@ int ConfigCenter::ApplySharedHostConfig(const std::string& contents) {
{"turn_mode", std::to_string(turn)}, {"video_encode_format", std::to_string(codec)},
{"direct_start_bitrate_bps", std::to_string(direct_bps)},
{"relay_start_bitrate_bps", std::to_string(relay_bps)},
+ {"disable_receiver_padding_probing",
+ disable_receiver_padding_probing ? "true" : "false"},
{"trusted_devices_only", trusted ? "true" : "false"},
{"lock_on_disconnect", lock ? "true" : "false"}}) != 0) return -1;
enable_self_hosted_ = self_hosted;
@@ -370,6 +387,7 @@ int ConfigCenter::ApplySharedHostConfig(const std::string& contents) {
turn_mode_ = static_cast(turn);
direct_start_bitrate_bps_ = direct_bps;
relay_start_bitrate_bps_ = relay_bps;
+ disable_receiver_padding_probing_ = disable_receiver_padding_probing;
video_encode_format_ = static_cast(codec);
trusted_devices_only_.store(trusted);
lock_on_disconnect_.store(lock);
@@ -664,6 +682,10 @@ int ConfigCenter::GetRelayStartBitrateBps() const {
return relay_start_bitrate_bps_;
}
+bool ConfigCenter::IsReceiverPaddingProbingDisabled() const {
+ return disable_receiver_padding_probing_;
+}
+
bool ConfigCenter::IsForceRelay() const {
return turn_mode_ == TURN_MODE::FORCE_UDP || turn_mode_ == TURN_MODE::FORCE_TCP;
}
diff --git a/apps/desktop/src/config_center/config_center.h b/apps/desktop/src/config_center/config_center.h
index 1bbb4198..ccbe4600 100644
--- a/apps/desktop/src/config_center/config_center.h
+++ b/apps/desktop/src/config_center/config_center.h
@@ -69,6 +69,7 @@ class ConfigCenter {
TURN_MODE GetTurnMode() const;
int GetDirectStartBitrateBps() const;
int GetRelayStartBitrateBps() const;
+ bool IsReceiverPaddingProbingDisabled() const;
bool IsForceRelay() const;
bool IsEnableSrtp() const;
std::string GetSignalServerHost() const;
@@ -112,6 +113,8 @@ class ConfigCenter {
static constexpr int kDefaultRelayStartBitrateBps = 500'000;
int direct_start_bitrate_bps_ = kDefaultDirectStartBitrateBps;
int relay_start_bitrate_bps_ = kDefaultRelayStartBitrateBps;
+ static constexpr bool kDefaultDisableReceiverPaddingProbing = true;
+ bool disable_receiver_padding_probing_ = kDefaultDisableReceiverPaddingProbing;
std::string signal_server_host_ = "";
std::string signal_server_host_default_ = "api.crossdesk.cn";
int signal_server_port_ = 0;
diff --git a/apps/desktop/src/gui/runtime/gui_runtime.cpp b/apps/desktop/src/gui/runtime/gui_runtime.cpp
index 644aca0b..2b6ecf98 100644
--- a/apps/desktop/src/gui/runtime/gui_runtime.cpp
+++ b/apps/desktop/src/gui/runtime/gui_runtime.cpp
@@ -318,6 +318,8 @@ int GuiRuntime::CreateConnectionPeer() {
params_.turn_mode = static_cast(config_center_->GetTurnMode());
params_.direct_start_bitrate_bps = config_center_->GetDirectStartBitrateBps();
params_.relay_start_bitrate_bps = config_center_->GetRelayStartBitrateBps();
+ params_.disable_receiver_padding_probing =
+ config_center_->IsReceiverPaddingProbingDisabled();
params_.enable_srtp = config_center_->IsEnableSrtp();
params_.video_content_type = MiniRtcVideoContentType::ScreenContent;
// Bootstrap outgoing media with fixed defaults. Live overrides come only
diff --git a/apps/desktop/src/gui/runtime/lan_runtime.cpp b/apps/desktop/src/gui/runtime/lan_runtime.cpp
index 4c666c92..3519703e 100644
--- a/apps/desktop/src/gui/runtime/lan_runtime.cpp
+++ b/apps/desktop/src/gui/runtime/lan_runtime.cpp
@@ -49,6 +49,8 @@ void GuiRuntime::InitializeLan() {
params.turn_mode = MiniRtcTurnMode::MiniRtcTurnDisabled;
params.direct_start_bitrate_bps = config_center_->GetDirectStartBitrateBps();
params.relay_start_bitrate_bps = config_center_->GetRelayStartBitrateBps();
+ params.disable_receiver_padding_probing =
+ config_center_->IsReceiverPaddingProbingDisabled();
params.video_content_type = MiniRtcVideoContentType::ScreenContent;
params.video_quality = MiniRtcVideoQuality::MiniRtcVideoQualityHigh;
params.video_frame_rate = 60;
diff --git a/deps/submodules/minirtc b/deps/submodules/minirtc
index 195f44c0..d75105c2 160000
--- a/deps/submodules/minirtc
+++ b/deps/submodules/minirtc
@@ -1 +1 @@
-Subproject commit 195f44c0fe68f3d0e8831cf9c1ab084b64582dbe
+Subproject commit d75105c22f16a140c996e4c9ec119c0759cd52f6
diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md
index 2b5e7af6..2cb1c7de 100644
--- a/docs/USER_GUIDE.md
+++ b/docs/USER_GUIDE.md
@@ -186,7 +186,7 @@ macOS 保留一个 CrossDesk Dock 应用图标,主窗口与远程控制窗口
-### 起始带宽配置
+### 起始带宽与探测配置
退出客户端后,编辑缓存目录中 `config.ini` 的 `[Settings]` 节,重启后生效:
@@ -194,13 +194,16 @@ macOS 保留一个 CrossDesk Dock 应用图标,主窗口与远程控制窗口
[Settings]
direct_start_bitrate_bps = 1500000
relay_start_bitrate_bps = 500000
+disable_receiver_padding_probing = true
```
两个值的单位均为 bps,分别控制本机原生媒体发送端在 P2P / IP 直连和 TURN 中继路径上的拥塞控制起始估计。桌面端默认值为 1.5 Mbps 和 0.5 Mbps,允许范围为 300000–20000000;缺失或非法值使用对应默认值,启动时补写到配置文件。连接后仍按网络反馈动态调整,桌面墙带宽预算继续生效。观看远程画面时,应修改发送画面的被控端配置。浏览器连接使用独立的带宽控制,不受这两个选项影响。
该文件在 macOS / Linux 上默认位于 `~/.cache/CrossDesk/`(设置 `XDG_CACHE_HOME` 时使用该目录下的 `CrossDesk/`);Windows 安装版 Release 位于 `%LOCALAPPDATA%\CrossDesk\cache\`,Windows Debug 使用工作目录下的 `cache/`,便携版使用可执行文件旁的 `data/`。
-Windows 已配置后台主机时,以 `%ProgramData%\CrossDeskUnattended\shared-identity.json` 的 `host_config` 中保存的 INI 配置为准。管理员须在 GUI 与后台服务均停止时修改其中这两个配置项,再重启服务和 GUI;单独修改用户缓存或 `host/config.ini` 会在启动时被共享配置覆盖。
+Windows 已配置后台主机时,以 `%ProgramData%\CrossDeskUnattended\shared-identity.json` 的 `host_config` 中保存的 INI 配置为准。管理员须在 GUI 与后台服务均停止时修改其中这些配置项,再重启服务和 GUI;单独修改用户缓存或 `host/config.ini` 会在启动时被共享配置覆盖。
+
+桌面端的 `disable_receiver_padding_probing` 默认为 `true`,禁止尚未发送过本地视频的连接发送填充探测包;设为 `false` 可恢复接收端填充探测。开始发送本地视频后仍保留正常探测和静态画面时的带宽恢复。缺失或非法值使用默认值,已有显式配置保持不变。该选项适用于原生直连和中继,配置位置及重启要求同上;Windows 后台主机共享配置也包含此项。MiniRTC API 零初始化仍默认为 `false`,桌面端会显式传入此配置。
### 桌面墙画面传输
diff --git a/docs/USER_GUIDE_EN.md b/docs/USER_GUIDE_EN.md
index 6ed6a00c..43857e27 100644
--- a/docs/USER_GUIDE_EN.md
+++ b/docs/USER_GUIDE_EN.md
@@ -187,7 +187,7 @@ The direct IP switch in the Network group is independent of the relay settings u
-### Starting bandwidth configuration
+### Starting bandwidth and probing configuration
Quit the client, edit the `[Settings]` section in its cache directory's `config.ini`, then restart:
@@ -195,13 +195,16 @@ Quit the client, edit the `[Settings]` section in its cache directory's `config.
[Settings]
direct_start_bitrate_bps = 1500000
relay_start_bitrate_bps = 500000
+disable_receiver_padding_probing = true
```
Both values are in bps and set the local native media sender's initial congestion-control estimate for P2P / direct IP and TURN relay paths, respectively. Desktop defaults are 1.5 Mbps and 0.5 Mbps; the accepted range is 300000–20000000. Missing or invalid values use the corresponding default, which is written to the file on startup. Network feedback continues to adjust bandwidth, and DeskHub bandwidth budgets still apply. To change the stream you watch remotely, edit the host that sends the video. Browser connections use separate bandwidth control and are unaffected.
The file is in `~/.cache/CrossDesk/` on macOS / Linux (`CrossDesk/` under `XDG_CACHE_HOME` when set), and `%LOCALAPPDATA%\CrossDesk\cache\` for installed Windows Release builds. Windows Debug builds use `cache/` under the working directory; portable builds use `data/` beside the executable.
-With a Windows background host configured, the INI string in `host_config` inside `%ProgramData%\CrossDeskUnattended\shared-identity.json` is authoritative. An administrator must stop both the GUI and background service before editing these two entries there, then restart both. Editing only the user cache or `host/config.ini` is overwritten by the shared configuration on startup.
+With a Windows background host configured, the INI string in `host_config` inside `%ProgramData%\CrossDeskUnattended\shared-identity.json` is authoritative. An administrator must stop both the GUI and background service before editing these entries there, then restart both. Editing only the user cache or `host/config.ini` is overwritten by the shared configuration on startup.
+
+The desktop default for `disable_receiver_padding_probing` is `true`, suppressing padding probes on connections that have not yet sent local video. Set it to `false` to restore receiver-side padding probes. After local video starts, normal probing and bandwidth recovery during static content remain available. Missing or invalid values use the default; existing explicit settings are preserved. It applies to native direct and relay connections, uses the configuration locations and restart procedure above, and is included in the Windows background host's shared configuration. A zero-initialized MiniRTC API parameter remains `false`; the desktop passes this setting explicitly.
### DeskHub video transmission