Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |