Index: content/browser/media/capture/desktop_capture_device.cc |
diff --git a/content/browser/media/capture/desktop_capture_device.cc b/content/browser/media/capture/desktop_capture_device.cc |
index 415096a0abc6b9d0a733a3390317de2625c49f8e..cab84407bf031ddb0fd4273eb44d17ec4ff17fba 100644 |
--- a/content/browser/media/capture/desktop_capture_device.cc |
+++ b/content/browser/media/capture/desktop_capture_device.cc |
@@ -75,9 +75,10 @@ class DesktopCaptureDevice::Core : public webrtc::DesktopCapturer::Callback { |
void SetNotificationWindowId(gfx::NativeViewId window_id); |
private: |
- |
- // webrtc::DesktopCapturer::Callback interface |
- void OnCaptureCompleted(webrtc::DesktopFrame* frame) override; |
+ // webrtc::DesktopCapturer::Callback interface. |
+ void OnCaptureResult( |
+ webrtc::DesktopCapturer::Result result, |
+ std::unique_ptr<webrtc::DesktopFrame> frame) override; |
// Method that is scheduled on |task_runner_| to be called on regular interval |
// to capture a frame. |
@@ -190,28 +191,33 @@ void DesktopCaptureDevice::Core::SetNotificationWindowId( |
desktop_capturer_->SetExcludedWindow(window_id); |
} |
-void DesktopCaptureDevice::Core::OnCaptureCompleted( |
- webrtc::DesktopFrame* frame) { |
+void DesktopCaptureDevice::Core::OnCaptureResult( |
+ webrtc::DesktopCapturer::Result result, |
+ std::unique_ptr<webrtc::DesktopFrame> frame) { |
DCHECK(task_runner_->BelongsToCurrentThread()); |
DCHECK(capture_in_progress_); |
+ capture_in_progress_ = false; |
+ |
+ bool success = result == webrtc::DesktopCapturer::Result::SUCCESS; |
+ |
if (!first_capture_returned_) { |
first_capture_returned_ = true; |
if (capturer_type_ == DesktopMediaID::TYPE_SCREEN) { |
- IncrementDesktopCaptureCounter(frame ? FIRST_SCREEN_CAPTURE_SUCCEEDED |
- : FIRST_SCREEN_CAPTURE_FAILED); |
+ IncrementDesktopCaptureCounter(success ? FIRST_SCREEN_CAPTURE_SUCCEEDED |
+ : FIRST_SCREEN_CAPTURE_FAILED); |
} else { |
- IncrementDesktopCaptureCounter(frame ? FIRST_WINDOW_CAPTURE_SUCCEEDED |
- : FIRST_WINDOW_CAPTURE_FAILED); |
+ IncrementDesktopCaptureCounter(success ? FIRST_WINDOW_CAPTURE_SUCCEEDED |
+ : FIRST_WINDOW_CAPTURE_FAILED); |
} |
} |
- capture_in_progress_ = false; |
- |
- if (!frame) { |
- client_->OnError(FROM_HERE, "Failed to capture a frame."); |
+ if (!success) { |
+ if (result == webrtc::DesktopCapturer::Result::ERROR_PERMANENT) |
+ client_->OnError(FROM_HERE, "The desktop capturer has failed."); |
return; |
} |
+ DCHECK(frame); |
if (!client_) |
return; |
@@ -227,8 +233,6 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted( |
UMA_HISTOGRAM_TIMES(kUmaWindowCaptureTime, capture_time); |
} |
- std::unique_ptr<webrtc::DesktopFrame> owned_frame(frame); |
- |
// If the frame size has changed, drop the output frame (if any), and |
// determine the new output size. |
if (!previous_frame_size_.equals(frame->size())) { |
@@ -245,6 +249,8 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted( |
if (output_size.is_empty()) |
return; |
+ webrtc::DesktopFrame* frame_ptr = frame.get(); |
+ |
// On OSX We receive a 1x1 frame when the shared window is minimized. It |
// cannot be subsampled to I420 and will be dropped downstream. So we replace |
// it with a black frame to avoid the video appearing frozen at the last |
@@ -252,19 +258,17 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted( |
if (frame->size().width() == 1 || frame->size().height() == 1) { |
if (!black_frame_) { |
black_frame_.reset(new webrtc::BasicDesktopFrame(output_size)); |
- memset(black_frame_->data(), |
- 0, |
+ memset(black_frame_->data(), 0, |
black_frame_->stride() * black_frame_->size().height()); |
} |
- owned_frame.reset(); |
- frame = black_frame_.get(); |
+ frame_ptr = black_frame_.get(); |
} |
size_t output_bytes = output_size.width() * output_size.height() * |
webrtc::DesktopFrame::kBytesPerPixel; |
const uint8_t* output_data = NULL; |
- if (!frame->size().equals(output_size)) { |
+ if (!frame_ptr->size().equals(output_size)) { |
// Down-scale and/or letterbox to the target format if the frame does not |
// match the output size. |
@@ -280,17 +284,16 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted( |
// TODO(wez): Optimize this to scale only changed portions of the output, |
// using ARGBScaleClip(). |
const webrtc::DesktopRect output_rect = |
- ComputeLetterboxRect(output_size, frame->size()); |
- uint8_t* output_rect_data = output_frame_->data() + |
- output_frame_->stride() * output_rect.top() + |
- webrtc::DesktopFrame::kBytesPerPixel * output_rect.left(); |
- libyuv::ARGBScale(frame->data(), frame->stride(), |
- frame->size().width(), frame->size().height(), |
+ ComputeLetterboxRect(output_size, frame_ptr->size()); |
+ uint8_t* output_rect_data = |
+ output_frame_->GetFrameDataAtPos(output_rect.top_left()); |
+ libyuv::ARGBScale(frame_ptr->data(), frame_ptr->stride(), |
+ frame_ptr->size().width(), frame_ptr->size().height(), |
output_rect_data, output_frame_->stride(), |
output_rect.width(), output_rect.height(), |
libyuv::kFilterBilinear); |
output_data = output_frame_->data(); |
- } else if (IsFrameUnpackedOrInverted(frame)) { |
+ } else if (IsFrameUnpackedOrInverted(frame_ptr)) { |
// If |frame| is not packed top-to-bottom then create a packed top-to-bottom |
// copy. |
// This is required if the frame is inverted (see crbug.com/306876), or if |
@@ -301,14 +304,13 @@ void DesktopCaptureDevice::Core::OnCaptureCompleted( |
} |
output_frame_->CopyPixelsFrom( |
- *frame, |
- webrtc::DesktopVector(), |
- webrtc::DesktopRect::MakeSize(frame->size())); |
+ *frame, webrtc::DesktopVector(), |
+ webrtc::DesktopRect::MakeSize(frame_ptr->size())); |
output_data = output_frame_->data(); |
} else { |
// If the captured frame matches the output size, we can return the pixel |
// data directly. |
- output_data = frame->data(); |
+ output_data = frame_ptr->data(); |
} |
base::TimeTicks now = base::TimeTicks::Now(); |