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

Unified Diff: media/gpu/android_video_decode_accelerator.cc

Issue 2245333004: Convert AVDAs thread hang detection to be timer based (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/gpu/android_video_decode_accelerator.cc
diff --git a/media/gpu/android_video_decode_accelerator.cc b/media/gpu/android_video_decode_accelerator.cc
index 41d3f550768b03219f98c57608a678c0e74ca8ad..2d88fd050d6a564576c1a9b62925ed8b09862eb2 100644
--- a/media/gpu/android_video_decode_accelerator.cc
+++ b/media/gpu/android_video_decode_accelerator.cc
@@ -172,6 +172,63 @@ class AndroidVideoDecodeAccelerator::OnFrameAvailableHandler
DISALLOW_COPY_AND_ASSIGN(OnFrameAvailableHandler);
};
+class TaskCountingTaskRunner : public base::SingleThreadTaskRunner {
+ public:
+ TaskCountingTaskRunner(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner)
+ : task_runner_(task_runner), pending_tasks_(0) {}
+
+ bool PostDelayedTask(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) override {
+ IncrementPendingTasks();
+ return task_runner_->PostDelayedTask(
+ from_here,
+ base::Bind(&TaskCountingTaskRunner::RunClosureAndDecrementPendingTasks,
+ base::Unretained(this), task),
liberato (no reviews please) 2016/08/16 23:08:36 not sure if this should be unretained. seems like
+ delay);
+ }
+
+ bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
+ const base::Closure& task,
+ base::TimeDelta delay) override {
+ IncrementPendingTasks();
+ return task_runner_->PostNonNestableDelayedTask(
+ from_here,
+ base::Bind(&TaskCountingTaskRunner::RunClosureAndDecrementPendingTasks,
+ base::Unretained(this), task),
liberato (no reviews please) 2016/08/16 23:08:36 same question.
+ delay);
+ }
+
+ bool RunsTasksOnCurrentThread() const override {
+ return task_runner_->RunsTasksOnCurrentThread();
+ }
+
+ int PendingTaskCount() {
+ base::AutoLock l(lock_);
+ return pending_tasks_;
+ }
+
+ private:
+ void IncrementPendingTasks() {
+ base::AutoLock l(lock_);
+ pending_tasks_++;
+ }
+
+ void RunClosureAndDecrementPendingTasks(const base::Closure& task) {
+ task.Run();
+ base::AutoLock l(lock_);
+ pending_tasks_--;
+ }
+
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+ base::Lock lock_;
+ int pending_tasks_;
+
+ DISALLOW_COPY_AND_ASSIGN(TaskCountingTaskRunner);
+};
+
// AVDAManager manages shared resources for a number of AVDA instances.
// Its responsibilities include:
// - Starting and stopping a shared "construction" thread for instantiating and
@@ -196,6 +253,8 @@ class AVDAManager {
LOG(ERROR) << "Failed to start construction thread.";
return false;
}
+ task_runner_ =
+ new TaskCountingTaskRunner(construction_thread_.task_runner());
}
thread_avda_instances_.insert(avda);
@@ -214,11 +273,7 @@ class AVDAManager {
if (!thread_avda_instances_.empty())
return;
- // Don't stop the thread if there are outstanding requests, since they
- // might be hung. They also might simply be incomplete, and the thread
- // will stay running until we try to shut it down again.
- base::AutoLock auto_lock(autodetection_info_.lock_);
- if (autodetection_info_.outstanding_)
+ if (task_runner_ && task_runner_->PendingTaskCount() > 0)
return;
construction_thread_.Stop();
@@ -261,36 +316,13 @@ class AVDAManager {
scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() {
DCHECK(thread_checker_.CalledOnValidThread());
- return construction_thread_.task_runner();
- }
-
- // Called on the main thread when the construction thread will be doing work
- // that can potentially hang (e.g., autodetection). There may be several
- // calls to this before any call to DoneUsingConstructionThread.
- // Note that this should only be called from the main thread, else it's a race
- // with IsCodecAutodetectionProbablySafe.
- void StartUsingConstructionThread() {
- DCHECK(thread_checker_.CalledOnValidThread());
- base::AutoLock auto_lock(autodetection_info_.lock_);
- ++autodetection_info_.outstanding_;
- }
-
- // Called on any thread after the potentially dangerous construction thread
- // work completes safely. May be called on any thread, including the
- // construction thread.
- // This assumes that requests are ordered, so please don't mix sync and async
- // codec construction here.
- void DoneUsingConstructionThread() {
- base::AutoLock auto_lock_l(autodetection_info_.lock_);
- DCHECK_GT(autodetection_info_.outstanding_, 0);
- --autodetection_info_.outstanding_;
+ return task_runner_;
}
// Return a hint about whether autodetecting the codec type is safe or not.
bool IsCodecAutodetectionProbablySafe() {
- base::AutoLock auto_lock_l(autodetection_info_.lock_);
-
- return autodetection_info_.outstanding_ < kMaxConcurrentCodecAutodetections;
+ return task_runner_ &&
+ task_runner_->PendingTaskCount() < kMaxConcurrentCodecAutodetections;
}
// |avda| would like to use |surface_id|. If it is not busy, then mark it
@@ -398,16 +430,8 @@ class AVDAManager {
// Repeating timer responsible for draining pending IO to the codecs.
base::RepeatingTimer io_timer_;
- // Data for determining if codec creation is hanging.
- struct {
- // Lock that protects other members of this struct.
- base::Lock lock_;
-
- // Number of currently pending work items of the construction thread.
- int outstanding_ = 0;
- } autodetection_info_;
-
base::Thread construction_thread_;
+ scoped_refptr<TaskCountingTaskRunner> task_runner_;
base::ThreadChecker thread_checker_;
@@ -1111,8 +1135,6 @@ void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
}
codec_config_->notify_completion_ = codec_config_->allow_autodetection_;
- if (codec_config_->allow_autodetection_)
- g_avda_manager.Get().StartUsingConstructionThread();
// If we're not trying autodetection, then use the main thread. The original
// might be blocked.
@@ -1168,11 +1190,6 @@ AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread(
codec_config->surface_.j_surface().obj(), media_crypto, true,
require_software_codec));
- // If we successfully completed after an autodetect, then let the other
- // instances know that we didn't get stuck.
- if (codec_config->notify_completion_)
- g_avda_manager.Get().DoneUsingConstructionThread();
-
return codec;
}
@@ -1683,13 +1700,8 @@ void AndroidVideoDecodeAccelerator::ReleaseMediaCodec() {
if (!codec_config_->allow_autodetection_) {
media_codec_.reset();
} else {
- g_avda_manager.Get().StartUsingConstructionThread();
- scoped_refptr<base::SingleThreadTaskRunner> task_runner =
- g_avda_manager.Get().ConstructionTaskRunner();
- task_runner->DeleteSoon(FROM_HERE, media_codec_.release());
- task_runner->PostTask(
- FROM_HERE, base::Bind(&AVDAManager::DoneUsingConstructionThread,
- base::Unretained(g_avda_manager.Pointer())));
+ g_avda_manager.Get().ConstructionTaskRunner()->DeleteSoon(
+ FROM_HERE, media_codec_.release());
}
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698