Index: content/browser/devtools/protocol/page_handler.cc |
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc |
index c4aac86bb98135ded08b06918c24c75a53e25e93..a14415631b5299188cf89a88d1899e79a9f6e2e9 100644 |
--- a/content/browser/devtools/protocol/page_handler.cc |
+++ b/content/browser/devtools/protocol/page_handler.cc |
@@ -96,11 +96,12 @@ PageHandler::PageHandler() |
screencast_quality_(kDefaultScreenshotQuality), |
screencast_max_width_(-1), |
screencast_max_height_(-1), |
+ capture_every_nth_frame_(1), |
capture_retry_count_(0), |
has_compositor_frame_metadata_(false), |
- screencast_frame_sent_(0), |
- screencast_frame_acked_(0), |
- processing_screencast_frame_(false), |
+ session_id_(0), |
+ frame_counter_(0), |
+ frames_in_flight_(0), |
color_picker_(new ColorPicker(base::Bind( |
&PageHandler::OnColorPicked, base::Unretained(this)))), |
host_(nullptr), |
@@ -288,7 +289,8 @@ Response PageHandler::CanScreencast(bool* result) { |
Response PageHandler::StartScreencast(const std::string* format, |
const int* quality, |
const int* max_width, |
- const int* max_height) { |
+ const int* max_height, |
+ const int* every_nth_frame) { |
RenderWidgetHostImpl* widget_host = |
host_ ? host_->GetRenderWidgetHost() : nullptr; |
if (!widget_host) |
@@ -301,6 +303,10 @@ Response PageHandler::StartScreencast(const std::string* format, |
screencast_quality_ = kDefaultScreenshotQuality; |
screencast_max_width_ = max_width ? *max_width : -1; |
screencast_max_height_ = max_height ? *max_height : -1; |
+ ++session_id_; |
+ frame_counter_ = 0; |
+ frames_in_flight_ = 0; |
+ capture_every_nth_frame_ = every_nth_frame ? *every_nth_frame : 1; |
bool visible = !widget_host->is_hidden(); |
NotifyScreencastVisibility(visible); |
@@ -320,8 +326,9 @@ Response PageHandler::StopScreencast() { |
return Response::FallThrough(); |
} |
-Response PageHandler::ScreencastFrameAck(int frame_number) { |
- screencast_frame_acked_ = frame_number; |
+Response PageHandler::ScreencastFrameAck(int session_id) { |
+ if (session_id == session_id_) |
+ --frames_in_flight_; |
return Response::OK(); |
} |
@@ -372,12 +379,13 @@ void PageHandler::NotifyScreencastVisibility(bool visible) { |
} |
void PageHandler::InnerSwapCompositorFrame() { |
- if (screencast_frame_sent_ - screencast_frame_acked_ > |
- kMaxScreencastFramesInFlight || processing_screencast_frame_) { |
+ if (!host_ || !host_->GetView()) |
return; |
- } |
- if (!host_ || !host_->GetView()) |
+ if (frames_in_flight_ > kMaxScreencastFramesInFlight) |
+ return; |
+ |
+ if (++frame_counter_ % capture_every_nth_frame_) |
return; |
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
@@ -412,7 +420,6 @@ void PageHandler::InnerSwapCompositorFrame() { |
gfx::ScaleSize(viewport_size_dip, scale))); |
if (snapshot_size_dip.width() > 0 && snapshot_size_dip.height() > 0) { |
- processing_screencast_frame_ = true; |
gfx::Rect viewport_bounds_dip(gfx::ToRoundedSize(viewport_size_dip)); |
view->CopyFromCompositingSurface( |
viewport_bounds_dip, |
@@ -421,6 +428,7 @@ void PageHandler::InnerSwapCompositorFrame() { |
weak_factory_.GetWeakPtr(), |
last_compositor_frame_metadata_), |
kN32_SkColorType); |
+ frames_in_flight_++; |
} |
} |
@@ -429,7 +437,6 @@ void PageHandler::ScreencastFrameCaptured( |
const SkBitmap& bitmap, |
ReadbackResponse response) { |
if (response != READBACK_SUCCESS) { |
- processing_screencast_frame_ = false; |
if (capture_retry_count_) { |
--capture_retry_count_; |
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
@@ -437,6 +444,7 @@ void PageHandler::ScreencastFrameCaptured( |
weak_factory_.GetWeakPtr()), |
base::TimeDelta::FromMilliseconds(kFrameRetryDelayMs)); |
} |
+ --frames_in_flight_; |
return; |
} |
base::PostTaskAndReplyWithResult( |
@@ -452,16 +460,18 @@ void PageHandler::ScreencastFrameEncoded( |
const cc::CompositorFrameMetadata& metadata, |
const base::Time& timestamp, |
const std::string& data) { |
- processing_screencast_frame_ = false; |
- |
// Consider metadata empty in case it has no device scale factor. |
- if (metadata.device_scale_factor == 0 || !host_ || data.empty()) |
+ if (metadata.device_scale_factor == 0 || !host_ || data.empty()) { |
+ --frames_in_flight_; |
return; |
+ } |
RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
host_->GetView()); |
- if (!view) |
+ if (!view) { |
+ --frames_in_flight_; |
return; |
+ } |
gfx::SizeF screen_size_dip = |
gfx::ScaleSize(gfx::SizeF(view->GetPhysicalBackingSize()), |
@@ -478,7 +488,7 @@ void PageHandler::ScreencastFrameEncoded( |
client_->ScreencastFrame(ScreencastFrameParams::Create() |
->set_data(data) |
->set_metadata(param_metadata) |
- ->set_frame_number(++screencast_frame_sent_)); |
+ ->set_session_id(session_id_)); |
} |
void PageHandler::ScreenshotCaptured(DevToolsCommandId command_id, |