From b2375659f916839a6bd403442adace707f378388 Mon Sep 17 00:00:00 2001 From: CloudWebRTC Date: Thu, 18 Aug 2022 18:59:07 +0800 Subject: [PATCH] fix: Get thumbnails asynchronously. (#37) * fix: Get thumbnails asynchronously. * Fixed the problem that only the mouse movement was captured and the background was not updated when capturing full screen on mac. --- .../mac/screen_capturer_mac.mm | 11 +--- sdk/objc/native/src/objc_desktop_capture.mm | 29 ++++++--- .../native/src/objc_desktop_media_list.mm | 59 ++++++++++++------- 3 files changed, 58 insertions(+), 41 deletions(-) diff --git a/modules/desktop_capture/mac/screen_capturer_mac.mm b/modules/desktop_capture/mac/screen_capturer_mac.mm index 634849122e..e2a51d0bd7 100644 --- a/modules/desktop_capture/mac/screen_capturer_mac.mm +++ b/modules/desktop_capture/mac/screen_capturer_mac.mm @@ -216,16 +216,7 @@ DesktopRect GetExcludedWindowPixelBounds(CGWindowID window, float dip_to_pixel_s ScreenConfigurationChanged(); } - // When screen is zoomed in/out, OSX only updates the part of Rects currently - // displayed on screen, with relative location to current top-left on screen. - // This will cause problems when we copy the dirty regions to the captured - // image. So we invalidate the whole screen to copy all the screen contents. - // With CGI method, the zooming will be ignored and the whole screen contents - // will be captured as before. - // With IOSurface method, the zoomed screen contents will be captured. - if (UAZoomEnabled()) { - helper_.InvalidateScreen(screen_pixel_bounds_.size()); - } + helper_.InvalidateScreen(screen_pixel_bounds_.size()); DesktopRegion region; helper_.TakeInvalidRegion(®ion); diff --git a/sdk/objc/native/src/objc_desktop_capture.mm b/sdk/objc/native/src/objc_desktop_capture.mm index bc6c6c9c6f..9a69d31804 100644 --- a/sdk/objc/native/src/objc_desktop_capture.mm +++ b/sdk/objc/native/src/objc_desktop_capture.mm @@ -28,19 +28,25 @@ webrtc::DesktopCapturer::SourceId source_id, id delegate) : thread_(rtc::Thread::Create()), source_id_(source_id), delegate_(delegate) { + RTC_DCHECK(thread_); + type_ = type; + thread_->Start(); options_ = webrtc::DesktopCaptureOptions::CreateDefault(); options_.set_detect_updated_region(true); options_.set_allow_iosurface(true); - if (type == kScreen) { - capturer_ = std::make_unique(webrtc::DesktopCapturer::CreateScreenCapturer(options_), options_); - } - else { capturer_ = std::make_unique(webrtc::DesktopCapturer::CreateWindowCapturer(options_), options_); } - type_ = type; - thread_->Start(); + thread_->Invoke(RTC_FROM_HERE, [this, type] { + if (type == kScreen) { + capturer_ = std::make_unique(webrtc::DesktopCapturer::CreateScreenCapturer(options_), options_); + } else { + capturer_ = std::make_unique(webrtc::DesktopCapturer::CreateWindowCapturer(options_), options_); + } + }); } ObjCDesktopCapturer::~ObjCDesktopCapturer() { - thread_->Stop(); + thread_->Invoke(RTC_FROM_HERE, [this] { + capturer_.reset(); + }); } ObjCDesktopCapturer::CaptureState ObjCDesktopCapturer::Start(uint32_t fps) { @@ -69,9 +75,14 @@ } } - capturer_->Start(this); + thread_->Invoke(RTC_FROM_HERE, [this] { + capturer_->Start(this); + }); capture_state_ = CS_RUNNING; - CaptureFrame(); + thread_->PostTask(ToQueuedTask( + [this]{ + CaptureFrame(); + })); [delegate_ didSourceCaptureStart]; return capture_state_; } diff --git a/sdk/objc/native/src/objc_desktop_media_list.mm b/sdk/objc/native/src/objc_desktop_media_list.mm index 6800b748b5..6b5e6b5bba 100644 --- a/sdk/objc/native/src/objc_desktop_media_list.mm +++ b/sdk/objc/native/src/objc_desktop_media_list.mm @@ -36,21 +36,29 @@ ObjCDesktopMediaList::ObjCDesktopMediaList(DesktopType type, RTC_OBJC_TYPE(RTCDesktopMediaList)* objcMediaList) :thread_(rtc::Thread::Create()),objcMediaList_(objcMediaList),type_(type) { + RTC_DCHECK(thread_); + thread_->Start(); options_ = webrtc::DesktopCaptureOptions::CreateDefault(); options_.set_detect_updated_region(true); options_.set_allow_iosurface(true); - if (type == kScreen) { - capturer_ = webrtc::DesktopCapturer::CreateScreenCapturer(options_); - } else { - capturer_ = webrtc::DesktopCapturer::CreateWindowCapturer(options_); - } + callback_ = std::make_unique(); - thread_->Start(); - capturer_->Start(callback_.get()); + + thread_->Invoke(RTC_FROM_HERE, [this, type] { + if (type == kScreen) { + capturer_ = webrtc::DesktopCapturer::CreateScreenCapturer(options_); + } else { + capturer_ = webrtc::DesktopCapturer::CreateWindowCapturer(options_); + } + capturer_->Start(callback_.get()); + }); + } ObjCDesktopMediaList::~ObjCDesktopMediaList() { - thread_->Stop(); + thread_->Invoke(RTC_FROM_HERE, [this] { + capturer_.reset(); + }); } int32_t ObjCDesktopMediaList::UpdateSourceList(bool force_reload, bool get_thumbnail) { @@ -63,7 +71,10 @@ } webrtc::DesktopCapturer::SourceList new_sources; - capturer_->GetSourceList(&new_sources); + + thread_->Invoke(RTC_FROM_HERE, [this,&new_sources] { + capturer_->GetSourceList(&new_sources); + }); typedef std::set SourceSet; SourceSet new_source_set; @@ -91,8 +102,8 @@ if (old_source_set.find(new_sources[i].id) == old_source_set.end()) { MediaSource* source = new MediaSource(this, new_sources[i],type_); sources_.insert(sources_.begin() + i, std::shared_ptr(source)); - GetThumbnail(source, false); [objcMediaList_ mediaSourceAdded:source]; + GetThumbnail(source, true); } } } @@ -135,19 +146,23 @@ } bool ObjCDesktopMediaList::GetThumbnail(MediaSource *source, bool notify) { - callback_->SetCallback([&](webrtc::DesktopCapturer::Result result, + + thread_->PostTask(ToQueuedTask( + [this, source, notify] { + if(capturer_->SelectSource(source->id())){ + callback_->SetCallback([&](webrtc::DesktopCapturer::Result result, std::unique_ptr frame) { - auto old_thumbnail = source->thumbnail(); - source->SaveCaptureResult(result, std::move(frame)); - if(old_thumbnail.size() != source->thumbnail().size() && notify) { - [objcMediaList_ mediaSourceThumbnailChanged:source]; - } - }); - if(capturer_->SelectSource(source->id())){ - capturer_->CaptureFrame(); - return true; - } - return false; + auto old_thumbnail = source->thumbnail(); + source->SaveCaptureResult(result, std::move(frame)); + if(old_thumbnail.size() != source->thumbnail().size() && notify) { + [objcMediaList_ mediaSourceThumbnailChanged:source]; + } + }); + capturer_->CaptureFrame(); + } + })); + + return true; } int ObjCDesktopMediaList::GetSourceCount() const {