118 lines
4.2 KiB
Diff
118 lines
4.2 KiB
Diff
|
diff --git a/modules/desktop_capture/mac/screen_capturer_mac.mm b/modules/desktop_capture/mac/screen_capturer_mac.mm
|
||
|
index df18777226..6a1e3da6ab 100644
|
||
|
--- a/modules/desktop_capture/mac/screen_capturer_mac.mm
|
||
|
+++ b/modules/desktop_capture/mac/screen_capturer_mac.mm
|
||
|
@@ -16,6 +16,7 @@
|
||
|
#include "rtc_base/checks.h"
|
||
|
#include "rtc_base/constructormagic.h"
|
||
|
#include "rtc_base/logging.h"
|
||
|
+#include "rtc_base/synchronization/rw_lock_wrapper.h"
|
||
|
#include "rtc_base/timeutils.h"
|
||
|
#include "sdk/objc/Framework/Classes/Common/scoped_cftyperef.h"
|
||
|
|
||
|
@@ -28,18 +29,31 @@ namespace webrtc {
|
||
|
// destroy itself once it's done.
|
||
|
class DisplayStreamManager {
|
||
|
public:
|
||
|
- int GetUniqueId() { return ++unique_id_generator_; }
|
||
|
- void DestroyStream(int unique_id) {
|
||
|
- auto it = display_stream_wrappers_.find(unique_id);
|
||
|
- RTC_CHECK(it != display_stream_wrappers_.end());
|
||
|
- RTC_CHECK(!it->second.active);
|
||
|
- CFRelease(it->second.stream);
|
||
|
- display_stream_wrappers_.erase(it);
|
||
|
+ DisplayStreamManager() : rw_lock_(RWLockWrapper::CreateRWLock()) {}
|
||
|
+ RWLockWrapper* GetLock() {return rw_lock_.get();};
|
||
|
|
||
|
- if (ready_for_self_destruction_ && display_stream_wrappers_.empty()) delete this;
|
||
|
+ int GetUniqueId() {
|
||
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
||
|
+ return ++unique_id_generator_;
|
||
|
+ }
|
||
|
+ void DestroyStream(int unique_id) {
|
||
|
+ bool finalize;
|
||
|
+ {
|
||
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
||
|
+ auto it = display_stream_wrappers_.find(unique_id);
|
||
|
+ RTC_CHECK(it != display_stream_wrappers_.end());
|
||
|
+ RTC_CHECK(!it->second.active);
|
||
|
+ CFRelease(it->second.stream);
|
||
|
+ display_stream_wrappers_.erase(it);
|
||
|
+ finalize = ready_for_self_destruction_ && display_stream_wrappers_.empty();
|
||
|
+ }
|
||
|
+ if (finalize) {
|
||
|
+ delete this;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
void SaveStream(int unique_id, CGDisplayStreamRef stream) {
|
||
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
||
|
RTC_CHECK(unique_id <= unique_id_generator_);
|
||
|
DisplayStreamWrapper wrapper;
|
||
|
wrapper.stream = stream;
|
||
|
@@ -47,6 +61,7 @@ class DisplayStreamManager {
|
||
|
}
|
||
|
|
||
|
void UnregisterActiveStreams() {
|
||
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
||
|
for (auto& pair : display_stream_wrappers_) {
|
||
|
DisplayStreamWrapper& wrapper = pair.second;
|
||
|
if (wrapper.active) {
|
||
|
@@ -61,12 +76,23 @@ class DisplayStreamManager {
|
||
|
void PrepareForSelfDestruction() {
|
||
|
ready_for_self_destruction_ = true;
|
||
|
|
||
|
- if (display_stream_wrappers_.empty()) delete this;
|
||
|
+ bool finalize;
|
||
|
+ {
|
||
|
+ WriteLockScoped scoped_display_stream_manager_lock(*rw_lock_);
|
||
|
+ ready_for_self_destruction_ = true;
|
||
|
+ finalize = display_stream_wrappers_.empty();
|
||
|
+ }
|
||
|
+ if (finalize) {
|
||
|
+ delete this;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
// Once the DisplayStreamManager is ready for destruction, the
|
||
|
// ScreenCapturerMac is no longer present. Any updates should be ignored.
|
||
|
- bool ShouldIgnoreUpdates() { return ready_for_self_destruction_; }
|
||
|
+ // Note: not thread-safe! Acquire and release a lock manually.
|
||
|
+ bool ShouldIgnoreUpdates() {
|
||
|
+ return ready_for_self_destruction_;
|
||
|
+ }
|
||
|
|
||
|
private:
|
||
|
struct DisplayStreamWrapper {
|
||
|
@@ -81,6 +107,7 @@ class DisplayStreamManager {
|
||
|
std::map<int, DisplayStreamWrapper> display_stream_wrappers_;
|
||
|
int unique_id_generator_ = 0;
|
||
|
bool ready_for_self_destruction_ = false;
|
||
|
+ std::unique_ptr<RWLockWrapper> rw_lock_;
|
||
|
};
|
||
|
|
||
|
namespace {
|
||
|
@@ -507,8 +534,6 @@ bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- if (manager->ShouldIgnoreUpdates()) return;
|
||
|
-
|
||
|
// Only pay attention to frame updates.
|
||
|
if (status != kCGDisplayStreamFrameStatusFrameComplete) return;
|
||
|
|
||
|
@@ -518,7 +543,12 @@ bool ScreenCapturerMac::RegisterRefreshAndMoveHandlers() {
|
||
|
if (count != 0) {
|
||
|
// According to CGDisplayStream.h, it's safe to call
|
||
|
// CGDisplayStreamStop() from within the callback.
|
||
|
- ScreenRefresh(count, rects, display_origin);
|
||
|
+ manager->GetLock()->AcquireLockShared();
|
||
|
+ bool screen_capturer_mac_invalidated = manager->ShouldIgnoreUpdates();
|
||
|
+ if (!screen_capturer_mac_invalidated) {
|
||
|
+ ScreenRefresh(count, rects, display_origin);
|
||
|
+ }
|
||
|
+ manager->GetLock()->ReleaseLockShared();
|
||
|
}
|
||
|
};
|
||
|
|