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

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"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // Update capture size. Must be called on the UI thread. 124 // Update capture size. Must be called on the UI thread.
123 void UpdateCaptureSize(); 125 void UpdateCaptureSize();
124 126
125 // Response callback for cc::Layer::RequestCopyOfOutput(). 127 // Response callback for cc::Layer::RequestCopyOfOutput().
126 void DidCopyOutput( 128 void DidCopyOutput(
127 scoped_refptr<media::VideoFrame> video_frame, 129 scoped_refptr<media::VideoFrame> video_frame,
128 base::TimeTicks start_time, 130 base::TimeTicks start_time,
129 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 131 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
130 scoped_ptr<cc::CopyOutputResult> result); 132 scoped_ptr<cc::CopyOutputResult> result);
131 133
134 // A helper which does the real work for DidCopyOutput. Returns true if
135 // succeeded.
136 bool ProcessCopyOutputResponse(
137 scoped_refptr<media::VideoFrame> video_frame,
138 base::TimeTicks start_time,
139 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
140 scoped_ptr<cc::CopyOutputResult> result);
141
132 // Helper function to update cursor state. 142 // Helper function to update cursor state.
133 // |region_in_frame| defines the desktop bound in the captured frame. 143 // |region_in_frame| defines the desktop bound in the captured frame.
134 // Returns the current cursor position in captured frame. 144 // Returns the current cursor position in captured frame.
135 gfx::Point UpdateCursorState(const gfx::Rect& region_in_frame); 145 gfx::Point UpdateCursorState(const gfx::Rect& region_in_frame);
136 146
137 // Clears cursor state. 147 // Clears cursor state.
138 void ClearCursorState(); 148 void ClearCursorState();
139 149
140 // The window associated with the desktop. 150 // The window associated with the desktop.
141 aura::Window* desktop_window_; 151 aura::Window* desktop_window_;
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position); 295 RenderCursorOnVideoFrame(target, cursor_bitmap, cursor_position);
286 release_callback->Run(0, false); 296 release_callback->Run(0, false);
287 capture_frame_cb.Run(start_time, result); 297 capture_frame_cb.Run(start_time, result);
288 } 298 }
289 299
290 void DesktopVideoCaptureMachine::DidCopyOutput( 300 void DesktopVideoCaptureMachine::DidCopyOutput(
291 scoped_refptr<media::VideoFrame> video_frame, 301 scoped_refptr<media::VideoFrame> video_frame,
292 base::TimeTicks start_time, 302 base::TimeTicks start_time,
293 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb, 303 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
294 scoped_ptr<cc::CopyOutputResult> result) { 304 scoped_ptr<cc::CopyOutputResult> result) {
305 static bool first_call = true;
306
307 bool succeeded = ProcessCopyOutputResponse(
308 video_frame, start_time, capture_frame_cb, result.Pass());
309
310 base::TimeDelta capture_time = base::TimeTicks::Now() - start_time;
311 UMA_HISTOGRAM_TIMES(
312 window_id_.type == DesktopMediaID::TYPE_SCREEN ? kUmaScreenCaptureTime
313 : kUmaWindowCaptureTime,
314 capture_time);
315
316 if (first_call) {
317 first_call = false;
318 if (window_id_.type == DesktopMediaID::TYPE_SCREEN) {
319 IncrementDesktopCaptureCounter(succeeded ? FIRST_SCREEN_CAPTURE_SUCCEEDED
320 : FIRST_SCREEN_CAPTURE_FAILED);
321 } else {
322 IncrementDesktopCaptureCounter(succeeded
323 ? FIRST_WINDOW_CAPTURE_SUCCEEDED
324 : FIRST_WINDOW_CAPTURE_SUCCEEDED);
325 }
326 }
327 }
328
329 bool DesktopVideoCaptureMachine::ProcessCopyOutputResponse(
330 scoped_refptr<media::VideoFrame> video_frame,
331 base::TimeTicks start_time,
332 const ThreadSafeCaptureOracle::CaptureFrameCallback& capture_frame_cb,
333 scoped_ptr<cc::CopyOutputResult> result) {
295 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_) 334 if (result->IsEmpty() || result->size().IsEmpty() || !desktop_layer_)
296 return; 335 return false;
297 336
298 // Compute the dest size we want after the letterboxing resize. Make the 337 // Compute the dest size we want after the letterboxing resize. Make the
299 // coordinates and sizes even because we letterbox in YUV space 338 // coordinates and sizes even because we letterbox in YUV space
300 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to 339 // (see CopyRGBToVideoFrame). They need to be even for the UV samples to
301 // line up correctly. 340 // line up correctly.
302 // The video frame's coded_size() and the result's size() are both physical 341 // The video frame's coded_size() and the result's size() are both physical
303 // pixels. 342 // pixels.
304 gfx::Rect region_in_frame = 343 gfx::Rect region_in_frame =
305 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()), 344 media::ComputeLetterboxRegion(gfx::Rect(video_frame->coded_size()),
306 result->size()); 345 result->size());
307 region_in_frame = gfx::Rect(region_in_frame.x() & ~1, 346 region_in_frame = gfx::Rect(region_in_frame.x() & ~1,
308 region_in_frame.y() & ~1, 347 region_in_frame.y() & ~1,
309 region_in_frame.width() & ~1, 348 region_in_frame.width() & ~1,
310 region_in_frame.height() & ~1); 349 region_in_frame.height() & ~1);
311 if (region_in_frame.IsEmpty()) 350 if (region_in_frame.IsEmpty())
312 return; 351 return false;
313 352
314 ImageTransportFactory* factory = ImageTransportFactory::GetInstance(); 353 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
315 GLHelper* gl_helper = factory->GetGLHelper(); 354 GLHelper* gl_helper = factory->GetGLHelper();
316 if (!gl_helper) 355 if (!gl_helper)
317 return; 356 return false;
318 357
319 cc::TextureMailbox texture_mailbox; 358 cc::TextureMailbox texture_mailbox;
320 scoped_ptr<cc::SingleReleaseCallback> release_callback; 359 scoped_ptr<cc::SingleReleaseCallback> release_callback;
321 result->TakeTexture(&texture_mailbox, &release_callback); 360 result->TakeTexture(&texture_mailbox, &release_callback);
322 DCHECK(texture_mailbox.IsTexture()); 361 DCHECK(texture_mailbox.IsTexture());
323 if (!texture_mailbox.IsTexture()) 362 if (!texture_mailbox.IsTexture())
324 return; 363 return false;
325 364
326 gfx::Rect result_rect(result->size()); 365 gfx::Rect result_rect(result->size());
327 if (!yuv_readback_pipeline_ || 366 if (!yuv_readback_pipeline_ ||
328 yuv_readback_pipeline_->scaler()->SrcSize() != result_rect.size() || 367 yuv_readback_pipeline_->scaler()->SrcSize() != result_rect.size() ||
329 yuv_readback_pipeline_->scaler()->SrcSubrect() != result_rect || 368 yuv_readback_pipeline_->scaler()->SrcSubrect() != result_rect ||
330 yuv_readback_pipeline_->scaler()->DstSize() != region_in_frame.size()) { 369 yuv_readback_pipeline_->scaler()->DstSize() != region_in_frame.size()) {
331 yuv_readback_pipeline_.reset( 370 yuv_readback_pipeline_.reset(
332 gl_helper->CreateReadbackPipelineYUV(GLHelper::SCALER_QUALITY_FAST, 371 gl_helper->CreateReadbackPipelineYUV(GLHelper::SCALER_QUALITY_FAST,
333 result_rect.size(), 372 result_rect.size(),
334 result_rect, 373 result_rect,
335 video_frame->coded_size(), 374 video_frame->coded_size(),
336 region_in_frame, 375 region_in_frame,
337 true, 376 true,
338 true)); 377 true));
339 } 378 }
340 379
341 gfx::Point cursor_position_in_frame = UpdateCursorState(region_in_frame); 380 gfx::Point cursor_position_in_frame = UpdateCursorState(region_in_frame);
342 yuv_readback_pipeline_->ReadbackYUV( 381 yuv_readback_pipeline_->ReadbackYUV(
343 texture_mailbox.mailbox(), 382 texture_mailbox.mailbox(),
344 texture_mailbox.sync_point(), 383 texture_mailbox.sync_point(),
345 video_frame.get(), 384 video_frame.get(),
346 base::Bind(&CopyOutputFinishedForVideo, 385 base::Bind(&CopyOutputFinishedForVideo,
347 start_time, 386 start_time,
348 capture_frame_cb, 387 capture_frame_cb,
349 video_frame, 388 video_frame,
350 scaled_cursor_bitmap_, 389 scaled_cursor_bitmap_,
351 cursor_position_in_frame, 390 cursor_position_in_frame,
352 base::Passed(&release_callback))); 391 base::Passed(&release_callback)));
392 return true;
353 } 393 }
354 394
355 gfx::Point DesktopVideoCaptureMachine::UpdateCursorState( 395 gfx::Point DesktopVideoCaptureMachine::UpdateCursorState(
356 const gfx::Rect& region_in_frame) { 396 const gfx::Rect& region_in_frame) {
357 const gfx::Rect desktop_bounds = desktop_layer_->bounds(); 397 const gfx::Rect desktop_bounds = desktop_layer_->bounds();
358 gfx::NativeCursor cursor = 398 gfx::NativeCursor cursor =
359 desktop_window_->GetHost()->last_cursor(); 399 desktop_window_->GetHost()->last_cursor();
360 if (last_cursor_ != cursor) { 400 if (last_cursor_ != cursor) {
361 SkBitmap cursor_bitmap; 401 SkBitmap cursor_bitmap;
362 if (ui::GetCursorBitmap(cursor, &cursor_bitmap, &cursor_hot_point_)) { 402 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>( 465 : core_(new ContentVideoCaptureDeviceCore(scoped_ptr<VideoCaptureMachine>(
426 new DesktopVideoCaptureMachine(source)))) {} 466 new DesktopVideoCaptureMachine(source)))) {}
427 467
428 DesktopCaptureDeviceAura::~DesktopCaptureDeviceAura() { 468 DesktopCaptureDeviceAura::~DesktopCaptureDeviceAura() {
429 DVLOG(2) << "DesktopCaptureDeviceAura@" << this << " destroying."; 469 DVLOG(2) << "DesktopCaptureDeviceAura@" << this << " destroying.";
430 } 470 }
431 471
432 // static 472 // static
433 media::VideoCaptureDevice* DesktopCaptureDeviceAura::Create( 473 media::VideoCaptureDevice* DesktopCaptureDeviceAura::Create(
434 const DesktopMediaID& source) { 474 const DesktopMediaID& source) {
475 IncrementDesktopCaptureCounter(source.type == DesktopMediaID::TYPE_SCREEN
476 ? SCREEN_CAPTURER_CREATED
477 : WINDOW_CATPTURER_CREATED);
435 return new DesktopCaptureDeviceAura(source); 478 return new DesktopCaptureDeviceAura(source);
436 } 479 }
437 480
438 void DesktopCaptureDeviceAura::AllocateAndStart( 481 void DesktopCaptureDeviceAura::AllocateAndStart(
439 const media::VideoCaptureParams& params, 482 const media::VideoCaptureParams& params,
440 scoped_ptr<Client> client) { 483 scoped_ptr<Client> client) {
441 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString(); 484 DVLOG(1) << "Allocating " << params.requested_format.frame_size.ToString();
442 core_->AllocateAndStart(params, client.Pass()); 485 core_->AllocateAndStart(params, client.Pass());
443 } 486 }
444 487
445 void DesktopCaptureDeviceAura::StopAndDeAllocate() { 488 void DesktopCaptureDeviceAura::StopAndDeAllocate() {
446 core_->StopAndDeAllocate(); 489 core_->StopAndDeAllocate();
447 } 490 }
448 491
449 } // namespace content 492 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698