Index: content/common/gpu/media/android_video_decode_accelerator.cc |
diff --git a/content/common/gpu/media/android_video_decode_accelerator.cc b/content/common/gpu/media/android_video_decode_accelerator.cc |
index dd8e3689ee69cef86cc7d099e4d9503ef3e0b00a..f6f30f55e0389b6b84baf3f3e3a1b5e47ae743da 100644 |
--- a/content/common/gpu/media/android_video_decode_accelerator.cc |
+++ b/content/common/gpu/media/android_video_decode_accelerator.cc |
@@ -16,6 +16,7 @@ |
#include "base/message_loop/message_loop.h" |
#include "base/metrics/histogram.h" |
#include "base/task_runner_util.h" |
+#include "base/threading/thread_checker.h" |
#include "base/trace_event/trace_event.h" |
#include "content/common/gpu/media/android_copying_backing_strategy.h" |
#include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h" |
@@ -179,16 +180,25 @@ class AndroidVideoDecodeAccelerator::OnFrameAvailableHandler |
class AVDATimerManager { |
public: |
// Make sure that the construction thread is started for |avda_instance|. |
- void StartThread(AndroidVideoDecodeAccelerator* avda_instance) { |
- if (thread_avda_instances_.empty()) |
- construction_thread_.Start(); |
+ bool StartThread(AndroidVideoDecodeAccelerator* avda_instance) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
+ if (thread_avda_instances_.empty()) { |
+ if (!construction_thread_.Start()) { |
+ LOG(ERROR) << "Failed to start construction thread."; |
+ return false; |
+ } |
+ } |
thread_avda_instances_.insert(avda_instance); |
+ return true; |
} |
// |avda_instance| will no longer need the construction thread. Stop the |
// thread if this is the last instance. |
void StopThread(AndroidVideoDecodeAccelerator* avda_instance) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
thread_avda_instances_.erase(avda_instance); |
if (thread_avda_instances_.empty()) |
construction_thread_.Stop(); |
@@ -198,6 +208,8 @@ class AVDATimerManager { |
// the instance is already registered and the timer started. The first request |
// will start the repeating timer on an interval of DecodePollDelay(). |
void StartTimer(AndroidVideoDecodeAccelerator* avda_instance) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
timer_avda_instances_.insert(avda_instance); |
// If the timer is running, StopTimer() might have been called earlier, if |
@@ -215,6 +227,8 @@ class AVDATimerManager { |
// is not registered. If there are no instances left, the repeating timer will |
// be stopped. |
void StopTimer(AndroidVideoDecodeAccelerator* avda_instance) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ |
// If the timer is running, defer erasures to avoid iterator invalidation. |
if (timer_running_) { |
pending_erase_.insert(avda_instance); |
@@ -229,6 +243,7 @@ class AVDATimerManager { |
// Eventually, we should run the timer on this thread. For now, we just keep |
// it as a convenience for construction. |
scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
return construction_thread_.task_runner(); |
} |
@@ -273,6 +288,8 @@ class AVDATimerManager { |
base::Thread construction_thread_; |
+ base::ThreadChecker thread_checker_; |
+ |
DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); |
}; |
@@ -407,7 +424,10 @@ bool AndroidVideoDecodeAccelerator::Initialize(const Config& config, |
// Start the thread for async configuration, even if we don't need it now. |
// ResetCodecState might rebuild the codec later, for example. |
- g_avda_timer.Pointer()->StartThread(this); |
+ if (!g_avda_timer.Pointer()->StartThread(this)) { |
+ LOG(ERROR) << "Failed to start thread for AVDA timer"; |
+ return false; |
+ } |
// If we are encrypted, then we aren't able to create the codec yet. |
if (is_encrypted_) |