Commit 3b9ecca5 authored by braveyao's avatar braveyao Committed by Commit Bot

NativeDesktopMediaList: do desktop capture on an exclusive thread

webrtc::ScreenCapturerMac requires to be started and destroyed on same
thread. The current SequencedTaskRunner can't satisfy this and will
cause random crashes.
This cl is to use an exclusive capture thread as same as the one in
content/browser/media/capture/desktop_capture_device.cc.

Bug: 877982,851883
Change-Id: I6508add3660f63e1d2539dd2175a131f869a836a
Reviewed-on: https://chromium-review.googlesource.com/1199806
Commit-Queue: Weiyong Yao <braveyao@chromium.org>
Reviewed-by: default avatarJulien Isorce <julien.isorce@chromium.org>
Cr-Commit-Position: refs/heads/master@{#588151}
parent f4aa8aad
...@@ -5,8 +5,11 @@ ...@@ -5,8 +5,11 @@
#include "chrome/browser/media/webrtc/native_desktop_media_list.h" #include "chrome/browser/media/webrtc/native_desktop_media_list.h"
#include "base/hash.h" #include "base/hash.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h" #include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -76,11 +79,13 @@ gfx::ImageSkia ScaleDesktopFrame(std::unique_ptr<webrtc::DesktopFrame> frame, ...@@ -76,11 +79,13 @@ gfx::ImageSkia ScaleDesktopFrame(std::unique_ptr<webrtc::DesktopFrame> frame,
class NativeDesktopMediaList::Worker class NativeDesktopMediaList::Worker
: public webrtc::DesktopCapturer::Callback { : public webrtc::DesktopCapturer::Callback {
public: public:
Worker(base::WeakPtr<NativeDesktopMediaList> media_list, Worker(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::WeakPtr<NativeDesktopMediaList> media_list,
DesktopMediaID::Type type, DesktopMediaID::Type type,
std::unique_ptr<webrtc::DesktopCapturer> capturer); std::unique_ptr<webrtc::DesktopCapturer> capturer);
~Worker() override; ~Worker() override;
void Start();
void Refresh(const DesktopMediaID::Id& view_dialog_id); void Refresh(const DesktopMediaID::Id& view_dialog_id);
void RefreshThumbnails(const std::vector<DesktopMediaID>& native_ids, void RefreshThumbnails(const std::vector<DesktopMediaID>& native_ids,
...@@ -93,6 +98,9 @@ class NativeDesktopMediaList::Worker ...@@ -93,6 +98,9 @@ class NativeDesktopMediaList::Worker
void OnCaptureResult(webrtc::DesktopCapturer::Result result, void OnCaptureResult(webrtc::DesktopCapturer::Result result,
std::unique_ptr<webrtc::DesktopFrame> frame) override; std::unique_ptr<webrtc::DesktopFrame> frame) override;
// Task runner used for capturing operations.
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtr<NativeDesktopMediaList> media_list_; base::WeakPtr<NativeDesktopMediaList> media_list_;
DesktopMediaID::Type type_; DesktopMediaID::Type type_;
...@@ -106,17 +114,27 @@ class NativeDesktopMediaList::Worker ...@@ -106,17 +114,27 @@ class NativeDesktopMediaList::Worker
}; };
NativeDesktopMediaList::Worker::Worker( NativeDesktopMediaList::Worker::Worker(
scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::WeakPtr<NativeDesktopMediaList> media_list, base::WeakPtr<NativeDesktopMediaList> media_list,
DesktopMediaID::Type type, DesktopMediaID::Type type,
std::unique_ptr<webrtc::DesktopCapturer> capturer) std::unique_ptr<webrtc::DesktopCapturer> capturer)
: media_list_(media_list), type_(type), capturer_(std::move(capturer)) { : task_runner_(task_runner),
capturer_->Start(this); media_list_(media_list),
type_(type),
capturer_(std::move(capturer)) {}
NativeDesktopMediaList::Worker::~Worker() {
DCHECK(task_runner_->BelongsToCurrentThread());
} }
NativeDesktopMediaList::Worker::~Worker() {} void NativeDesktopMediaList::Worker::Start() {
DCHECK(task_runner_->BelongsToCurrentThread());
capturer_->Start(this);
}
void NativeDesktopMediaList::Worker::Refresh( void NativeDesktopMediaList::Worker::Refresh(
const DesktopMediaID::Id& view_dialog_id) { const DesktopMediaID::Id& view_dialog_id) {
DCHECK(task_runner_->BelongsToCurrentThread());
std::vector<SourceDescription> result; std::vector<SourceDescription> result;
webrtc::DesktopCapturer::SourceList sources; webrtc::DesktopCapturer::SourceList sources;
...@@ -163,6 +181,7 @@ void NativeDesktopMediaList::Worker::Refresh( ...@@ -163,6 +181,7 @@ void NativeDesktopMediaList::Worker::Refresh(
void NativeDesktopMediaList::Worker::RefreshThumbnails( void NativeDesktopMediaList::Worker::RefreshThumbnails(
const std::vector<DesktopMediaID>& native_ids, const std::vector<DesktopMediaID>& native_ids,
const gfx::Size& thumbnail_size) { const gfx::Size& thumbnail_size) {
DCHECK(task_runner_->BelongsToCurrentThread());
ImageHashesMap new_image_hashes; ImageHashesMap new_image_hashes;
// Get a thumbnail for each native source. // Get a thumbnail for each native source.
...@@ -210,17 +229,30 @@ NativeDesktopMediaList::NativeDesktopMediaList( ...@@ -210,17 +229,30 @@ NativeDesktopMediaList::NativeDesktopMediaList(
std::unique_ptr<webrtc::DesktopCapturer> capturer) std::unique_ptr<webrtc::DesktopCapturer> capturer)
: DesktopMediaListBase(base::TimeDelta::FromMilliseconds( : DesktopMediaListBase(base::TimeDelta::FromMilliseconds(
kDefaultNativeDesktopMediaListUpdatePeriod)), kDefaultNativeDesktopMediaListUpdatePeriod)),
thread_("DesktopMediaListCaptureThread"),
weak_factory_(this) { weak_factory_(this) {
type_ = type; type_ = type;
capture_task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE});
worker_.reset( #if defined(OS_WIN) || defined(OS_MACOSX)
new Worker(weak_factory_.GetWeakPtr(), type, std::move(capturer))); // On Windows/OSX the thread must be a UI thread.
base::MessageLoop::Type thread_type = base::MessageLoop::TYPE_UI;
#else
base::MessageLoop::Type thread_type = base::MessageLoop::TYPE_DEFAULT;
#endif
thread_.StartWithOptions(base::Thread::Options(thread_type, 0));
worker_.reset(new Worker(thread_.task_runner(), weak_factory_.GetWeakPtr(),
type, std::move(capturer)));
thread_.task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&Worker::Start, base::Unretained(worker_.get())));
} }
NativeDesktopMediaList::~NativeDesktopMediaList() { NativeDesktopMediaList::~NativeDesktopMediaList() {
capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release()); base::ThreadRestrictions::ScopedAllowIO allow_io;
thread_.task_runner()->DeleteSoon(FROM_HERE, worker_.release());
thread_.Stop();
} }
void NativeDesktopMediaList::Refresh() { void NativeDesktopMediaList::Refresh() {
...@@ -230,7 +262,7 @@ void NativeDesktopMediaList::Refresh() { ...@@ -230,7 +262,7 @@ void NativeDesktopMediaList::Refresh() {
new_aura_thumbnail_hashes_.clear(); new_aura_thumbnail_hashes_.clear();
#endif #endif
capture_task_runner_->PostTask( thread_.task_runner()->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&Worker::Refresh, base::Unretained(worker_.get()), base::BindOnce(&Worker::Refresh, base::Unretained(worker_.get()),
view_dialog_id_.id)); view_dialog_id_.id));
...@@ -280,7 +312,7 @@ void NativeDesktopMediaList::RefreshForAuraWindows( ...@@ -280,7 +312,7 @@ void NativeDesktopMediaList::RefreshForAuraWindows(
#if defined(USE_AURA) #if defined(USE_AURA)
pending_native_thumbnail_capture_ = true; pending_native_thumbnail_capture_ = true;
#endif #endif
capture_task_runner_->PostTask( thread_.task_runner()->PostTask(
FROM_HERE, base::BindOnce(&Worker::RefreshThumbnails, FROM_HERE, base::BindOnce(&Worker::RefreshThumbnails,
base::Unretained(worker_.get()), native_ids, base::Unretained(worker_.get()), native_ids,
thumbnail_size_)); thumbnail_size_));
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <memory> #include <memory>
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h" #include "base/threading/thread.h"
#include "chrome/browser/media/webrtc/desktop_media_list_base.h" #include "chrome/browser/media/webrtc/desktop_media_list_base.h"
#include "content/public/browser/desktop_media_id.h" #include "content/public/browser/desktop_media_id.h"
#include "ui/gfx/image/image.h" #include "ui/gfx/image/image.h"
...@@ -44,12 +44,7 @@ class NativeDesktopMediaList : public DesktopMediaListBase { ...@@ -44,12 +44,7 @@ class NativeDesktopMediaList : public DesktopMediaListBase {
gfx::Image image); gfx::Image image);
#endif #endif
// Task runner used for the |worker_|. base::Thread thread_;
scoped_refptr<base::SequencedTaskRunner> capture_task_runner_;
// An object that does all the work of getting list of sources on a background
// thread (see |capture_task_runner_|). Destroyed on |capture_task_runner_|
// after the model is destroyed.
std::unique_ptr<Worker> worker_; std::unique_ptr<Worker> worker_;
#if defined(USE_AURA) #if defined(USE_AURA)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment