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

Side by Side Diff: content/browser/media/capture/desktop_capture_device.cc

Issue 252393002: Adds UMA histograms for desktop capture device. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/media/capture/desktop_capture_device.h" 5 #include "content/browser/media/capture/desktop_capture_device.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/histogram.h"
10 #include "base/sequenced_task_runner.h" 11 #include "base/sequenced_task_runner.h"
11 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
12 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
13 #include "base/threading/sequenced_worker_pool.h" 14 #include "base/threading/sequenced_worker_pool.h"
14 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/desktop_media_id.h" 16 #include "content/public/browser/desktop_media_id.h"
16 #include "media/base/video_util.h" 17 #include "media/base/video_util.h"
17 #include "third_party/libyuv/include/libyuv/scale_argb.h" 18 #include "third_party/libyuv/include/libyuv/scale_argb.h"
18 #include "third_party/webrtc/modules/desktop_capture/desktop_and_cursor_composer .h" 19 #include "third_party/webrtc/modules/desktop_capture/desktop_and_cursor_composer .h"
19 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" 20 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
20 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" 21 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
21 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 22 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
22 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h" 23 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
23 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" 24 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
24 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h" 25 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
25 26
26 namespace content { 27 namespace content {
27 28
28 namespace { 29 namespace {
29 30
31 enum DesktopCaptureCounters {
32 SCREEN_CAPTURER_CREATED,
33 WINDOW_CATPTURER_CREATED,
34 FIRST_SCREEN_CAPTURE_SUCCEEDED,
35 FIRST_SCREEN_CAPTURE_FAILED,
36 FIRST_WINDOW_CAPTURE_SUCCEEDED,
37 FIRST_WINDOW_CAPTURE_FAILED,
38 DESKTOP_CAPTURE_COUNTER_BOUNDARY
Ilya Sherman 2014/04/24 01:57:43 nit: Please document that since this enum is used
39 };
40
41 void IncrementCounter(DesktopCaptureCounters counter) {
42 UMA_HISTOGRAM_ENUMERATION("WebRTC.DesktopCaptureCounters",
43 counter,
44 DESKTOP_CAPTURE_COUNTER_BOUNDARY);
45 }
46
30 // Maximum CPU time percentage of a single core that can be consumed for desktop 47 // Maximum CPU time percentage of a single core that can be consumed for desktop
31 // capturing. This means that on systems where screen scraping is slow we may 48 // capturing. This means that on systems where screen scraping is slow we may
32 // need to capture at frame rate lower than requested. This is necessary to keep 49 // need to capture at frame rate lower than requested. This is necessary to keep
33 // UI responsive. 50 // UI responsive.
34 const int kMaximumCpuConsumptionPercentage = 50; 51 const int kMaximumCpuConsumptionPercentage = 50;
35 52
36 webrtc::DesktopRect ComputeLetterboxRect( 53 webrtc::DesktopRect ComputeLetterboxRect(
37 const webrtc::DesktopSize& max_size, 54 const webrtc::DesktopSize& max_size,
38 const webrtc::DesktopSize& source_size) { 55 const webrtc::DesktopSize& source_size) {
39 gfx::Rect result = media::ComputeLetterboxRegion( 56 gfx::Rect result = media::ComputeLetterboxRegion(
40 gfx::Rect(0, 0, max_size.width(), max_size.height()), 57 gfx::Rect(0, 0, max_size.width(), max_size.height()),
41 gfx::Size(source_size.width(), source_size.height())); 58 gfx::Size(source_size.width(), source_size.height()));
42 return webrtc::DesktopRect::MakeLTRB( 59 return webrtc::DesktopRect::MakeLTRB(
43 result.x(), result.y(), result.right(), result.bottom()); 60 result.x(), result.y(), result.right(), result.bottom());
44 } 61 }
45 62
46 } // namespace 63 } // namespace
47 64
48 class DesktopCaptureDevice::Core 65 class DesktopCaptureDevice::Core
49 : public base::RefCountedThreadSafe<Core>, 66 : public base::RefCountedThreadSafe<Core>,
50 public webrtc::DesktopCapturer::Callback { 67 public webrtc::DesktopCapturer::Callback {
51 public: 68 public:
52 Core(scoped_refptr<base::SequencedTaskRunner> task_runner, 69 Core(scoped_refptr<base::SequencedTaskRunner> task_runner,
53 scoped_ptr<webrtc::DesktopCapturer> capturer); 70 scoped_ptr<webrtc::DesktopCapturer> capturer,
71 DesktopMediaID::Type type);
54 72
55 // Implementation of VideoCaptureDevice methods. 73 // Implementation of VideoCaptureDevice methods.
56 void AllocateAndStart(const media::VideoCaptureParams& params, 74 void AllocateAndStart(const media::VideoCaptureParams& params,
57 scoped_ptr<Client> client); 75 scoped_ptr<Client> client);
58 void StopAndDeAllocate(); 76 void StopAndDeAllocate();
59 77
60 void SetNotificationWindowId(gfx::NativeViewId window_id); 78 void SetNotificationWindowId(gfx::NativeViewId window_id);
61 79
62 private: 80 private:
63 friend class base::RefCountedThreadSafe<Core>; 81 friend class base::RefCountedThreadSafe<Core>;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 // and/or letterboxed. 136 // and/or letterboxed.
119 webrtc::DesktopRect output_rect_; 137 webrtc::DesktopRect output_rect_;
120 138
121 // True when we have delayed OnCaptureTimer() task posted on 139 // True when we have delayed OnCaptureTimer() task posted on
122 // |task_runner_|. 140 // |task_runner_|.
123 bool capture_task_posted_; 141 bool capture_task_posted_;
124 142
125 // True when waiting for |desktop_capturer_| to capture current frame. 143 // True when waiting for |desktop_capturer_| to capture current frame.
126 bool capture_in_progress_; 144 bool capture_in_progress_;
127 145
146 // The type of the capturer.
147 DesktopMediaID::Type capturer_type_;
148
128 DISALLOW_COPY_AND_ASSIGN(Core); 149 DISALLOW_COPY_AND_ASSIGN(Core);
129 }; 150 };
130 151
131 DesktopCaptureDevice::Core::Core( 152 DesktopCaptureDevice::Core::Core(
132 scoped_refptr<base::SequencedTaskRunner> task_runner, 153 scoped_refptr<base::SequencedTaskRunner> task_runner,
133 scoped_ptr<webrtc::DesktopCapturer> capturer) 154 scoped_ptr<webrtc::DesktopCapturer> capturer,
155 DesktopMediaID::Type type)
134 : task_runner_(task_runner), 156 : task_runner_(task_runner),
135 desktop_capturer_(capturer.Pass()), 157 desktop_capturer_(capturer.Pass()),
136 capture_task_posted_(false), 158 capture_task_posted_(false),
137 capture_in_progress_(false) {} 159 capture_in_progress_(false),
160 capturer_type_(type) {}
138 161
139 DesktopCaptureDevice::Core::~Core() { 162 DesktopCaptureDevice::Core::~Core() {
140 } 163 }
141 164
142 void DesktopCaptureDevice::Core::AllocateAndStart( 165 void DesktopCaptureDevice::Core::AllocateAndStart(
143 const media::VideoCaptureParams& params, 166 const media::VideoCaptureParams& params,
144 scoped_ptr<Client> client) { 167 scoped_ptr<Client> client) {
145 DCHECK_GT(params.requested_format.frame_size.GetArea(), 0); 168 DCHECK_GT(params.requested_format.frame_size.GetArea(), 0);
146 DCHECK_GT(params.requested_format.frame_rate, 0); 169 DCHECK_GT(params.requested_format.frame_rate, 0);
147 170
(...skipping 17 matching lines...) Expand all
165 webrtc::SharedMemory* 188 webrtc::SharedMemory*
166 DesktopCaptureDevice::Core::CreateSharedMemory(size_t size) { 189 DesktopCaptureDevice::Core::CreateSharedMemory(size_t size) {
167 return NULL; 190 return NULL;
168 } 191 }
169 192
170 void DesktopCaptureDevice::Core::OnCaptureCompleted( 193 void DesktopCaptureDevice::Core::OnCaptureCompleted(
171 webrtc::DesktopFrame* frame) { 194 webrtc::DesktopFrame* frame) {
172 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 195 DCHECK(task_runner_->RunsTasksOnCurrentThread());
173 DCHECK(capture_in_progress_); 196 DCHECK(capture_in_progress_);
174 197
198 static bool first_call = true;
199 if (first_call) {
200 first_call = false;
201 if (frame) {
202 if (capturer_type_ == DesktopMediaID::TYPE_SCREEN)
Sergey Ulanov 2014/04/24 02:21:20 maybe use :? to make this code shorter: if (captu
203 IncrementCounter(FIRST_SCREEN_CAPTURE_SUCCEEDED);
Sergey Ulanov 2014/04/24 02:21:20 add {} please
204 else
205 IncrementCounter(FIRST_WINDOW_CAPTURE_SUCCEEDED);
206 } else {
207 if (capturer_type_ == DesktopMediaID::TYPE_SCREEN)
208 IncrementCounter(FIRST_SCREEN_CAPTURE_FAILED);
209 else
210 IncrementCounter(FIRST_WINDOW_CAPTURE_FAILED);
211 }
212 }
213
175 capture_in_progress_ = false; 214 capture_in_progress_ = false;
176 215
177 if (!frame) { 216 if (!frame) {
178 std::string log("Failed to capture a frame."); 217 std::string log("Failed to capture a frame.");
179 LOG(ERROR) << log; 218 LOG(ERROR) << log;
180 client_->OnError(log); 219 client_->OnError(log);
181 return; 220 return;
182 } 221 }
183 222
184 if (!client_) 223 if (!client_)
185 return; 224 return;
186 225
226 base::TimeDelta capture_time(
227 base::TimeDelta::FromMilliseconds(frame->capture_time_ms()));
228 if (capturer_type_ == DesktopMediaID::TYPE_SCREEN)
229 HISTOGRAM_TIMES("WebRTC.ScreenCaptureTime", capture_time);
Sergey Ulanov 2014/04/24 02:21:20 add {} please
230 else
231 HISTOGRAM_TIMES("WebRTC.WindowCaptureTime", capture_time);
Ilya Sherman 2014/04/24 01:57:43 These should both be UMA_HISTOGRAM_TIMES rather th
232
187 scoped_ptr<webrtc::DesktopFrame> owned_frame(frame); 233 scoped_ptr<webrtc::DesktopFrame> owned_frame(frame);
188 234
189 // Handle initial frame size and size changes. 235 // Handle initial frame size and size changes.
190 RefreshCaptureFormat(frame->size()); 236 RefreshCaptureFormat(frame->size());
191 237
192 webrtc::DesktopSize output_size(capture_format_.frame_size.width(), 238 webrtc::DesktopSize output_size(capture_format_.frame_size.width(),
193 capture_format_.frame_size.height()); 239 capture_format_.frame_size.height());
194 size_t output_bytes = output_size.width() * output_size.height() * 240 size_t output_bytes = output_size.width() * output_size.height() *
195 webrtc::DesktopFrame::kBytesPerPixel; 241 webrtc::DesktopFrame::kBytesPerPixel;
196 const uint8_t* output_data = NULL; 242 const uint8_t* output_data = NULL;
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 scoped_ptr<webrtc::DesktopCapturer> capturer; 428 scoped_ptr<webrtc::DesktopCapturer> capturer;
383 429
384 switch (source.type) { 430 switch (source.type) {
385 case DesktopMediaID::TYPE_SCREEN: { 431 case DesktopMediaID::TYPE_SCREEN: {
386 scoped_ptr<webrtc::ScreenCapturer> screen_capturer; 432 scoped_ptr<webrtc::ScreenCapturer> screen_capturer;
387 screen_capturer.reset(webrtc::ScreenCapturer::Create(options)); 433 screen_capturer.reset(webrtc::ScreenCapturer::Create(options));
388 if (screen_capturer && screen_capturer->SelectScreen(source.id)) { 434 if (screen_capturer && screen_capturer->SelectScreen(source.id)) {
389 capturer.reset(new webrtc::DesktopAndCursorComposer( 435 capturer.reset(new webrtc::DesktopAndCursorComposer(
390 screen_capturer.release(), 436 screen_capturer.release(),
391 webrtc::MouseCursorMonitor::CreateForScreen(options, source.id))); 437 webrtc::MouseCursorMonitor::CreateForScreen(options, source.id)));
438 IncrementCounter(SCREEN_CAPTURER_CREATED);
392 } 439 }
393 break; 440 break;
394 } 441 }
395 442
396 case DesktopMediaID::TYPE_WINDOW: { 443 case DesktopMediaID::TYPE_WINDOW: {
397 scoped_ptr<webrtc::WindowCapturer> window_capturer( 444 scoped_ptr<webrtc::WindowCapturer> window_capturer(
398 webrtc::WindowCapturer::Create(options)); 445 webrtc::WindowCapturer::Create(options));
399 if (window_capturer && window_capturer->SelectWindow(source.id)) { 446 if (window_capturer && window_capturer->SelectWindow(source.id)) {
400 window_capturer->BringSelectedWindowToFront(); 447 window_capturer->BringSelectedWindowToFront();
401 capturer.reset(new webrtc::DesktopAndCursorComposer( 448 capturer.reset(new webrtc::DesktopAndCursorComposer(
402 window_capturer.release(), 449 window_capturer.release(),
403 webrtc::MouseCursorMonitor::CreateForWindow(options, source.id))); 450 webrtc::MouseCursorMonitor::CreateForWindow(options, source.id)));
451 IncrementCounter(WINDOW_CATPTURER_CREATED);
404 } 452 }
405 break; 453 break;
406 } 454 }
407 455
408 default: { 456 default: {
409 NOTREACHED(); 457 NOTREACHED();
410 } 458 }
411 } 459 }
412 460
413 scoped_ptr<media::VideoCaptureDevice> result; 461 scoped_ptr<media::VideoCaptureDevice> result;
414 if (capturer) 462 if (capturer) {
415 result.reset(new DesktopCaptureDevice(task_runner, capturer.Pass())); 463 result.reset(
464 new DesktopCaptureDevice(task_runner, capturer.Pass(), source.type));
465 }
416 466
417 return result.Pass(); 467 return result.Pass();
418 } 468 }
419 469
420 DesktopCaptureDevice::DesktopCaptureDevice( 470 DesktopCaptureDevice::DesktopCaptureDevice(
421 scoped_refptr<base::SequencedTaskRunner> task_runner, 471 scoped_refptr<base::SequencedTaskRunner> task_runner,
422 scoped_ptr<webrtc::DesktopCapturer> capturer) 472 scoped_ptr<webrtc::DesktopCapturer> capturer,
423 : core_(new Core(task_runner, capturer.Pass())) {} 473 DesktopMediaID::Type type)
474 : core_(new Core(task_runner, capturer.Pass(), type)) {}
424 475
425 DesktopCaptureDevice::~DesktopCaptureDevice() { 476 DesktopCaptureDevice::~DesktopCaptureDevice() {
426 StopAndDeAllocate(); 477 StopAndDeAllocate();
427 } 478 }
428 479
429 void DesktopCaptureDevice::AllocateAndStart( 480 void DesktopCaptureDevice::AllocateAndStart(
430 const media::VideoCaptureParams& params, 481 const media::VideoCaptureParams& params,
431 scoped_ptr<Client> client) { 482 scoped_ptr<Client> client) {
432 core_->AllocateAndStart(params, client.Pass()); 483 core_->AllocateAndStart(params, client.Pass());
433 } 484 }
434 485
435 void DesktopCaptureDevice::StopAndDeAllocate() { 486 void DesktopCaptureDevice::StopAndDeAllocate() {
436 core_->StopAndDeAllocate(); 487 core_->StopAndDeAllocate();
437 } 488 }
438 489
439 void DesktopCaptureDevice::SetNotificationWindowId( 490 void DesktopCaptureDevice::SetNotificationWindowId(
440 gfx::NativeViewId window_id) { 491 gfx::NativeViewId window_id) {
441 core_->SetNotificationWindowId(window_id); 492 core_->SetNotificationWindowId(window_id);
442 } 493 }
443 494
444 } // namespace content 495 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698