Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: content/browser/devtools/protocol/frame_recorder.cc

Issue 888573002: DevTools: FrameRecorder: add cancelRecordingFrames command (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/devtools/protocol/frame_recorder.h" 5 #include "content/browser/devtools/protocol/frame_recorder.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/task_runner_util.h" 10 #include "base/task_runner_util.h"
11 #include "base/threading/worker_pool.h" 11 #include "base/threading/worker_pool.h"
12 #include "content/browser/renderer_host/render_view_host_impl.h" 12 #include "content/browser/renderer_host/render_view_host_impl.h"
13 #include "content/browser/renderer_host/render_widget_host_view_base.h" 13 #include "content/browser/renderer_host/render_widget_host_view_base.h"
14 #include "third_party/skia/include/core/SkBitmap.h" 14 #include "third_party/skia/include/core/SkBitmap.h"
15 #include "ui/gfx/codec/png_codec.h" 15 #include "ui/gfx/codec/png_codec.h"
16 #include "ui/gfx/geometry/size.h" 16 #include "ui/gfx/geometry/size.h"
17 17
18 namespace content { 18 namespace content {
19 namespace devtools { 19 namespace devtools {
20 namespace page { 20 namespace page {
21 21
22 namespace { 22 namespace {
23 23
24 static int kMaxRecordFrameCount = 180; 24 static int kMaxRecordFrameCount = 180;
25 25
26 std::string EncodeFrame(const SkBitmap& bitmap) { 26 scoped_ptr<EncodedFrame> EncodeFrame(
27 const SkBitmap& bitmap, double timestamp) {
27 std::vector<unsigned char> data; 28 std::vector<unsigned char> data;
28 SkAutoLockPixels lock_image(bitmap); 29 SkAutoLockPixels lock_image(bitmap);
29 bool encoded = gfx::PNGCodec::Encode( 30 bool encoded = gfx::PNGCodec::Encode(
30 reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)), 31 reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
31 gfx::PNGCodec::FORMAT_SkBitmap, 32 gfx::PNGCodec::FORMAT_SkBitmap,
32 gfx::Size(bitmap.width(), bitmap.height()), 33 gfx::Size(bitmap.width(), bitmap.height()),
33 bitmap.width() * bitmap.bytesPerPixel(), 34 bitmap.width() * bitmap.bytesPerPixel(),
34 false, std::vector<gfx::PNGCodec::Comment>(), &data); 35 false, std::vector<gfx::PNGCodec::Comment>(), &data);
35 36
37 scoped_ptr<EncodedFrame> result(new EncodedFrame(std::string(), timestamp));
38
36 if (!encoded) 39 if (!encoded)
37 return std::string(); 40 return result.Pass();
38 41
39 std::string base_64_data; 42 std::string base_64_data;
40 base::Base64Encode( 43 base::Base64Encode(
41 base::StringPiece(reinterpret_cast<char*>(&data[0]), data.size()), 44 base::StringPiece(reinterpret_cast<char*>(&data[0]), data.size()),
42 &base_64_data); 45 &result->first);
43 46
44 return base_64_data; 47 return result.Pass();
45 } 48 }
46 } // namespace 49 } // namespace
47 50
48 typedef DevToolsProtocolClient::Response Response; 51 typedef DevToolsProtocolClient::Response Response;
49 52
50 FrameRecorder::FrameRecorder() 53 FrameRecorder::FrameRecorder()
51 : host_(nullptr), 54 : host_(nullptr),
52 state_(Ready), 55 state_(Ready),
53 inflight_requests_count_(0), 56 inflight_requests_count_(0),
54 max_frame_count_(0), 57 max_frame_count_(0),
(...skipping 10 matching lines...) Expand all
65 } 68 }
66 69
67 Response FrameRecorder::StartRecordingFrames(int max_frame_count) { 70 Response FrameRecorder::StartRecordingFrames(int max_frame_count) {
68 if (max_frame_count <= 0 || max_frame_count > kMaxRecordFrameCount) 71 if (max_frame_count <= 0 || max_frame_count > kMaxRecordFrameCount)
69 return Response::InvalidParams("maxFrameCount"); 72 return Response::InvalidParams("maxFrameCount");
70 if (state_ != Ready) 73 if (state_ != Ready)
71 return Response::InternalError("Already recording"); 74 return Response::InternalError("Already recording");
72 state_ = Recording; 75 state_ = Recording;
73 max_frame_count_ = max_frame_count; 76 max_frame_count_ = max_frame_count;
74 captured_frames_count_ = 0; 77 captured_frames_count_ = 0;
78 frame_encoded_callback_.Reset(base::Bind(
79 &FrameRecorder::FrameEncoded, weak_factory_.GetWeakPtr()));
75 last_captured_frame_timestamp_ = base::Time(); 80 last_captured_frame_timestamp_ = base::Time();
76 std::vector<scoped_refptr<devtools::page::RecordedFrame>> frames; 81 std::vector<scoped_refptr<devtools::page::RecordedFrame>> frames;
77 frames.reserve(max_frame_count); 82 frames.reserve(max_frame_count);
78 frames_.swap(frames); 83 frames_.swap(frames);
79 84
80 return Response::OK(); 85 return Response::OK();
81 } 86 }
82 87
83 Response FrameRecorder::StopRecordingFrames( 88 Response FrameRecorder::StopRecordingFrames(
84 StopRecordingFramesCallback callback) { 89 StopRecordingFramesCallback callback) {
85 if (state_ != Recording) 90 if (state_ != Recording)
86 return Response::InternalError("Not recording"); 91 return Response::InternalError("Not recording");
87 state_ = Encoding; 92 state_ = Encoding;
88 callback_ = callback; 93 callback_ = callback;
89 MaybeSendResponse(); 94 MaybeSendResponse();
90 return Response::OK(); 95 return Response::OK();
91 } 96 }
92 97
98 Response FrameRecorder::CancelRecordingFrames() {
99 frame_encoded_callback_.Cancel();
100 std::vector<scoped_refptr<devtools::page::RecordedFrame>> no_frames;
101 frames_.swap(no_frames);
102 if (state_ == Encoding)
103 callback_.Run(StopRecordingFramesResponse::Create()->set_frames(frames_));
104 state_ = Ready;
105 return Response::OK();
106 }
107
93 void FrameRecorder::OnSwapCompositorFrame() { 108 void FrameRecorder::OnSwapCompositorFrame() {
94 if (!host_ || state_ != Recording) 109 if (!host_ || state_ != Recording)
95 return; 110 return;
96 if (captured_frames_count_ >= max_frame_count_) 111 if (captured_frames_count_ >= max_frame_count_)
97 return; 112 return;
98 RenderWidgetHostViewBase* view = 113 RenderWidgetHostViewBase* view =
99 static_cast<RenderWidgetHostViewBase*>(host_->GetView()); 114 static_cast<RenderWidgetHostViewBase*>(host_->GetView());
100 if (!view) 115 if (!view)
101 return; 116 return;
102 117
103 inflight_requests_count_++; 118 inflight_requests_count_++;
104 view->CopyFromCompositingSurface( 119 view->CopyFromCompositingSurface(
105 gfx::Rect(), 120 gfx::Rect(),
106 gfx::Size(), 121 gfx::Size(),
107 base::Bind(&FrameRecorder::FrameCaptured, weak_factory_.GetWeakPtr()), 122 base::Bind(&FrameRecorder::FrameCaptured, weak_factory_.GetWeakPtr()),
108 kN32_SkColorType); 123 kN32_SkColorType);
109 } 124 }
110 125
111 void FrameRecorder::FrameCaptured( 126 void FrameRecorder::FrameCaptured(
112 const SkBitmap& bitmap, ReadbackResponse response) { 127 const SkBitmap& bitmap, ReadbackResponse response) {
113 inflight_requests_count_--; 128 inflight_requests_count_--;
114 base::Time timestamp = last_captured_frame_timestamp_; 129 base::Time timestamp = last_captured_frame_timestamp_;
115 last_captured_frame_timestamp_ = base::Time::Now(); 130 last_captured_frame_timestamp_ = base::Time::Now();
116 if (timestamp.is_null() || response != READBACK_SUCCESS) 131 if (timestamp.is_null() || response != READBACK_SUCCESS) {
132 MaybeSendResponse();
117 return; 133 return;
134 }
118 135
119 captured_frames_count_++; 136 captured_frames_count_++;
120 base::PostTaskAndReplyWithResult( 137 base::PostTaskAndReplyWithResult(
121 base::WorkerPool::GetTaskRunner(true).get(), 138 base::WorkerPool::GetTaskRunner(true).get(),
122 FROM_HERE, 139 FROM_HERE,
123 base::Bind(&EncodeFrame, bitmap), 140 base::Bind(&EncodeFrame, bitmap, timestamp.ToDoubleT()),
124 base::Bind(&FrameRecorder::FrameEncoded, weak_factory_.GetWeakPtr(), 141 frame_encoded_callback_.callback());
125 timestamp.ToDoubleT()));
126 } 142 }
127 143
128 void FrameRecorder::FrameEncoded( 144 void FrameRecorder::FrameEncoded(
129 double timestamp, const std::string& encoded_frame) { 145 const scoped_ptr<EncodedFrame>& encoded_frame) {
130 frames_.push_back(RecordedFrame::Create() 146 frames_.push_back(RecordedFrame::Create()
131 ->set_data(encoded_frame) 147 ->set_data(encoded_frame->first)
132 ->set_timestamp(timestamp)); 148 ->set_timestamp(encoded_frame->second));
133 MaybeSendResponse(); 149 MaybeSendResponse();
134 } 150 }
135 151
136 void FrameRecorder::MaybeSendResponse() { 152 void FrameRecorder::MaybeSendResponse() {
137 if (state_ != Encoding) 153 if (state_ != Encoding)
138 return; 154 return;
139 if (inflight_requests_count_ || frames_.size() != captured_frames_count_) 155 if (inflight_requests_count_ || frames_.size() != captured_frames_count_)
140 return; 156 return;
141 callback_.Run(StopRecordingFramesResponse::Create()->set_frames(frames_)); 157 callback_.Run(StopRecordingFramesResponse::Create()->set_frames(frames_));
142 std::vector<scoped_refptr<devtools::page::RecordedFrame>> frames; 158 std::vector<scoped_refptr<devtools::page::RecordedFrame>> frames;
143 frames_.swap(frames); 159 frames_.swap(frames);
144 state_ = Ready; 160 state_ = Ready;
145 } 161 }
146 162
147 } // namespace page 163 } // namespace page
148 } // namespace devtools 164 } // namespace devtools
149 } // namespace content 165 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/protocol/frame_recorder.h ('k') | content/browser/devtools/protocol/page_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698