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

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

Issue 268123003: Enables using the magnification API for screen capturing on Windows under a Finch experiment. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 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/field_trial.h"
10 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
11 #include "base/sequenced_task_runner.h" 12 #include "base/sequenced_task_runner.h"
12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
13 #include "base/synchronization/lock.h" 14 #include "base/synchronization/lock.h"
14 #include "base/threading/sequenced_worker_pool.h" 15 #include "base/threading/sequenced_worker_pool.h"
16 #include "base/threading/thread.h"
15 #include "content/browser/media/capture/desktop_capture_device_uma_types.h" 17 #include "content/browser/media/capture/desktop_capture_device_uma_types.h"
16 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/desktop_media_id.h" 19 #include "content/public/browser/desktop_media_id.h"
18 #include "media/base/video_util.h" 20 #include "media/base/video_util.h"
19 #include "third_party/libyuv/include/libyuv/scale_argb.h" 21 #include "third_party/libyuv/include/libyuv/scale_argb.h"
20 #include "third_party/webrtc/modules/desktop_capture/desktop_and_cursor_composer .h" 22 #include "third_party/webrtc/modules/desktop_capture/desktop_and_cursor_composer .h"
21 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" 23 #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
22 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" 24 #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h"
23 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 25 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
24 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h" 26 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_monitor.h"
(...skipping 20 matching lines...) Expand all
45 result.x(), result.y(), result.right(), result.bottom()); 47 result.x(), result.y(), result.right(), result.bottom());
46 } 48 }
47 49
48 } // namespace 50 } // namespace
49 51
50 class DesktopCaptureDevice::Core 52 class DesktopCaptureDevice::Core
51 : public base::RefCountedThreadSafe<Core>, 53 : public base::RefCountedThreadSafe<Core>,
52 public webrtc::DesktopCapturer::Callback { 54 public webrtc::DesktopCapturer::Callback {
53 public: 55 public:
54 Core(scoped_refptr<base::SequencedTaskRunner> task_runner, 56 Core(scoped_refptr<base::SequencedTaskRunner> task_runner,
57 scoped_ptr<base::Thread> thread,
55 scoped_ptr<webrtc::DesktopCapturer> capturer, 58 scoped_ptr<webrtc::DesktopCapturer> capturer,
56 DesktopMediaID::Type type); 59 DesktopMediaID::Type type);
57 60
58 // Implementation of VideoCaptureDevice methods. 61 // Implementation of VideoCaptureDevice methods.
59 void AllocateAndStart(const media::VideoCaptureParams& params, 62 void AllocateAndStart(const media::VideoCaptureParams& params,
60 scoped_ptr<Client> client); 63 scoped_ptr<Client> client);
61 void StopAndDeAllocate(); 64 void StopAndDeAllocate();
62 65
63 void SetNotificationWindowId(gfx::NativeViewId window_id); 66 void SetNotificationWindowId(gfx::NativeViewId window_id);
64 67
(...skipping 24 matching lines...) Expand all
89 void CaptureFrameAndScheduleNext(); 92 void CaptureFrameAndScheduleNext();
90 93
91 // Captures a single frame. 94 // Captures a single frame.
92 void DoCapture(); 95 void DoCapture();
93 96
94 void DoSetNotificationWindowId(gfx::NativeViewId window_id); 97 void DoSetNotificationWindowId(gfx::NativeViewId window_id);
95 98
96 // Task runner used for capturing operations. 99 // Task runner used for capturing operations.
97 scoped_refptr<base::SequencedTaskRunner> task_runner_; 100 scoped_refptr<base::SequencedTaskRunner> task_runner_;
98 101
102 // The thread on which the capturer is running.
103 scoped_ptr<base::Thread> thread_;
104
99 // The underlying DesktopCapturer instance used to capture frames. 105 // The underlying DesktopCapturer instance used to capture frames.
100 scoped_ptr<webrtc::DesktopCapturer> desktop_capturer_; 106 scoped_ptr<webrtc::DesktopCapturer> desktop_capturer_;
101 107
102 // The device client which proxies device events to the controller. Accessed 108 // The device client which proxies device events to the controller. Accessed
103 // on the task_runner_ thread. 109 // on the task_runner_ thread.
104 scoped_ptr<Client> client_; 110 scoped_ptr<Client> client_;
105 111
106 // Requested video capture format (width, height, frame rate, etc). 112 // Requested video capture format (width, height, frame rate, etc).
107 media::VideoCaptureParams requested_params_; 113 media::VideoCaptureParams requested_params_;
108 114
(...skipping 20 matching lines...) Expand all
129 bool capture_in_progress_; 135 bool capture_in_progress_;
130 136
131 // The type of the capturer. 137 // The type of the capturer.
132 DesktopMediaID::Type capturer_type_; 138 DesktopMediaID::Type capturer_type_;
133 139
134 DISALLOW_COPY_AND_ASSIGN(Core); 140 DISALLOW_COPY_AND_ASSIGN(Core);
135 }; 141 };
136 142
137 DesktopCaptureDevice::Core::Core( 143 DesktopCaptureDevice::Core::Core(
138 scoped_refptr<base::SequencedTaskRunner> task_runner, 144 scoped_refptr<base::SequencedTaskRunner> task_runner,
145 scoped_ptr<base::Thread> thread,
139 scoped_ptr<webrtc::DesktopCapturer> capturer, 146 scoped_ptr<webrtc::DesktopCapturer> capturer,
140 DesktopMediaID::Type type) 147 DesktopMediaID::Type type)
141 : task_runner_(task_runner), 148 : task_runner_(task_runner),
149 thread_(thread.Pass()),
142 desktop_capturer_(capturer.Pass()), 150 desktop_capturer_(capturer.Pass()),
143 capture_task_posted_(false), 151 capture_task_posted_(false),
144 capture_in_progress_(false), 152 capture_in_progress_(false),
145 capturer_type_(type) { 153 capturer_type_(type) {
154 DCHECK(!task_runner_.get() || !thread_.get());
155 if (thread_.get())
156 task_runner_ = thread_->message_loop_proxy();
146 } 157 }
147 158
148 DesktopCaptureDevice::Core::~Core() { 159 DesktopCaptureDevice::Core::~Core() {
149 } 160 }
150 161
151 void DesktopCaptureDevice::Core::AllocateAndStart( 162 void DesktopCaptureDevice::Core::AllocateAndStart(
152 const media::VideoCaptureParams& params, 163 const media::VideoCaptureParams& params,
153 scoped_ptr<Client> client) { 164 scoped_ptr<Client> client) {
154 DCHECK_GT(params.requested_format.frame_size.GetArea(), 0); 165 DCHECK_GT(params.requested_format.frame_size.GetArea(), 0);
155 DCHECK_GT(params.requested_format.frame_rate, 0); 166 DCHECK_GT(params.requested_format.frame_rate, 0);
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 void DesktopCaptureDevice::Core::DoSetNotificationWindowId( 400 void DesktopCaptureDevice::Core::DoSetNotificationWindowId(
390 gfx::NativeViewId window_id) { 401 gfx::NativeViewId window_id) {
391 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 402 DCHECK(task_runner_->RunsTasksOnCurrentThread());
392 DCHECK(window_id); 403 DCHECK(window_id);
393 desktop_capturer_->SetExcludedWindow(window_id); 404 desktop_capturer_->SetExcludedWindow(window_id);
394 } 405 }
395 406
396 // static 407 // static
397 scoped_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create( 408 scoped_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
398 const DesktopMediaID& source) { 409 const DesktopMediaID& source) {
399 scoped_refptr<base::SequencedWorkerPool> blocking_pool = 410 scoped_ptr<base::Thread> ui_thread;
400 BrowserThread::GetBlockingPool();
401 scoped_refptr<base::SequencedTaskRunner> task_runner =
402 blocking_pool->GetSequencedTaskRunner(
403 blocking_pool->GetSequenceToken());
404 411
405 webrtc::DesktopCaptureOptions options = 412 webrtc::DesktopCaptureOptions options =
406 webrtc::DesktopCaptureOptions::CreateDefault(); 413 webrtc::DesktopCaptureOptions::CreateDefault();
407 // Leave desktop effects enabled during WebRTC captures. 414 // Leave desktop effects enabled during WebRTC captures.
408 options.set_disable_effects(false); 415 options.set_disable_effects(false);
409 416
410 scoped_ptr<webrtc::DesktopCapturer> capturer; 417 scoped_ptr<webrtc::DesktopCapturer> capturer;
411 418
412 switch (source.type) { 419 switch (source.type) {
413 case DesktopMediaID::TYPE_SCREEN: { 420 case DesktopMediaID::TYPE_SCREEN: {
414 scoped_ptr<webrtc::ScreenCapturer> screen_capturer; 421 scoped_ptr<webrtc::ScreenCapturer> screen_capturer;
422
423 #if defined(OS_WIN)
424 bool magnification_allowed =
425 base::FieldTrialList::FindFullName("ScreenCaptureUseMagnification") ==
426 "Enabled";
427
428 if (magnification_allowed) {
429 // The magnification capturer requires running on a dedicated UI thread.
430 ui_thread.reset(new base::Thread("screenCaptureUIThread"));
431 base::Thread::Options thread_options(base::MessageLoop::TYPE_UI, 0);
432 ui_thread->StartWithOptions(thread_options);
433
434 options.set_allow_use_magnification_api(true);
435 }
436 #endif
437
415 screen_capturer.reset(webrtc::ScreenCapturer::Create(options)); 438 screen_capturer.reset(webrtc::ScreenCapturer::Create(options));
416 if (screen_capturer && screen_capturer->SelectScreen(source.id)) { 439 if (screen_capturer && screen_capturer->SelectScreen(source.id)) {
417 capturer.reset(new webrtc::DesktopAndCursorComposer( 440 capturer.reset(new webrtc::DesktopAndCursorComposer(
418 screen_capturer.release(), 441 screen_capturer.release(),
419 webrtc::MouseCursorMonitor::CreateForScreen(options, source.id))); 442 webrtc::MouseCursorMonitor::CreateForScreen(options, source.id)));
420 IncrementDesktopCaptureCounter(SCREEN_CAPTURER_CREATED); 443 IncrementDesktopCaptureCounter(SCREEN_CAPTURER_CREATED);
421 } 444 }
422 break; 445 break;
423 } 446 }
424 447
(...skipping 10 matching lines...) Expand all
435 break; 458 break;
436 } 459 }
437 460
438 default: { 461 default: {
439 NOTREACHED(); 462 NOTREACHED();
440 } 463 }
441 } 464 }
442 465
443 scoped_ptr<media::VideoCaptureDevice> result; 466 scoped_ptr<media::VideoCaptureDevice> result;
444 if (capturer) { 467 if (capturer) {
445 result.reset( 468 scoped_refptr<base::SequencedTaskRunner> task_runner;
446 new DesktopCaptureDevice(task_runner, capturer.Pass(), source.type)); 469 if (!ui_thread.get()) {
470 scoped_refptr<base::SequencedWorkerPool> blocking_pool =
471 BrowserThread::GetBlockingPool();
472 task_runner = blocking_pool->GetSequencedTaskRunner(
473 blocking_pool->GetSequenceToken());
474 }
475 result.reset(new DesktopCaptureDevice(
476 task_runner, ui_thread.Pass(), capturer.Pass(), source.type));
447 } 477 }
448 478
449 return result.Pass(); 479 return result.Pass();
450 } 480 }
451 481
452 DesktopCaptureDevice::DesktopCaptureDevice(
453 scoped_refptr<base::SequencedTaskRunner> task_runner,
454 scoped_ptr<webrtc::DesktopCapturer> capturer,
455 DesktopMediaID::Type type)
456 : core_(new Core(task_runner, capturer.Pass(), type)) {
457 }
458
459 DesktopCaptureDevice::~DesktopCaptureDevice() { 482 DesktopCaptureDevice::~DesktopCaptureDevice() {
460 StopAndDeAllocate(); 483 StopAndDeAllocate();
461 } 484 }
462 485
463 void DesktopCaptureDevice::AllocateAndStart( 486 void DesktopCaptureDevice::AllocateAndStart(
464 const media::VideoCaptureParams& params, 487 const media::VideoCaptureParams& params,
465 scoped_ptr<Client> client) { 488 scoped_ptr<Client> client) {
466 core_->AllocateAndStart(params, client.Pass()); 489 core_->AllocateAndStart(params, client.Pass());
467 } 490 }
468 491
469 void DesktopCaptureDevice::StopAndDeAllocate() { 492 void DesktopCaptureDevice::StopAndDeAllocate() {
470 core_->StopAndDeAllocate(); 493 core_->StopAndDeAllocate();
471 } 494 }
472 495
473 void DesktopCaptureDevice::SetNotificationWindowId( 496 void DesktopCaptureDevice::SetNotificationWindowId(
474 gfx::NativeViewId window_id) { 497 gfx::NativeViewId window_id) {
475 core_->SetNotificationWindowId(window_id); 498 core_->SetNotificationWindowId(window_id);
476 } 499 }
477 500
501 DesktopCaptureDevice::DesktopCaptureDevice(
502 scoped_refptr<base::SequencedTaskRunner> task_runner,
503 scoped_ptr<base::Thread> thread,
504 scoped_ptr<webrtc::DesktopCapturer> capturer,
505 DesktopMediaID::Type type)
506 : core_(new Core(task_runner, thread.Pass(), capturer.Pass(), type)) {
507 }
508
478 } // namespace content 509 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698