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

Side by Side Diff: content/browser/media/capture/desktop_capture_device_aura.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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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_aura.h" 5 #include "content/browser/media/capture/desktop_capture_device_aura.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
8 #include "base/timer/timer.h" 9 #include "base/timer/timer.h"
9 #include "cc/output/copy_output_request.h" 10 #include "cc/output/copy_output_request.h"
10 #include "cc/output/copy_output_result.h" 11 #include "cc/output/copy_output_result.h"
11 #include "content/browser/compositor/image_transport_factory.h" 12 #include "content/browser/compositor/image_transport_factory.h"
12 #include "content/browser/media/capture/content_video_capture_device_core.h" 13 #include "content/browser/media/capture/content_video_capture_device_core.h"
14 #include "content/browser/media/capture/desktop_capture_device_uma_types.h"
13 #include "content/common/gpu/client/gl_helper.h" 15 #include "content/common/gpu/client/gl_helper.h"
14 #include "content/public/browser/browser_thread.h" 16 #include "content/public/browser/browser_thread.h"
15 #include "media/base/video_util.h" 17 #include "media/base/video_util.h"
16 #include "media/video/capture/video_capture_types.h" 18 #include "media/video/capture/video_capture_types.h"
17 #include "skia/ext/image_operations.h" 19 #include "skia/ext/image_operations.h"
18 #include "third_party/skia/include/core/SkBitmap.h" 20 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "ui/aura/env.h" 21 #include "ui/aura/env.h"
20 #include "ui/aura/window.h" 22 #include "ui/aura/window.h"
21 #include "ui/aura/window_observer.h" 23 #include "ui/aura/window_observer.h"
22 #include "ui/aura/window_tree_host.h" 24 #include "ui/aura/window_tree_host.h"
23 #include "ui/base/cursor/cursors_aura.h" 25 #include "ui/base/cursor/cursors_aura.h"
24 #include "ui/compositor/compositor.h" 26 #include "ui/compositor/compositor.h"
25 #include "ui/compositor/dip_util.h" 27 #include "ui/compositor/dip_util.h"
26 #include "ui/compositor/layer.h" 28 #include "ui/compositor/layer.h"
27 #include "ui/gfx/screen.h" 29 #include "ui/gfx/screen.h"
28 30
29 namespace content { 31 namespace content {
30 32
31 namespace { 33 namespace {
32 34
35 void IncrementCounter(DesktopCaptureCounters counter) {
36 UMA_HISTOGRAM_ENUMERATION(kUMADesopCaptureCounters,
37 counter,
38 DESKTOP_CAPTURE_COUNTER_BOUNDARY);
39 }
40
33 int clip_byte(int x) { 41 int clip_byte(int x) {
34 return std::max(0, std::min(x, 255)); 42 return std::max(0, std::min(x, 255));
35 } 43 }
36 44
37 int alpha_blend(int alpha, int src, int dst) { 45 int alpha_blend(int alpha, int src, int dst) {
38 return (src * alpha + dst * (255 - alpha)) / 255; 46 return (src * alpha + dst * (255 - alpha)) / 255;
39 } 47 }
40 48
41 // Helper function to composite a cursor bitmap on a YUV420 video frame. 49 // Helper function to composite a cursor bitmap on a YUV420 video frame.
42 void RenderCursorOnVideoFrame( 50 void RenderCursorOnVideoFrame(
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // Update capture size. Must be called on the UI thread. 130 // Update capture size. Must be called on the UI thread.
123 void UpdateCaptureSize(); 131 void UpdateCaptureSize();
124 132
125 // Response callback for cc::Layer::RequestCopyOfOutput(). 133 // Response callback for cc::Layer::RequestCopyOfOutput().
126 void DidCopyOutput( 134 void DidCopyOutput(
127 scoped_refptr<media::VideoFrame> video_frame, 135 scoped_refptr<media::VideoFrame> video_frame,
128 base::TimeTicks start_time, 136 base::TimeTicks start_time,
129 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 137 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
130 scoped_ptr<cc::CopyOutputResult> result); 138 scoped_ptr<cc::CopyOutputResult> result);
131 139
140 // A helper which does the real work for DidCopyOutput. Returns true if
141 // succeeded.
142 bool DidCopyOutputHelper(
143 scoped_refptr<media::VideoFrame> video_frame,
144 base::TimeTicks start_time,
145 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
146 scoped_ptr<cc::CopyOutputResult> result);
147
132 // Helper function to update cursor state. 148 // Helper function to update cursor state.
133 // |region_in_frame| defines the desktop bound in the captured frame. 149 // |region_in_frame| defines the desktop bound in the captured frame.
134 // Returns the current cursor position in captured frame. 150 // Returns the current cursor position in captured frame.
135 gfx::Point UpdateCursorState(const gfx::Rect& region_in_frame); 151 gfx::Point UpdateCursorState(const gfx::Rect& region_in_frame);
136 152
137 // Clears cursor state. 153 // Clears cursor state.
138 void ClearCursorState(); 154 void ClearCursorState();
139 155
140 // The window associated with the desktop. 156 // The window associated with the desktop.
141 aura::Window* desktop_window_; 157 aura::Window* desktop_window_;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position); 301 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position);
286 release_callback->Run(0, false); 302 release_callback->Run(0, false);
287 capture_frame_cb.Run(start_time, result); 303 capture_frame_cb.Run(start_time, result);
288 } 304 }
289 305
290 void DesktopVideoCaptureMachine::DidCopyOutput( 306 void DesktopVideoCaptureMachine::DidCopyOutput(
291 scoped_refptr<media::VideoFrame> video_frame, 307 scoped_refptr<media::VideoFrame> video_frame,
292 base::TimeTicks start_time, 308 base::TimeTicks start_time,
293 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 309 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
294 scoped_ptr<cc::CopyOutputResult> result) { 310 scoped_ptr<cc::CopyOutputResult> result) {
311 static bool first_call = true;
312
313 bool succeeded = DidCopyOutputHelper(
314 video_frame, start_time, capture_frame_cb, result.Pass());
315
316 if (first_call) {
317 first_call = false;
318 if (window_id_.type == DesktopMediaID::TYPE_SCREEN) {
319 IncrementCounter(succeeded ? FIRST_SCREEN_CAPTURE_SUCCEEDED :
320 FIRST_SCREEN_CAPTURE_FAILED);
Sergey Ulanov 2014/04/24 19:33:24 nit: indentation. Also : can be wrapped. clang-for
jiayl 2014/04/24 20:58:55 Done.
321 } else {
322 IncrementCounter(succeeded ? FIRST_WINDOW_CAPTURE_SUCCEEDED :
323 FIRST_WINDOW_CAPTURE_SUCCEEDED);
324 }
325 }
326 }
327
328 bool DesktopVideoCaptureMachine::DidCopyOutputHelper(
Sergey Ulanov 2014/04/24 19:33:24 Call this something like ProcessCopyOutputResponse
jiayl 2014/04/24 20:58:55 Done.
329 scoped_refptr<media::VideoFrame> video_frame,
330 base::TimeTicks start_time,
331 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
332 scoped_ptr<cc::CopyOutputResult> result) {
295 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_) 333 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_)
296 return; 334 return false;
297 335
298 // Compute the dest size we want after the letterboxing resize. Make the 336 // Compute the dest size we want after the letterboxing resize. Make the
299 // coordinates and sizes even because we letterbox in YUV space 337 // coordinates and sizes even because we letterbox in YUV space
300 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to 338 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
301 // line up correctly. 339 // line up correctly.
302 // The video frame's coded_size() and the result's size() are both physical 340 // The video frame's coded_size() and the result's size() are both physical
303 // pixels. 341 // pixels.
304 gfx::Rect region_in_frame = 342 gfx::Rect region_in_frame =
305 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), 343 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()),
306 result->size()); 344 result->size());
307 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, 345 region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
308 region_in_frame.y() & ~1, 346 region_in_frame.y() & ~1,
309 region_in_frame.width() & ~1, 347 region_in_frame.width() & ~1,
310 region_in_frame.height() & ~1); 348 region_in_frame.height() & ~1);
311 if (region_in_frame.IsEmpty()) 349 if (region_in_frame.IsEmpty())
312 return; 350 return false;
313 351
314 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 352 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
315 GLHelper* gl_helper = factory->GetGLHelper(); 353 GLHelper* gl_helper = factory->GetGLHelper();
316 if (!gl_helper) 354 if (!gl_helper)
317 return; 355 return false;
318 356
319 cc::TextureMailbox texture_mailbox; 357 cc::TextureMailbox texture_mailbox;
320 scoped_ptr<cc::SingleReleaseCallback> release_callback; 358 scoped_ptr<cc::SingleReleaseCallback> release_callback;
321 result->TakeTexture(&texture_mailbox, &release_callback); 359 result->TakeTexture(&texture_mailbox, &release_callback);
322 DCHECK(texture_mailbox.IsTexture()); 360 DCHECK(texture_mailbox.IsTexture());
323 if (!texture_mailbox.IsTexture()) 361 if (!texture_mailbox.IsTexture())
324 return; 362 return false;
325 363
326 gfx::Rect result_rect(result->size()); 364 gfx::Rect result_rect(result->size());
327 if (!yuv_readback_pipeline_ || 365 if (!yuv_readback_pipeline_ ||
328 yuv_readback_pipeline_->scaler()->SrcSize() != result_rect.size() || 366 yuv_readback_pipeline_->scaler()->SrcSize() != result_rect.size() ||
329 yuv_readback_pipeline_->scaler()->SrcSubrect() != result_rect || 367 yuv_readback_pipeline_->scaler()->SrcSubrect() != result_rect ||
330 yuv_readback_pipeline_->scaler()->DstSize() != region_in_frame.size()) { 368 yuv_readback_pipeline_->scaler()->DstSize() != region_in_frame.size()) {
331 yuv_readback_pipeline_.reset( 369 yuv_readback_pipeline_.reset(
332 gl_helper->CreateReadbackPipelineYUV(GLHelper::SCALER_QUALITY_FAST, 370 gl_helper->CreateReadbackPipelineYUV(GLHelper::SCALER_QUALITY_FAST,
333 result_rect.size(), 371 result_rect.size(),
334 result_rect, 372 result_rect,
335 video_frame->coded_size(), 373 video_frame->coded_size(),
336 region_in_frame, 374 region_in_frame,
337 true, 375 true,
338 true)); 376 true));
339 } 377 }
340 378
341 gfx::Point cursor_position_in_frame = UpdateCursorState(region_in_frame); 379 gfx::Point cursor_position_in_frame = UpdateCursorState(region_in_frame);
342 yuv_readback_pipeline_->ReadbackYUV( 380 yuv_readback_pipeline_->ReadbackYUV(
343 texture_mailbox.mailbox(), 381 texture_mailbox.mailbox(),
344 texture_mailbox.sync_point(), 382 texture_mailbox.sync_point(),
345 video_frame.get(), 383 video_frame.get(),
346 base::Bind(&CopyOutputFinishedForVideo, 384 base::Bind(&CopyOutputFinishedForVideo,
347 start_time, 385 start_time,
348 capture_frame_cb, 386 capture_frame_cb,
349 video_frame, 387 video_frame,
350 scaled_cursor_bitmap_, 388 scaled_cursor_bitmap_,
351 cursor_position_in_frame, 389 cursor_position_in_frame,
352 base::Passed(&release_callback))); 390 base::Passed(&release_callback)));
391
392 base::TimeDelta capture_time = base::TimeTicks::Now() - start_time;
Sergey Ulanov 2014/04/24 19:33:24 Move this to DidCopyOutput() so that all UMA logic
jiayl 2014/04/24 20:58:55 Done.
393 if (window_id_.type == DesktopMediaID::TYPE_SCREEN)
394 UMA_HISTOGRAM_TIMES(kUMAScreenCaptureTime, capture_time);
Sergey Ulanov 2014/04/24 19:33:24 {}
jiayl 2014/04/24 20:58:55 It's not required for single line conditionals.
395 else
396 UMA_HISTOGRAM_TIMES(kUMAWindowCaptureTime, capture_time);
397
398 return true;
353 } 399 }
354 400
355 gfx::Point DesktopVideoCaptureMachine::UpdateCursorState( 401 gfx::Point DesktopVideoCaptureMachine::UpdateCursorState(
356 const gfx::Rect& region_in_frame) { 402 const gfx::Rect& region_in_frame) {
357 const gfx::Rect desktop_bounds = desktop_layer_->bounds(); 403 const gfx::Rect desktop_bounds = desktop_layer_->bounds();
358 gfx::NativeCursor cursor = 404 gfx::NativeCursor cursor =
359 desktop_window_->GetHost()->last_cursor(); 405 desktop_window_->GetHost()->last_cursor();
360 if (last_cursor_ != cursor) { 406 if (last_cursor_ != cursor) {
361 SkBitmap cursor_bitmap; 407 SkBitmap cursor_bitmap;
362 if (ui::GetCursorBitmap(cursor, &cursor_bitmap, &cursor_hot_point_)) { 408 if (ui::GetCursorBitmap(cursor, &cursor_bitmap, &cursor_hot_point_)) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 : core_(new ContentVideoCaptureDeviceCore(scoped_ptr<VideoCaptureMachine>( 471 : core_(new ContentVideoCaptureDeviceCore(scoped_ptr<VideoCaptureMachine>(
426 new DesktopVideoCaptureMachine(source)))) {} 472 new DesktopVideoCaptureMachine(source)))) {}
427 473
428 DesktopCaptureDeviceAura::~DesktopCaptureDeviceAura() { 474 DesktopCaptureDeviceAura::~DesktopCaptureDeviceAura() {
429 DVLOG(2) << "DesktopCaptureDeviceAura@" << this << " destroying."; 475 DVLOG(2) << "DesktopCaptureDeviceAura@" << this << " destroying.";
430 } 476 }
431 477
432 // static 478 // static
433 media::VideoCaptureDevice* DesktopCaptureDeviceAura::Create( 479 media::VideoCaptureDevice* DesktopCaptureDeviceAura::Create(
434 const DesktopMediaID& source) { 480 const DesktopMediaID& source) {
481 IncrementCounter(source.type == DesktopMediaID::TYPE_SCREEN ?
482 SCREEN_CAPTURER_CREATED : WINDOW_CATPTURER_CREATED);
435 return new DesktopCaptureDeviceAura(source); 483 return new DesktopCaptureDeviceAura(source);
436 } 484 }
437 485
438 void DesktopCaptureDeviceAura::AllocateAndStart( 486 void DesktopCaptureDeviceAura::AllocateAndStart(
439 const media::VideoCaptureParams& params, 487 const media::VideoCaptureParams& params,
440 scoped_ptr<Client> client) { 488 scoped_ptr<Client> client) {
441 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); 489 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
442 core_->AllocateAndStart(params, client.Pass()); 490 core_->AllocateAndStart(params, client.Pass());
443 } 491 }
444 492
445 void DesktopCaptureDeviceAura::StopAndDeAllocate() { 493 void DesktopCaptureDeviceAura::StopAndDeAllocate() {
446 core_->StopAndDeAllocate(); 494 core_->StopAndDeAllocate();
447 } 495 }
448 496
449 } // namespace content 497 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698