#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"
#include "base/threading/sequenced_worker_pool.h"
+#include "base/threading/thread.h"
+#include "content/browser/media/capture/desktop_capture_device_uma_types.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/desktop_media_id.h"
#include "media/base/video_util.h"
public webrtc::DesktopCapturer::Callback {
public:
Core(scoped_refptr<base::SequencedTaskRunner> task_runner,
- scoped_ptr<webrtc::DesktopCapturer> capturer);
+ scoped_ptr<base::Thread> thread,
+ scoped_ptr<webrtc::DesktopCapturer> capturer,
+ DesktopMediaID::Type type);
// Implementation of VideoCaptureDevice methods.
void AllocateAndStart(const media::VideoCaptureParams& params,
// Task runner used for capturing operations.
scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ // The thread on which the capturer is running.
+ scoped_ptr<base::Thread> thread_;
+
// The underlying DesktopCapturer instance used to capture frames.
scoped_ptr<webrtc::DesktopCapturer> desktop_capturer_;
// True when waiting for |desktop_capturer_| to capture current frame.
bool capture_in_progress_;
+ // The type of the capturer.
+ DesktopMediaID::Type capturer_type_;
+
DISALLOW_COPY_AND_ASSIGN(Core);
};
DesktopCaptureDevice::Core::Core(
scoped_refptr<base::SequencedTaskRunner> task_runner,
- scoped_ptr<webrtc::DesktopCapturer> capturer)
+ scoped_ptr<base::Thread> thread,
+ scoped_ptr<webrtc::DesktopCapturer> capturer,
+ DesktopMediaID::Type type)
: task_runner_(task_runner),
+ thread_(thread.Pass()),
desktop_capturer_(capturer.Pass()),
capture_task_posted_(false),
- capture_in_progress_(false) {}
+ capture_in_progress_(false),
+ capturer_type_(type) {
+ DCHECK(!task_runner_.get() || !thread_.get());
+ if (thread_.get())
+ task_runner_ = thread_->message_loop_proxy();
+}
DesktopCaptureDevice::Core::~Core() {
}
DCHECK(task_runner_->RunsTasksOnCurrentThread());
DCHECK(capture_in_progress_);
+ static bool first_call = true;
+ if (first_call) {
+ first_call = false;
+ if (capturer_type_ == DesktopMediaID::TYPE_SCREEN) {
+ IncrementDesktopCaptureCounter(frame ? FIRST_SCREEN_CAPTURE_SUCCEEDED
+ : FIRST_SCREEN_CAPTURE_FAILED);
+ } else {
+ IncrementDesktopCaptureCounter(frame ? FIRST_WINDOW_CAPTURE_SUCCEEDED
+ : FIRST_WINDOW_CAPTURE_FAILED);
+ }
+ }
+
capture_in_progress_ = false;
if (!frame) {
if (!client_)
return;
+ base::TimeDelta capture_time(
+ base::TimeDelta::FromMilliseconds(frame->capture_time_ms()));
+ UMA_HISTOGRAM_TIMES(
+ capturer_type_ == DesktopMediaID::TYPE_SCREEN ? kUmaScreenCaptureTime
+ : kUmaWindowCaptureTime,
+ capture_time);
+
scoped_ptr<webrtc::DesktopFrame> owned_frame(frame);
// Handle initial frame size and size changes.
// static
scoped_ptr<media::VideoCaptureDevice> DesktopCaptureDevice::Create(
const DesktopMediaID& source) {
- scoped_refptr<base::SequencedWorkerPool> blocking_pool =
- BrowserThread::GetBlockingPool();
- scoped_refptr<base::SequencedTaskRunner> task_runner =
- blocking_pool->GetSequencedTaskRunner(
- blocking_pool->GetSequenceToken());
+ scoped_ptr<base::Thread> ui_thread;
webrtc::DesktopCaptureOptions options =
webrtc::DesktopCaptureOptions::CreateDefault();
switch (source.type) {
case DesktopMediaID::TYPE_SCREEN: {
scoped_ptr<webrtc::ScreenCapturer> screen_capturer;
+
+#if defined(OS_WIN)
+ bool magnification_allowed =
+ base::FieldTrialList::FindFullName("ScreenCaptureUseMagnification") ==
+ "Enabled";
+
+ if (magnification_allowed) {
+ // The magnification capturer requires running on a dedicated UI thread.
+ ui_thread.reset(new base::Thread("screenCaptureUIThread"));
+ base::Thread::Options thread_options(base::MessageLoop::TYPE_UI, 0);
+ ui_thread->StartWithOptions(thread_options);
+
+ options.set_allow_use_magnification_api(true);
+ }
+#endif
+
screen_capturer.reset(webrtc::ScreenCapturer::Create(options));
if (screen_capturer && screen_capturer->SelectScreen(source.id)) {
capturer.reset(new webrtc::DesktopAndCursorComposer(
screen_capturer.release(),
webrtc::MouseCursorMonitor::CreateForScreen(options, source.id)));
+ IncrementDesktopCaptureCounter(SCREEN_CAPTURER_CREATED);
}
break;
}
capturer.reset(new webrtc::DesktopAndCursorComposer(
window_capturer.release(),
webrtc::MouseCursorMonitor::CreateForWindow(options, source.id)));
+ IncrementDesktopCaptureCounter(WINDOW_CATPTURER_CREATED);
}
break;
}
}
scoped_ptr<media::VideoCaptureDevice> result;
- if (capturer)
- result.reset(new DesktopCaptureDevice(task_runner, capturer.Pass()));
+ if (capturer) {
+ scoped_refptr<base::SequencedTaskRunner> task_runner;
+ if (!ui_thread.get()) {
+ scoped_refptr<base::SequencedWorkerPool> blocking_pool =
+ BrowserThread::GetBlockingPool();
+ task_runner = blocking_pool->GetSequencedTaskRunner(
+ blocking_pool->GetSequenceToken());
+ }
+ result.reset(new DesktopCaptureDevice(
+ task_runner, ui_thread.Pass(), capturer.Pass(), source.type));
+ }
return result.Pass();
}
-DesktopCaptureDevice::DesktopCaptureDevice(
- scoped_refptr<base::SequencedTaskRunner> task_runner,
- scoped_ptr<webrtc::DesktopCapturer> capturer)
- : core_(new Core(task_runner, capturer.Pass())) {}
-
DesktopCaptureDevice::~DesktopCaptureDevice() {
StopAndDeAllocate();
}
core_->SetNotificationWindowId(window_id);
}
+DesktopCaptureDevice::DesktopCaptureDevice(
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
+ scoped_ptr<base::Thread> thread,
+ scoped_ptr<webrtc::DesktopCapturer> capturer,
+ DesktopMediaID::Type type)
+ : core_(new Core(task_runner, thread.Pass(), capturer.Pass(), type)) {
+}
+
} // namespace content