[feat] show video latency in DeskHub network status

This commit is contained in:
dijunkun
2026-10-14 04:17:38 +08:00
parent 61ff9b2787
commit 0a6356085d
7 changed files with 43 additions and 17 deletions
@@ -510,6 +510,11 @@ void GuiRuntime::ResetRemoteSessionResources(
std::shared_ptr<RemoteSession> props) {
props->net_traffic_stats_.Reset();
props->received_video_stats_.Reset();
{
std::lock_guard lock(props->gallery_frame_mutex_);
props->gallery_video_latency_->Reset();
props->gallery_frame_timing_ = {};
}
{
std::lock_guard<std::mutex> lock(props->video_frame_mutex_);
props->video_latency_->Reset();
@@ -331,6 +331,11 @@ void PeerEventHandler::OnConnectionStatus(ConnectionStatus status,
}
props->net_traffic_stats_.Reset();
props->received_video_stats_.Reset();
{
std::lock_guard lock(props->gallery_frame_mutex_);
props->gallery_video_latency_->Reset();
props->gallery_frame_timing_ = {};
}
props->traversal_mode_ = TraversalMode::UnknownMode;
props->enable_mouse_control_ = false;
props->preview_subscription_supported_ = false;
@@ -50,6 +50,8 @@ void PeerEventHandler::OnReceiveVideoBuffer(
if (props->connection_established_) {
const auto timing_now = VideoLatencyFrame::Clock::now();
// Pair the clocks before preview conversion so its cost is included.
const auto local_now_us = GetSystemTimeMicros(props->peer_);
const auto* received_native = GetNativeVideoFrame(video_frame);
props->received_video_stats_.Record(
received_native ? received_native->width : video_frame->width,
@@ -65,6 +67,8 @@ void PeerEventHandler::OnReceiveVideoBuffer(
std::defer_lock);
if (preview_width > 0) conversion_lock.lock();
if (conversion_lock.owns_lock()) {
const auto gallery_timing = props->gallery_video_latency_->Frame(
video_frame->captured_timestamp, local_now_us, timing_now);
const auto* native = GetNativeVideoFrame(video_frame);
const int w = native ? native->width : video_frame->width;
const int h = native ? native->height : video_frame->height;
@@ -100,6 +104,7 @@ void PeerEventHandler::OnReceiveVideoBuffer(
props->gallery_width_ = dw;
props->gallery_height_ = dh;
props->gallery_frame_at_ = timing_now;
props->gallery_frame_timing_ = gallery_timing;
++props->gallery_sequence_;
}
}
@@ -118,8 +123,7 @@ void PeerEventHandler::OnReceiveVideoBuffer(
return;
}
const auto timing = props->video_latency_->Frame(
video_frame->captured_timestamp, GetSystemTimeMicros(props->peer_),
timing_now);
video_frame->captured_timestamp, local_now_us, timing_now);
bool background_snapshot_only = false;
auto* native_renderer = runtime->video_renderer_.get();
if (native_renderer && native_renderer->IsActive()) {
@@ -95,6 +95,10 @@ struct RemoteSession {
int gallery_width_ = 0, gallery_height_ = 0;
uint64_t gallery_sequence_ = 0;
std::chrono::steady_clock::time_point gallery_frame_at_{};
VideoLatencyFrame gallery_frame_timing_;
// Keep preview submission estimates separate from stream presentation times.
std::shared_ptr<VideoLatencyStats> gallery_video_latency_ =
std::make_shared<VideoLatencyStats>();
// Decoder-thread scratch memory, never shared with the UI.
std::mutex gallery_conversion_mutex_;
std::vector<unsigned char> gallery_nv12_, gallery_scaled_, gallery_scratch_;