Bug 1966238 - Cherry-pick upstream libwebrtc commit 83bd277b28 r=pehrsons,webrtc-reviewers

Upstream commit: https://webrtc.googlesource.com/src/+/83bd277b28d70213cc0c8b4a9c42cc8c46417711
       To ScreenCapturerSck add more elaborate logging

       This commit adds the capturer's `this` pointer address as an identifier
       to existing logging statements, and adds several others.

       Bug: webrtc:367915807
       Change-Id: I6daa404cd2ed20f0d50fd66eb6e066779c18df7a
       Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/365086
       Commit-Queue: Andreas Pehrson <apehrson@mozilla.com>
       Reviewed-by: Alexander Cooper <alcooper@chromium.org>
       Cr-Commit-Position: refs/heads/main@{#44209}

Differential Revision: https://phabricator.services.mozilla.com/D249155
This commit is contained in:
Michael Froman
2025-05-16 17:25:50 +00:00
committed by mfroman@mozilla.com
parent 5e5a1edeb9
commit 5fa01a1373
2 changed files with 52 additions and 17 deletions

View File

@@ -37,7 +37,8 @@ API_AVAILABLE(macos(14.0))
- (instancetype)initWithCapturer:(webrtc::ScreenCapturerSck*)capturer;
- (void)onShareableContentCreated:(SCShareableContent*)content;
- (void)onShareableContentCreated:(SCShareableContent*)content
error:(NSError*)error;
// Called just before the capturer is destroyed. This avoids a dangling pointer,
// and prevents any new calls into a deleted capturer. If any method-call on the
@@ -67,7 +68,7 @@ class API_AVAILABLE(macos(14.0)) ScreenCapturerSck final
// Called by SckHelper when shareable content is returned by ScreenCaptureKit.
// `content` will be nil if an error occurred. May run on an arbitrary thread.
void OnShareableContentCreated(SCShareableContent* content);
void OnShareableContentCreated(SCShareableContent* content, NSError* error);
// Called by SckHelper to notify of a newly captured frame. May run on an
// arbitrary thread.
@@ -132,15 +133,18 @@ class API_AVAILABLE(macos(14.0)) ScreenCapturerSck final
ScreenCapturerSck::ScreenCapturerSck(const DesktopCaptureOptions& options)
: capture_options_(options) {
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << this << " created";
helper_ = [[SckHelper alloc] initWithCapturer:this];
}
ScreenCapturerSck::~ScreenCapturerSck() {
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << this << " destroyed.";
[stream_ stopCaptureWithCompletionHandler:nil];
[helper_ releaseCapturer];
}
void ScreenCapturerSck::Start(DesktopCapturer::Callback* callback) {
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << this << " " << __func__ << ".";
callback_ = callback;
desktop_config_ =
capture_options_.configuration_monitor()->desktop_configuration();
@@ -155,6 +159,8 @@ void ScreenCapturerSck::CaptureFrame() {
int64_t capture_start_time_millis = rtc::TimeMillis();
if (permanent_error_) {
RTC_LOG(LS_VERBOSE) << "ScreenCapturerSck " << this
<< " CaptureFrame() -> ERROR_PERMANENT";
callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
return;
}
@@ -180,14 +186,20 @@ void ScreenCapturerSck::CaptureFrame() {
}
if (frame) {
RTC_LOG(LS_VERBOSE) << "ScreenCapturerSck " << this
<< " CaptureFrame() -> SUCCESS";
frame->set_capture_time_ms(rtc::TimeSince(capture_start_time_millis));
callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
} else {
RTC_LOG(LS_VERBOSE) << "ScreenCapturerSck " << this
<< " CaptureFrame() -> ERROR_TEMPORARY";
callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
}
}
bool ScreenCapturerSck::SelectSource(SourceId id) {
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << this << " SelectSource(id=" << id
<< ").";
bool stream_started = false;
{
MutexLock lock(&lock_);
@@ -207,20 +219,26 @@ bool ScreenCapturerSck::SelectSource(SourceId id) {
return true;
}
void ScreenCapturerSck::OnShareableContentCreated(SCShareableContent* content) {
void ScreenCapturerSck::OnShareableContentCreated(SCShareableContent* content,
NSError* error) {
if (!content) {
RTC_LOG(LS_ERROR) << "getShareableContent failed.";
RTC_LOG(LS_ERROR) << "ScreenCapturerSck " << this
<< " getShareableContent failed with error code "
<< (error ? error.code : 0) << ".";
permanent_error_ = true;
return;
}
if (!content.displays.count) {
RTC_LOG(LS_ERROR) << "getShareableContent returned no displays.";
RTC_LOG(LS_ERROR) << "ScreenCapturerSck " << this
<< " getShareableContent returned no displays.";
permanent_error_ = true;
return;
}
MutexLock lock(&lock_);
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << this << " " << __func__
<< ". current_display_=" << current_display_;
SCDisplay* captured_display;
for (SCDisplay* display in content.displays) {
if (current_display_ == display.displayID) {
@@ -231,11 +249,15 @@ void ScreenCapturerSck::OnShareableContentCreated(SCShareableContent* content) {
if (!captured_display) {
if (current_display_ ==
static_cast<CGDirectDisplayID>(kFullDesktopScreenId)) {
RTC_LOG(LS_WARNING) << "Full screen capture is not supported, falling "
"back to first display.";
RTC_LOG(LS_WARNING) << "ScreenCapturerSck " << this
<< " Full screen "
"capture is not supported, falling back to first "
"display.";
} else {
RTC_LOG(LS_WARNING) << "Display " << current_display_
<< " not found, falling back to first display.";
RTC_LOG(LS_WARNING) << "ScreenCapturerSck " << this << " Display "
<< current_display_
<< " not found, falling back to "
"first display.";
}
captured_display = content.displays.firstObject;
}
@@ -257,10 +279,13 @@ void ScreenCapturerSck::OnShareableContentCreated(SCShareableContent* content) {
}
if (stream_) {
RTC_LOG(LS_INFO) << "Updating stream configuration.";
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << this
<< " Updating stream configuration to size="
<< config.width << "x" << config.height << ".";
[stream_ updateContentFilter:filter completionHandler:nil];
[stream_ updateConfiguration:config completionHandler:nil];
} else {
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << this << " Creating new stream.";
stream_ = [[SCStream alloc] initWithFilter:filter
configuration:config
delegate:helper_];
@@ -275,7 +300,8 @@ void ScreenCapturerSck::OnShareableContentCreated(SCShareableContent* content) {
error:&add_stream_output_error];
if (!add_stream_output_result) {
stream_ = nil;
RTC_LOG(LS_ERROR) << "addStreamOutput failed.";
RTC_LOG(LS_ERROR) << "ScreenCapturerSck " << this
<< " addStreamOutput failed.";
permanent_error_ = true;
return;
}
@@ -286,9 +312,10 @@ void ScreenCapturerSck::OnShareableContentCreated(SCShareableContent* content) {
// calls stopCaptureWithCompletionHandler on the stream, which cancels
// this handler.
permanent_error_ = true;
RTC_LOG(LS_ERROR) << "startCaptureWithCompletionHandler failed.";
RTC_LOG(LS_ERROR) << "ScreenCapturerSck " << this
<< " Starting failed.";
} else {
RTC_LOG(LS_INFO) << "Capture started.";
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << this << " Capture started.";
}
};
@@ -298,6 +325,9 @@ void ScreenCapturerSck::OnShareableContentCreated(SCShareableContent* content) {
void ScreenCapturerSck::OnNewIOSurface(IOSurfaceRef io_surface,
CFDictionaryRef attachment) {
RTC_LOG(LS_VERBOSE) << "ScreenCapturerSck " << this << " " << __func__
<< " width=" << IOSurfaceGetWidth(io_surface)
<< ", height=" << IOSurfaceGetHeight(io_surface) << ".";
rtc::ScopedCFTypeRef<IOSurfaceRef> scoped_io_surface(
io_surface, rtc::RetainPolicy::RETAIN);
std::unique_ptr<DesktopFrameIOSurface> desktop_frame_io_surface =
@@ -362,12 +392,13 @@ void ScreenCapturerSck::OnNewIOSurface(IOSurfaceRef io_surface,
}
void ScreenCapturerSck::StartOrReconfigureCapturer() {
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << this << " " << __func__ << ".";
// The copy is needed to avoid capturing `this` in the Objective-C block.
// Accessing `helper_` inside the block is equivalent to `this->helper_` and
// would crash (UAF) if `this` is deleted before the block is executed.
SckHelper* local_helper = helper_;
auto handler = ^(SCShareableContent* content, NSError* /* error */) {
[local_helper onShareableContentCreated:content];
auto handler = ^(SCShareableContent* content, NSError* error) {
[local_helper onShareableContentCreated:content error:error];
};
[SCShareableContent getShareableContentWithCompletionHandler:handler];
@@ -408,10 +439,11 @@ std::unique_ptr<DesktopCapturer> CreateScreenCapturerSck(
return self;
}
- (void)onShareableContentCreated:(SCShareableContent*)content {
- (void)onShareableContentCreated:(SCShareableContent*)content
error:(NSError*)error {
webrtc::MutexLock lock(&_capturer_lock);
if (_capturer) {
_capturer->OnShareableContentCreated(content);
_capturer->OnShareableContentCreated(content, error);
}
}
@@ -446,6 +478,8 @@ std::unique_ptr<DesktopCapturer> CreateScreenCapturerSck(
- (void)releaseCapturer {
webrtc::MutexLock lock(&_capturer_lock);
RTC_LOG(LS_INFO) << "ScreenCapturerSck " << _capturer << " " << __func__
<< ".";
_capturer = nullptr;
}

View File

@@ -0,0 +1 @@
We cherry-picked this in bug 1966238