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

Side by Side 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: timeout 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 unified diff | Download patch
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "media/gpu/android_video_decode_accelerator.h" 5 #include "media/gpu/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "base/android/build_info.h" 11 #include "base/android/build_info.h"
12 #include "base/auto_reset.h" 12 #include "base/auto_reset.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/callback_helpers.h" 15 #include "base/callback_helpers.h"
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
18 #include "base/logging.h" 18 #include "base/logging.h"
19 #include "base/message_loop/message_loop.h"
19 #include "base/metrics/histogram.h" 20 #include "base/metrics/histogram.h"
20 #include "base/task_runner_util.h" 21 #include "base/task_runner_util.h"
21 #include "base/threading/thread_checker.h" 22 #include "base/threading/thread_checker.h"
22 #include "base/threading/thread_task_runner_handle.h" 23 #include "base/threading/thread_task_runner_handle.h"
23 #include "base/trace_event/trace_event.h" 24 #include "base/trace_event/trace_event.h"
24 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 25 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
25 #include "gpu/command_buffer/service/mailbox_manager.h" 26 #include "gpu/command_buffer/service/mailbox_manager.h"
26 #include "gpu/ipc/service/gpu_channel.h" 27 #include "gpu/ipc/service/gpu_channel.h"
27 #include "media/base/android/media_codec_bridge.h" 28 #include "media/base/android/media_codec_bridge.h"
28 #include "media/base/android/media_codec_util.h" 29 #include "media/base/android/media_codec_util.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 99
99 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); 100 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0);
100 101
101 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); 102 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1);
102 103
103 // Time between when we notice an error, and when we actually notify somebody. 104 // Time between when we notice an error, and when we actually notify somebody.
104 // This is to prevent codec errors caused by SurfaceView fullscreen transitions 105 // This is to prevent codec errors caused by SurfaceView fullscreen transitions
105 // from breaking the pipeline, if we're about to be reset anyway. 106 // from breaking the pipeline, if we're about to be reset anyway.
106 constexpr base::TimeDelta ErrorPostingDelay = base::TimeDelta::FromSeconds(2); 107 constexpr base::TimeDelta ErrorPostingDelay = base::TimeDelta::FromSeconds(2);
107 108
109 constexpr base::TimeDelta kHungTaskDetectionTimeout =
110 base::TimeDelta::FromSeconds(2);
111
108 // Maximum number of concurrent, incomplete codec creations that we'll allow 112 // Maximum number of concurrent, incomplete codec creations that we'll allow
109 // before turning off autodection of codec type. 113 // before turning off autodection of codec type.
110 enum { kMaxConcurrentCodecAutodetections = 4 }; 114 enum { kMaxConcurrentCodecAutodetections = 4 };
111 115
112 // For RecordFormatChangedMetric. 116 // For RecordFormatChangedMetric.
113 enum FormatChangedValue { 117 enum FormatChangedValue {
114 CodecInitialized = false, 118 CodecInitialized = false,
115 MissingFormatChanged = true 119 MissingFormatChanged = true
116 }; 120 };
117 121
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 // - Starting and stopping a shared "construction" thread for instantiating and 181 // - Starting and stopping a shared "construction" thread for instantiating and
178 // releasing MediaCodecs. 182 // releasing MediaCodecs.
179 // - Tracking the number of outstanding tasks running on the construction 183 // - Tracking the number of outstanding tasks running on the construction
180 // thread. (For detecting when one of those tasks has hung indefinitely.) 184 // thread. (For detecting when one of those tasks has hung indefinitely.)
181 // - Running a RepeatingTimer so that AVDAs can get a regular callback to 185 // - Running a RepeatingTimer so that AVDAs can get a regular callback to
182 // DoIOTask(). 186 // DoIOTask().
183 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when 187 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when
184 // surfaces are released. 188 // surfaces are released.
185 class AVDAManager { 189 class AVDAManager {
186 public: 190 public:
191 class HangDetector : public base::MessageLoop::TaskObserver {
192 public:
193 HangDetector() {}
194
195 void WillProcessTask(const base::PendingTask& pending_task) override {
196 base::AutoLock l(lock_);
197 task_start_time_ = base::TimeTicks::Now();
198 }
199
200 void DidProcessTask(const base::PendingTask& pending_task) override {
201 base::AutoLock l(lock_);
202 task_start_time_.reset();
203 }
204
205 void Reset() {
206 base::AutoLock l(lock_);
207 task_start_time_.reset();
208 }
209
210 bool ThreadLikelyHung() {
211 base::AutoLock l(lock_);
212 if (task_start_time_.has_value()) {
DaleCurtis 2016/08/17 04:58:45 is_null() is sufficient, ticks never starts at zer
213 return (base::TimeTicks::Now() - task_start_time_.value()) >
214 kHungTaskDetectionTimeout;
215 }
216 return false;
217 }
218
219 private:
220 base::Lock lock_;
221 base::Optional<base::TimeTicks> task_start_time_;
222
223 DISALLOW_COPY_AND_ASSIGN(HangDetector);
224 };
225
187 // Make sure that the construction thread is started for |avda|. 226 // Make sure that the construction thread is started for |avda|.
188 bool StartThread(AndroidVideoDecodeAccelerator* avda) { 227 bool StartThread(AndroidVideoDecodeAccelerator* avda) {
189 DCHECK(thread_checker_.CalledOnValidThread()); 228 DCHECK(thread_checker_.CalledOnValidThread());
190 229
191 // If we chose not to shut it down due to pending codec constructions, then 230 // If we chose not to shut it down due to pending codec constructions, then
192 // the thread might already be started even if there are no avda instances. 231 // the thread might already be started even if there are no avda instances.
193 // Plus, sometimes we just fail to start the thread. 232 // Plus, sometimes we just fail to start the thread.
194 if (!construction_thread_.IsRunning()) { 233 if (!construction_thread_.IsRunning()) {
195 if (!construction_thread_.Start()) { 234 if (!construction_thread_.Start()) {
196 LOG(ERROR) << "Failed to start construction thread."; 235 LOG(ERROR) << "Failed to start construction thread.";
197 return false; 236 return false;
198 } 237 }
238 construction_thread_.task_runner()->PostTask(
239 FROM_HERE,
240 base::Bind(&base::MessageLoop::AddTaskObserver,
241 base::Unretained(construction_thread_.message_loop()),
242 &hang_detector_));
199 } 243 }
200 244
201 thread_avda_instances_.insert(avda); 245 thread_avda_instances_.insert(avda);
202 UMA_HISTOGRAM_ENUMERATION("Media.AVDA.NumAVDAInstances", 246 UMA_HISTOGRAM_ENUMERATION("Media.AVDA.NumAVDAInstances",
203 thread_avda_instances_.size(), 247 thread_avda_instances_.size(),
204 31); // PRESUBMIT_IGNORE_UMA_MAX 248 31); // PRESUBMIT_IGNORE_UMA_MAX
205 return true; 249 return true;
206 } 250 }
207 251
208 // |avda| will no longer need the construction thread. Stop the thread if 252 // |avda| will no longer need the construction thread. Stop the thread if
209 // this is the last instance. 253 // this is the last instance.
210 void StopThread(AndroidVideoDecodeAccelerator* avda) { 254 void StopThread(AndroidVideoDecodeAccelerator* avda) {
211 DCHECK(thread_checker_.CalledOnValidThread()); 255 DCHECK(thread_checker_.CalledOnValidThread());
212 256
213 thread_avda_instances_.erase(avda); 257 thread_avda_instances_.erase(avda);
liberato (no reviews please) 2016/08/17 15:15:42 if we end up not resetting below, then i think tha
214 if (!thread_avda_instances_.empty()) 258 if (!thread_avda_instances_.empty())
215 return; 259 return;
216 260
217 // Don't stop the thread if there are outstanding requests, since they 261 // TODO: post a task to stop the thread.
liberato (no reviews please) 2016/08/17 15:15:42 not sure that posting a task to stop the thread is
218 // might be hung. They also might simply be incomplete, and the thread 262 hang_detector_.Reset();
liberato (no reviews please) 2016/08/17 15:15:42 i don't think that it should reset here. for exam
219 // will stay running until we try to shut it down again.
220 base::AutoLock auto_lock(autodetection_info_.lock_);
221 if (autodetection_info_.outstanding_)
222 return;
223
224 construction_thread_.Stop();
225 } 263 }
226 264
227 // Request periodic callback of |avda|->DoIOTask(). Does nothing if the 265 // Request periodic callback of |avda|->DoIOTask(). Does nothing if the
228 // instance is already registered and the timer started. The first request 266 // instance is already registered and the timer started. The first request
229 // will start the repeating timer on an interval of DecodePollDelay. 267 // will start the repeating timer on an interval of DecodePollDelay.
230 void StartTimer(AndroidVideoDecodeAccelerator* avda) { 268 void StartTimer(AndroidVideoDecodeAccelerator* avda) {
231 DCHECK(thread_checker_.CalledOnValidThread()); 269 DCHECK(thread_checker_.CalledOnValidThread());
232 270
233 timer_avda_instances_.insert(avda); 271 timer_avda_instances_.insert(avda);
234 272
(...skipping 22 matching lines...) Expand all
257 timer_avda_instances_.erase(avda); 295 timer_avda_instances_.erase(avda);
258 if (timer_avda_instances_.empty()) 296 if (timer_avda_instances_.empty())
259 io_timer_.Stop(); 297 io_timer_.Stop();
260 } 298 }
261 299
262 scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() { 300 scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() {
263 DCHECK(thread_checker_.CalledOnValidThread()); 301 DCHECK(thread_checker_.CalledOnValidThread());
264 return construction_thread_.task_runner(); 302 return construction_thread_.task_runner();
265 } 303 }
266 304
267 // Called on the main thread when the construction thread will be doing work
268 // that can potentially hang (e.g., autodetection). There may be several
269 // calls to this before any call to DoneUsingConstructionThread.
270 // Note that this should only be called from the main thread, else it's a race
271 // with IsCodecAutodetectionProbablySafe.
272 void StartUsingConstructionThread() {
273 DCHECK(thread_checker_.CalledOnValidThread());
274 base::AutoLock auto_lock(autodetection_info_.lock_);
275 ++autodetection_info_.outstanding_;
276 }
277
278 // Called on any thread after the potentially dangerous construction thread
279 // work completes safely. May be called on any thread, including the
280 // construction thread.
281 // This assumes that requests are ordered, so please don't mix sync and async
282 // codec construction here.
283 void DoneUsingConstructionThread() {
284 base::AutoLock auto_lock_l(autodetection_info_.lock_);
285 DCHECK_GT(autodetection_info_.outstanding_, 0);
286 --autodetection_info_.outstanding_;
287 }
288
289 // Return a hint about whether autodetecting the codec type is safe or not. 305 // Return a hint about whether autodetecting the codec type is safe or not.
290 bool IsCodecAutodetectionProbablySafe() { 306 bool IsCodecAutodetectionProbablySafe() {
291 base::AutoLock auto_lock_l(autodetection_info_.lock_); 307 return !hang_detector_.ThreadLikelyHung();
292
293 return autodetection_info_.outstanding_ < kMaxConcurrentCodecAutodetections;
294 } 308 }
295 309
296 // |avda| would like to use |surface_id|. If it is not busy, then mark it 310 // |avda| would like to use |surface_id|. If it is not busy, then mark it
297 // as busy and return true. If it is busy, then replace any existing waiter, 311 // as busy and return true. If it is busy, then replace any existing waiter,
298 // make |avda| the current waiter, and return false. Any existing waiter 312 // make |avda| the current waiter, and return false. Any existing waiter
299 // is assumed to be on the way out, so we fail its allocation request. 313 // is assumed to be on the way out, so we fail its allocation request.
300 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { 314 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) {
301 // Nobody has to wait for no surface. 315 // Nobody has to wait for no surface.
302 if (surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID) 316 if (surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID)
303 return true; 317 return true;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 SurfaceWaiterMap surface_waiter_map_; 405 SurfaceWaiterMap surface_waiter_map_;
392 406
393 // Since we can't delete while iterating when using a set, defer erasure until 407 // Since we can't delete while iterating when using a set, defer erasure until
394 // after iteration complete. 408 // after iteration complete.
395 bool timer_running_ = false; 409 bool timer_running_ = false;
396 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; 410 std::set<AndroidVideoDecodeAccelerator*> pending_erase_;
397 411
398 // Repeating timer responsible for draining pending IO to the codecs. 412 // Repeating timer responsible for draining pending IO to the codecs.
399 base::RepeatingTimer io_timer_; 413 base::RepeatingTimer io_timer_;
400 414
401 // Data for determining if codec creation is hanging.
402 struct {
403 // Lock that protects other members of this struct.
404 base::Lock lock_;
405
406 // Number of currently pending work items of the construction thread.
407 int outstanding_ = 0;
408 } autodetection_info_;
409
410 base::Thread construction_thread_; 415 base::Thread construction_thread_;
416 HangDetector hang_detector_;
411 417
412 base::ThreadChecker thread_checker_; 418 base::ThreadChecker thread_checker_;
413 419
414 DISALLOW_COPY_AND_ASSIGN(AVDAManager); 420 DISALLOW_COPY_AND_ASSIGN(AVDAManager);
415 }; 421 };
416 422
417 static base::LazyInstance<AVDAManager>::Leaky g_avda_manager = 423 static base::LazyInstance<AVDAManager>::Leaky g_avda_manager =
418 LAZY_INSTANCE_INITIALIZER; 424 LAZY_INSTANCE_INITIALIZER;
419 425
420 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {} 426 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {}
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 g_avda_manager.Get().IsCodecAutodetectionProbablySafe(); 1109 g_avda_manager.Get().IsCodecAutodetectionProbablySafe();
1104 1110
1105 // If autodetection is disallowed, fall back to Chrome's software decoders 1111 // If autodetection is disallowed, fall back to Chrome's software decoders
1106 // instead of using the software decoders provided by MediaCodec. 1112 // instead of using the software decoders provided by MediaCodec.
1107 if (!codec_config_->allow_autodetection_ && 1113 if (!codec_config_->allow_autodetection_ &&
1108 IsMediaCodecSoftwareDecodingForbidden()) { 1114 IsMediaCodecSoftwareDecodingForbidden()) {
1109 OnCodecConfigured(nullptr); 1115 OnCodecConfigured(nullptr);
1110 return; 1116 return;
1111 } 1117 }
1112 1118
1113 codec_config_->notify_completion_ = codec_config_->allow_autodetection_;
1114 if (codec_config_->allow_autodetection_)
1115 g_avda_manager.Get().StartUsingConstructionThread();
1116
1117 // If we're not trying autodetection, then use the main thread. The original 1119 // If we're not trying autodetection, then use the main thread. The original
1118 // might be blocked. 1120 // might be blocked.
1119 scoped_refptr<base::SingleThreadTaskRunner> task_runner = 1121 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
1120 codec_config_->allow_autodetection_ 1122 codec_config_->allow_autodetection_
1121 ? g_avda_manager.Get().ConstructionTaskRunner() 1123 ? g_avda_manager.Get().ConstructionTaskRunner()
1122 : base::ThreadTaskRunnerHandle::Get(); 1124 : base::ThreadTaskRunnerHandle::Get();
1123 CHECK(task_runner); 1125 CHECK(task_runner);
1124 1126
1125 base::PostTaskAndReplyWithResult( 1127 base::PostTaskAndReplyWithResult(
1126 task_runner.get(), FROM_HERE, 1128 task_runner.get(), FROM_HERE,
1127 base::Bind(&AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread, 1129 base::Bind(&AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread,
1128 codec_config_), 1130 codec_config_),
1129 base::Bind(&AndroidVideoDecodeAccelerator::OnCodecConfigured, 1131 base::Bind(&AndroidVideoDecodeAccelerator::OnCodecConfigured,
1130 weak_this_factory_.GetWeakPtr())); 1132 weak_this_factory_.GetWeakPtr()));
1131 } 1133 }
1132 1134
1133 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { 1135 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() {
1134 state_ = WAITING_FOR_CODEC; 1136 state_ = WAITING_FOR_CODEC;
1135 1137
1136 // Decide whether to allow autodetection or not. Since we're on the main 1138 // Decide whether to allow autodetection or not. Since we're on the main
1137 // thread, and this request is unordered with respect to pending async config 1139 // thread, and this request is unordered with respect to pending async config
1138 // attempts, don't record it. It may break book-keeping, and there's not 1140 // attempts, don't record it. It may break book-keeping, and there's not
1139 // much we can do anyway. 1141 // much we can do anyway.
1140 codec_config_->allow_autodetection_ = 1142 codec_config_->allow_autodetection_ =
1141 g_avda_manager.Get().IsCodecAutodetectionProbablySafe(); 1143 g_avda_manager.Get().IsCodecAutodetectionProbablySafe();
1142 codec_config_->notify_completion_ = false;
1143 1144
1144 ReleaseMediaCodec(); 1145 ReleaseMediaCodec();
1145 std::unique_ptr<VideoCodecBridge> media_codec = 1146 std::unique_ptr<VideoCodecBridge> media_codec =
1146 ConfigureMediaCodecOnAnyThread(codec_config_); 1147 ConfigureMediaCodecOnAnyThread(codec_config_);
1147 OnCodecConfigured(std::move(media_codec)); 1148 OnCodecConfigured(std::move(media_codec));
1148 return !!media_codec_; 1149 return !!media_codec_;
1149 } 1150 }
1150 1151
1151 std::unique_ptr<VideoCodecBridge> 1152 std::unique_ptr<VideoCodecBridge>
1152 AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread( 1153 AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread(
1153 scoped_refptr<CodecConfig> codec_config) { 1154 scoped_refptr<CodecConfig> codec_config) {
1154 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec"); 1155 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec");
1155 1156
1156 jobject media_crypto = codec_config->media_crypto_ 1157 jobject media_crypto = codec_config->media_crypto_
1157 ? codec_config->media_crypto_->obj() 1158 ? codec_config->media_crypto_->obj()
1158 : nullptr; 1159 : nullptr;
1159 1160
1160 // |needs_protected_surface_| implies encrypted stream. 1161 // |needs_protected_surface_| implies encrypted stream.
1161 DCHECK(!codec_config->needs_protected_surface_ || media_crypto); 1162 DCHECK(!codec_config->needs_protected_surface_ || media_crypto);
1162 1163
1163 const bool require_software_codec = !codec_config->allow_autodetection_; 1164 const bool require_software_codec = !codec_config->allow_autodetection_;
1164 1165
1165 std::unique_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder( 1166 std::unique_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder(
1166 codec_config->codec_, codec_config->needs_protected_surface_, 1167 codec_config->codec_, codec_config->needs_protected_surface_,
1167 codec_config->initial_expected_coded_size_, 1168 codec_config->initial_expected_coded_size_,
1168 codec_config->surface_.j_surface().obj(), media_crypto, true, 1169 codec_config->surface_.j_surface().obj(), media_crypto, true,
1169 require_software_codec)); 1170 require_software_codec));
1170 1171
1171 // If we successfully completed after an autodetect, then let the other
1172 // instances know that we didn't get stuck.
1173 if (codec_config->notify_completion_)
1174 g_avda_manager.Get().DoneUsingConstructionThread();
1175
1176 return codec; 1172 return codec;
1177 } 1173 }
1178 1174
1179 void AndroidVideoDecodeAccelerator::OnCodecConfigured( 1175 void AndroidVideoDecodeAccelerator::OnCodecConfigured(
1180 std::unique_ptr<VideoCodecBridge> media_codec) { 1176 std::unique_ptr<VideoCodecBridge> media_codec) {
1181 DCHECK(thread_checker_.CalledOnValidThread()); 1177 DCHECK(thread_checker_.CalledOnValidThread());
1182 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); 1178 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED);
1183 1179
1184 // Record one instance of the codec being initialized. 1180 // Record one instance of the codec being initialized.
1185 RecordFormatChangedMetric(FormatChangedValue::CodecInitialized); 1181 RecordFormatChangedMetric(FormatChangedValue::CodecInitialized);
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 // backed by hardware, else it may hang too. Post it to the construction 1672 // backed by hardware, else it may hang too. Post it to the construction
1677 // thread, and it'll get freed if things start working. If things are 1673 // thread, and it'll get freed if things start working. If things are
1678 // already working, then it'll be freed soon. 1674 // already working, then it'll be freed soon.
1679 // 1675 //
1680 // We require software codecs when |allow_autodetection_| is false, so use 1676 // We require software codecs when |allow_autodetection_| is false, so use
1681 // the stored value as a proxy for whether the MediaCodec is software backed 1677 // the stored value as a proxy for whether the MediaCodec is software backed
1682 // or not. 1678 // or not.
1683 if (!codec_config_->allow_autodetection_) { 1679 if (!codec_config_->allow_autodetection_) {
1684 media_codec_.reset(); 1680 media_codec_.reset();
1685 } else { 1681 } else {
1686 g_avda_manager.Get().StartUsingConstructionThread(); 1682 g_avda_manager.Get().ConstructionTaskRunner()->DeleteSoon(
1687 scoped_refptr<base::SingleThreadTaskRunner> task_runner = 1683 FROM_HERE, media_codec_.release());
1688 g_avda_manager.Get().ConstructionTaskRunner();
1689 task_runner->DeleteSoon(FROM_HERE, media_codec_.release());
1690 task_runner->PostTask(
1691 FROM_HERE, base::Bind(&AVDAManager::DoneUsingConstructionThread,
1692 base::Unretained(g_avda_manager.Pointer())));
1693 } 1684 }
1694 } 1685 }
1695 1686
1696 // static 1687 // static
1697 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy( 1688 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy(
1698 const gpu::GpuPreferences& gpu_preferences) { 1689 const gpu::GpuPreferences& gpu_preferences) {
1699 return true; 1690 return true;
1700 } 1691 }
1701 1692
1702 // static 1693 // static
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1781 1772
1782 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() 1773 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden()
1783 const { 1774 const {
1784 // Prevent MediaCodec from using its internal software decoders when we have 1775 // Prevent MediaCodec from using its internal software decoders when we have
1785 // more secure and up to date versions in the renderer process. 1776 // more secure and up to date versions in the renderer process.
1786 return !config_.is_encrypted && (codec_config_->codec_ == media::kCodecVP8 || 1777 return !config_.is_encrypted && (codec_config_->codec_ == media::kCodecVP8 ||
1787 codec_config_->codec_ == media::kCodecVP9); 1778 codec_config_->codec_ == media::kCodecVP9);
1788 } 1779 }
1789 1780
1790 } // namespace media 1781 } // namespace media
OLDNEW
« no previous file with comments | « media/gpu/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698