diff --git a/src/gui/features/devices/session_device_manager.cpp b/src/gui/features/devices/session_device_manager.cpp index 7d4fd34..752bf56 100644 --- a/src/gui/features/devices/session_device_manager.cpp +++ b/src/gui/features/devices/session_device_manager.cpp @@ -60,6 +60,26 @@ int SessionDeviceManager::InitializeScreenCapturer() { return; } + std::vector connected_remote_ids; + { + std::shared_lock lock(owner_.connection_status_mutex_); + connected_remote_ids.reserve(owner_.connection_status_.size()); + for (const auto &[remote_id, status] : owner_.connection_status_) { + if (status == ConnectionStatus::Connected) { + connected_remote_ids.push_back(remote_id); + } + } + } + + // Capture can still deliver frames while ICE is gathering or after + // the final controller disconnects. Do not broadcast those frames to + // MiniRTC: a broadcast also reaches newly joining peers whose ICE + // transport is not ready yet. + if (connected_remote_ids.empty()) { + last_frame_time_ = now_time; + return; + } + const std::string stream_id = display_name ? display_name : ""; const bool resumed_after_gap = last_frame_time_ != 0 && duration >= kCaptureResumeKeyFrameGapMs; @@ -79,7 +99,10 @@ int SessionDeviceManager::InitializeScreenCapturer() { frame.width = width; frame.height = height; frame.captured_timestamp = GetSystemTimeMicros(owner_.peer_); - SendVideoFrame(owner_.peer_, &frame, stream_id.c_str()); + for (const std::string &remote_id : connected_remote_ids) { + SendVideoFrameToPeer(owner_.peer_, &frame, stream_id.c_str(), + remote_id.data(), remote_id.size()); + } last_video_frame_stream_id_ = stream_id; last_frame_time_ = now_time; }); diff --git a/src/screen_capturer/macosx/screen_capturer_sck_impl.mm b/src/screen_capturer/macosx/screen_capturer_sck_impl.mm index 2758be0..4f0624f 100644 --- a/src/screen_capturer/macosx/screen_capturer_sck_impl.mm +++ b/src/screen_capturer/macosx/screen_capturer_sck_impl.mm @@ -335,7 +335,7 @@ int ScreenCapturerSckImpl::SwitchTo(int monitor_index) { } int ScreenCapturerSckImpl::ResetToInitialMonitor() { - int target = initial_monitor_index_; + const int target = initial_monitor_index_; if (display_info_list_.empty()) return -1; auto display_it = display_id_map_.find(target); if (display_it == display_id_map_.end()) { @@ -343,13 +343,20 @@ int ScreenCapturerSckImpl::ResetToInitialMonitor() { return -1; } - CGDirectDisplayID target_display = display_it->second; - if (current_display_ == target_display) return 0; + const CGDirectDisplayID target_display = display_it->second; + bool should_reconfigure = false; { std::lock_guard lock(lock_); + if (current_display_ == target_display) return 0; current_display_ = target_display; + should_reconfigure = stream_ != nil; + } + + // Resetting session state must not create a capture stream. Preserve the + // selected monitor for the next Start(), and only reconfigure an active one. + if (should_reconfigure) { + StartOrReconfigureCapturer(); } - StartOrReconfigureCapturer(); return 0; }