From 8d5e5ffccd413f01c8d4f8ad48a12e98bc7aabff Mon Sep 17 00:00:00 2001 From: Jeffrey Nijs <109092992+JeffreyNijs@users.noreply.github.com> Date: Sun, 9 Aug 2026 21:29:51 +0200 Subject: [PATCH] feat: add enable_uso option to disable USO for batched video sends Some NIC drivers (notably VirtIO) accept the UDP_SEND_MSG_SIZE control message but silently drop the datagram instead of segmenting it. This results in Apollo logging frames as sent while no video ever reaches the client ('no video received from host' after ~10s). Add an 'enable_uso' config option (default enabled) so users on such adapters can disable UDP segmentation offload and fall back to regular MTU-sized packet sends, which works reliably. --- src/config.cpp | 1 + src/config.h | 9 +++++++++ src/platform/common.h | 8 ++++++++ src/platform/windows/misc.cpp | 5 ++++- src/stream.cpp | 1 + src_assets/common/assets/web/config.html | 1 + 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/config.cpp b/src/config.cpp index 6892e3029..037decd13 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1209,6 +1209,7 @@ namespace config { string_f(vars, "fallback_mode", video.fallback_mode); bool_f(vars, "isolated_virtual_display_option", video.isolated_virtual_display_option); bool_f(vars, "ignore_encoder_probe_failure", video.ignore_encoder_probe_failure); + bool_f(vars, "enable_uso", video.enable_uso); path_f(vars, "pkey", nvhttp.pkey); path_f(vars, "cert", nvhttp.cert); diff --git a/src/config.h b/src/config.h index a6d7c8338..21e29bb9f 100644 --- a/src/config.h +++ b/src/config.h @@ -149,6 +149,15 @@ namespace config { std::string fallback_mode; bool isolated_virtual_display_option; bool ignore_encoder_probe_failure; + + /** + * @brief Whether to use UDP segmentation offload (USO) when sending batched video packets on Windows. + * + * Some NIC drivers (notably VirtIO) accept the UDP_SEND_MSG_SIZE control message but silently + * drop the datagram instead of segmenting it, which results in no video ever reaching the client. + * Set to false to send video as regular MTU-sized packets instead. + */ + bool enable_uso = true; }; struct audio_t { diff --git a/src/platform/common.h b/src/platform/common.h index 2073d5937..bd00e5079 100644 --- a/src/platform/common.h +++ b/src/platform/common.h @@ -674,6 +674,14 @@ namespace platf { uint16_t target_port; boost::asio::ip::address &source_address; + /** + * @brief Whether to use UDP segmentation offload (USO) for the batch. + * + * Only supported on Windows and only meaningful when more than one message + * block is sent in a single call. + */ + bool enable_uso; + /** * @brief Returns a payload buffer descriptor for the given payload offset. * @param offset The offset in the total payload data (bytes). diff --git a/src/platform/windows/misc.cpp b/src/platform/windows/misc.cpp index ce07c7be9..c89f167e2 100644 --- a/src/platform/windows/misc.cpp +++ b/src/platform/windows/misc.cpp @@ -1491,7 +1491,10 @@ namespace platf { memcpy(WSA_CMSG_DATA(cm), &pktInfo, sizeof(pktInfo)); } - if (send_info.block_count > 1) { + // Only request USO when the user opted in. Some NIC drivers (notably VirtIO) accept the + // UDP_SEND_MSG_SIZE control message but silently drop the datagram instead of segmenting + // it, which breaks video streaming without any error being reported. + if (send_info.enable_uso && send_info.block_count > 1) { cmbuflen += WSA_CMSG_SPACE(sizeof(DWORD)); cm = WSA_CMSG_NXTHDR(&msg, cm); diff --git a/src/stream.cpp b/src/stream.cpp index bceeb93d3..68d9a7904 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -1519,6 +1519,7 @@ namespace stream { peer_address, session->video.peer.port(), session->localAddress, + config::video.enable_uso, }; size_t next_shard_to_send = 0; diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index 1c638b6fa..446119291 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -213,6 +213,7 @@

{{ $t('config.configuration') }}

"max_bitrate": 0, "minimum_fps_target": 0, "isolated_virtual_display_option": "disabled", + "enable_uso": "enabled", }, }, {