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/memory/ref_counted.h" | |
| 19 #include "base/message_loop/message_loop.h" | 20 #include "base/message_loop/message_loop.h" |
| 20 #include "base/metrics/histogram.h" | 21 #include "base/metrics/histogram.h" |
| 21 #include "base/sys_info.h" | 22 #include "base/sys_info.h" |
| 22 #include "base/task_runner_util.h" | 23 #include "base/task_runner_util.h" |
| 23 #include "base/threading/thread.h" | 24 #include "base/threading/thread.h" |
| 24 #include "base/threading/thread_checker.h" | 25 #include "base/threading/thread_checker.h" |
| 25 #include "base/threading/thread_task_runner_handle.h" | 26 #include "base/threading/thread_task_runner_handle.h" |
| 26 #include "base/trace_event/trace_event.h" | 27 #include "base/trace_event/trace_event.h" |
| 27 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 28 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 28 #include "gpu/command_buffer/service/mailbox_manager.h" | 29 #include "gpu/command_buffer/service/mailbox_manager.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 // pictures have been fed to saturate any internal buffering). This is | 100 // pictures have been fed to saturate any internal buffering). This is |
| 100 // speculative and it's unclear that this would be a win (nor that there's a | 101 // speculative and it's unclear that this would be a win (nor that there's a |
| 101 // reasonably device-agnostic way to fill in the "believes" above). | 102 // reasonably device-agnostic way to fill in the "believes" above). |
| 102 constexpr base::TimeDelta DecodePollDelay = | 103 constexpr base::TimeDelta DecodePollDelay = |
| 103 base::TimeDelta::FromMilliseconds(10); | 104 base::TimeDelta::FromMilliseconds(10); |
| 104 | 105 |
| 105 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); | 106 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); |
| 106 | 107 |
| 107 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); | 108 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); |
| 108 | 109 |
| 110 // Time between when we notice an error, and when we actually notify somebody. | |
| 111 // This is to prevent codec errors caused by SurfaceView fullscreen transitions | |
| 112 // from breaking the pipeline, if we're about to be reset anyway. | |
| 113 constexpr base::TimeDelta ErrorPostingDelay = base::TimeDelta::FromSeconds(2); | |
| 114 | |
| 115 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), | |
| 116 // defer the surface creation until the codec is actually used if we know no | |
| 117 // software fallback exists. | |
| 118 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { | |
| 119 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 && | |
| 120 AVDACodecAllocator::Get().IsAnyRegisteredAVDA() && | |
| 121 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || | |
| 122 base::SysInfo::IsLowEndDevice()); | |
| 123 } | |
| 124 | |
| 109 } // namespace | 125 } // namespace |
| 110 | 126 |
| 111 static base::LazyInstance<AVDACodecAllocator>::Leaky g_avda_codec_allocator = | |
| 112 LAZY_INSTANCE_INITIALIZER; | |
| 113 | |
| 114 // AVDAManager manages shared resources for a number of AVDA instances. | 127 // AVDAManager manages shared resources for a number of AVDA instances. |
| 115 // Its responsibilities include: | 128 // Its responsibilities include: |
| 116 // - Starting and stopping a shared "construction" thread for instantiating and | 129 // - Starting and stopping a shared "construction" thread for instantiating and |
| 117 // releasing MediaCodecs. | 130 // releasing MediaCodecs. |
| 118 // - Detecting when a task has hung on the construction thread so AVDAs can | 131 // - Detecting when a task has hung on the construction thread so AVDAs can |
| 119 // stop using it. | 132 // stop using it. |
| 120 // - Running a RepeatingTimer so that AVDAs can get a regular callback to | 133 // - Running a RepeatingTimer so that AVDAs can get a regular callback to |
| 121 // DoIOTask(). | 134 // DoIOTask(). |
| 122 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when | 135 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when |
| 123 // surfaces are released. | 136 // surfaces are released. |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 151 if (timer_running_) { | 164 if (timer_running_) { |
| 152 pending_erase_.insert(avda); | 165 pending_erase_.insert(avda); |
| 153 return; | 166 return; |
| 154 } | 167 } |
| 155 | 168 |
| 156 timer_avda_instances_.erase(avda); | 169 timer_avda_instances_.erase(avda); |
| 157 if (timer_avda_instances_.empty()) | 170 if (timer_avda_instances_.empty()) |
| 158 io_timer_.Stop(); | 171 io_timer_.Stop(); |
| 159 } | 172 } |
| 160 | 173 |
| 161 // |avda| would like to use |surface_id|. If it is not busy, then mark it | |
| 162 // as busy and return true. If it is busy, then replace any existing waiter, | |
| 163 // make |avda| the current waiter, and return false. Any existing waiter | |
| 164 // is assumed to be on the way out, so we fail its allocation request. | |
| 165 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { | |
| 166 // Nobody has to wait for no surface. | |
| 167 if (surface_id == SurfaceManager::kNoSurfaceID) | |
| 168 return true; | |
| 169 | |
| 170 auto iter = surface_waiter_map_.find(surface_id); | |
| 171 if (iter == surface_waiter_map_.end()) { | |
| 172 // SurfaceView isn't allocated. Succeed. | |
| 173 surface_waiter_map_[surface_id].owner = avda; | |
| 174 return true; | |
| 175 } | |
| 176 | |
| 177 // SurfaceView is already allocated. | |
| 178 if (iter->second.waiter) { | |
| 179 // Some other AVDA is waiting. |avda| will replace it, so notify it | |
| 180 // that it will fail. | |
| 181 iter->second.waiter->OnSurfaceAvailable(false); | |
| 182 iter->second.waiter = nullptr; | |
| 183 } | |
| 184 | |
| 185 // |avda| is now waiting. | |
| 186 iter->second.waiter = avda; | |
| 187 return false; | |
| 188 } | |
| 189 | |
| 190 // Clear any waiting request for |surface_id| by |avda|. It is okay if | |
| 191 // |waiter| is not waiting and/or isn't the owner of |surface_id|. | |
| 192 void DeallocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { | |
| 193 SurfaceWaiterMap::iterator iter = surface_waiter_map_.find(surface_id); | |
| 194 if (iter == surface_waiter_map_.end()) | |
| 195 return; | |
| 196 | |
| 197 // If |avda| was waiting, then remove it without OnSurfaceAvailable. | |
| 198 if (iter->second.waiter == avda) | |
| 199 iter->second.waiter = nullptr; | |
| 200 | |
| 201 // If |avda| is the owner, then let the waiter have it. | |
| 202 if (iter->second.owner != avda) | |
| 203 return; | |
| 204 | |
| 205 AndroidVideoDecodeAccelerator* waiter = iter->second.waiter; | |
| 206 if (!waiter) { | |
| 207 // No waiter -- remove the record and return explicitly since |iter| is | |
| 208 // no longer valid. | |
| 209 surface_waiter_map_.erase(iter); | |
| 210 return; | |
| 211 } | |
| 212 | |
| 213 // Promote |waiter| to be the owner. | |
| 214 iter->second.owner = waiter; | |
| 215 iter->second.waiter = nullptr; | |
| 216 waiter->OnSurfaceAvailable(true); | |
| 217 } | |
| 218 | |
| 219 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), | |
| 220 // defer the surface creation until the codec is actually used if we know no | |
| 221 // software fallback exists. | |
| 222 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { | |
| 223 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 && | |
| 224 g_avda_codec_allocator.Get().IsAnyRegisteredAVDA() && | |
| 225 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || | |
| 226 base::SysInfo::IsLowEndDevice()); | |
| 227 } | |
| 228 | |
| 229 private: | 174 private: |
| 230 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; | 175 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; |
| 231 | 176 |
| 232 AVDAManager() {} | 177 AVDAManager() {} |
| 233 ~AVDAManager() { NOTREACHED(); } | 178 ~AVDAManager() { NOTREACHED(); } |
| 234 | 179 |
| 235 void RunTimer() { | 180 void RunTimer() { |
| 236 { | 181 { |
| 237 // Call out to all AVDA instances, some of which may attempt to remove | 182 // Call out to all AVDA instances, some of which may attempt to remove |
| 238 // themselves from the list during this operation; those removals will be | 183 // themselves from the list during this operation; those removals will be |
| 239 // deferred until after all iterations are complete. | 184 // deferred until after all iterations are complete. |
| 240 base::AutoReset<bool> scoper(&timer_running_, true); | 185 base::AutoReset<bool> scoper(&timer_running_, true); |
| 241 for (auto* avda : timer_avda_instances_) | 186 for (auto* avda : timer_avda_instances_) |
| 242 avda->DoIOTask(false); | 187 avda->DoIOTask(false); |
| 243 } | 188 } |
| 244 | 189 |
| 245 // Take care of any deferred erasures. | 190 // Take care of any deferred erasures. |
| 246 for (auto* avda : pending_erase_) | 191 for (auto* avda : pending_erase_) |
| 247 StopTimer(avda); | 192 StopTimer(avda); |
| 248 pending_erase_.clear(); | 193 pending_erase_.clear(); |
| 249 | 194 |
| 250 // TODO(dalecurtis): We may want to consider chunking this if task execution | 195 // TODO(dalecurtis): We may want to consider chunking this if task execution |
| 251 // takes too long for the combined timer. | 196 // takes too long for the combined timer. |
| 252 } | 197 } |
| 253 | 198 |
| 254 // All AVDA instances that would like us to poll DoIOTask. | 199 // All AVDA instances that would like us to poll DoIOTask. |
| 255 std::set<AndroidVideoDecodeAccelerator*> timer_avda_instances_; | 200 std::set<AndroidVideoDecodeAccelerator*> timer_avda_instances_; |
| 256 | 201 |
| 257 struct OwnerRecord { | |
| 258 AndroidVideoDecodeAccelerator* owner = nullptr; | |
| 259 AndroidVideoDecodeAccelerator* waiter = nullptr; | |
| 260 }; | |
| 261 // [surface id] = OwnerRecord for that surface. | |
| 262 using SurfaceWaiterMap = std::map<int, OwnerRecord>; | |
| 263 SurfaceWaiterMap surface_waiter_map_; | |
| 264 | |
| 265 // Since we can't delete while iterating when using a set, defer erasure until | 202 // Since we can't delete while iterating when using a set, defer erasure until |
| 266 // after iteration complete. | 203 // after iteration complete. |
| 267 bool timer_running_ = false; | 204 bool timer_running_ = false; |
| 268 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; | 205 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; |
| 269 | 206 |
| 270 // Repeating timer responsible for draining pending IO to the codecs. | 207 // Repeating timer responsible for draining pending IO to the codecs. |
| 271 base::RepeatingTimer io_timer_; | 208 base::RepeatingTimer io_timer_; |
| 272 | 209 |
| 273 base::ThreadChecker thread_checker_; | 210 base::ThreadChecker thread_checker_; |
| 274 | 211 |
| 275 DISALLOW_COPY_AND_ASSIGN(AVDAManager); | 212 DISALLOW_COPY_AND_ASSIGN(AVDAManager); |
| 276 }; | 213 }; |
| 277 | 214 |
| 278 static base::LazyInstance<AVDAManager>::Leaky g_avda_manager = | 215 static base::LazyInstance<AVDAManager>::Leaky g_avda_manager = |
| 279 LAZY_INSTANCE_INITIALIZER; | 216 LAZY_INSTANCE_INITIALIZER; |
| 280 | 217 |
| 281 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {} | |
| 282 | |
| 283 AndroidVideoDecodeAccelerator::CodecConfig::~CodecConfig() {} | |
| 284 | |
| 285 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( | 218 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( |
| 286 const BitstreamBuffer& bitstream_buffer) | 219 const BitstreamBuffer& bitstream_buffer) |
| 287 : buffer(bitstream_buffer) { | 220 : buffer(bitstream_buffer) { |
| 288 if (buffer.id() != -1) | 221 if (buffer.id() != -1) |
| 289 memory.reset(new SharedMemoryRegion(buffer, true)); | 222 memory.reset(new SharedMemoryRegion(buffer, true)); |
| 290 } | 223 } |
| 291 | 224 |
| 292 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( | 225 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( |
| 293 BitstreamRecord&& other) | 226 BitstreamRecord&& other) |
| 294 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {} | 227 : buffer(std::move(other.buffer)), memory(std::move(other.memory)) {} |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 309 cdm_registration_id_(0), | 242 cdm_registration_id_(0), |
| 310 pending_input_buf_index_(-1), | 243 pending_input_buf_index_(-1), |
| 311 deferred_initialization_pending_(false), | 244 deferred_initialization_pending_(false), |
| 312 codec_needs_reset_(false), | 245 codec_needs_reset_(false), |
| 313 defer_surface_creation_(false), | 246 defer_surface_creation_(false), |
| 314 weak_this_factory_(this) {} | 247 weak_this_factory_(this) {} |
| 315 | 248 |
| 316 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 249 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 317 DCHECK(thread_checker_.CalledOnValidThread()); | 250 DCHECK(thread_checker_.CalledOnValidThread()); |
| 318 g_avda_manager.Get().StopTimer(this); | 251 g_avda_manager.Get().StopTimer(this); |
| 319 g_avda_codec_allocator.Get().StopThread(this); | 252 AVDACodecAllocator::Get().StopThread(this); |
| 320 | 253 |
| 321 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 254 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 322 if (!media_drm_bridge_cdm_context_) | 255 if (!media_drm_bridge_cdm_context_) |
| 323 return; | 256 return; |
| 324 | 257 |
| 325 DCHECK(cdm_registration_id_); | 258 DCHECK(cdm_registration_id_); |
| 326 | 259 |
| 327 // Cancel previously registered callback (if any). | 260 // Cancel previously registered callback (if any). |
| 328 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( | 261 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( |
| 329 MediaDrmBridgeCdmContext::MediaCryptoReadyCB()); | 262 MediaDrmBridgeCdmContext::MediaCryptoReadyCB()); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 388 DLOG(ERROR) << "Failed to get gles2 decoder instance."; | 321 DLOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 389 return false; | 322 return false; |
| 390 } | 323 } |
| 391 | 324 |
| 392 // SetSurface() can't be called before Initialize(), so we pick up our first | 325 // SetSurface() can't be called before Initialize(), so we pick up our first |
| 393 // surface ID from the codec configuration. | 326 // surface ID from the codec configuration. |
| 394 DCHECK(!pending_surface_id_); | 327 DCHECK(!pending_surface_id_); |
| 395 | 328 |
| 396 // If we're low on resources, we may decide to defer creation of the surface | 329 // If we're low on resources, we may decide to defer creation of the surface |
| 397 // until the codec is actually used. | 330 // until the codec is actually used. |
| 398 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, | 331 if (ShouldDeferSurfaceCreation(config_.surface_id, codec_config_->codec_)) { |
| 399 codec_config_->codec_)) { | |
| 400 DCHECK(!deferred_initialization_pending_); | 332 DCHECK(!deferred_initialization_pending_); |
| 401 | |
| 402 // We should never be here if a SurfaceView is required. | 333 // We should never be here if a SurfaceView is required. |
| 403 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); | 334 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); |
| 404 DCHECK(g_avda_manager.Get().AllocateSurface(config_.surface_id, this)); | |
|
liberato (no reviews please)
2016/11/17 07:28:19
where did this go?
watk
2016/11/17 20:37:05
Ah, I added a unit test that mostly obseletes this
| |
| 405 | |
| 406 defer_surface_creation_ = true; | 335 defer_surface_creation_ = true; |
| 407 NotifyInitializationComplete(true); | 336 NotifyInitializationComplete(true); |
| 408 return true; | 337 return true; |
| 409 } | 338 } |
| 410 | 339 |
| 411 // We signaled that we support deferred initialization, so see if the client | 340 // We signaled that we support deferred initialization, so see if the client |
| 412 // does also. | 341 // does also. |
| 413 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 342 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
| 414 if (config_.is_encrypted && !deferred_initialization_pending_) { | 343 if (config_.is_encrypted && !deferred_initialization_pending_) { |
| 415 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; | 344 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; |
| 416 return false; | 345 return false; |
| 417 } | 346 } |
| 418 | 347 |
| 419 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { | 348 if (AVDACodecAllocator::Get().AllocateSurface(this, config_.surface_id)) { |
| 420 // We have successfully owned the surface, so finish initialization now. | 349 // We now own the surface, so finish initialization. |
| 421 return InitializePictureBufferManager(); | 350 return InitializePictureBufferManager(); |
| 422 } | 351 } |
| 423 | 352 |
| 424 // We have to wait for some other AVDA instance to free up the surface. | 353 // We have to wait for some other AVDA instance to free up the surface. |
| 425 // OnSurfaceAvailable will be called when it's available. | 354 // OnSurfaceAvailable will be called when it's available. |
| 426 return true; | 355 return true; |
| 427 } | 356 } |
| 428 | 357 |
| 429 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { | 358 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
| 430 DCHECK(deferred_initialization_pending_); | 359 DCHECK(deferred_initialization_pending_); |
| 431 DCHECK(!defer_surface_creation_); | 360 DCHECK(!defer_surface_creation_); |
| 432 | 361 |
| 433 if (!success || !InitializePictureBufferManager()) { | 362 if (!success || !InitializePictureBufferManager()) { |
| 434 NotifyInitializationComplete(false); | 363 NotifyInitializationComplete(false); |
| 435 deferred_initialization_pending_ = false; | 364 deferred_initialization_pending_ = false; |
| 436 } | 365 } |
| 437 } | 366 } |
| 438 | 367 |
| 439 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 368 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| 440 if (!make_context_current_cb_.Run()) { | 369 if (!make_context_current_cb_.Run()) { |
| 441 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 370 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 442 return false; | 371 return false; |
| 443 } | 372 } |
| 444 | 373 |
| 445 codec_config_->surface_ = | 374 codec_config_->surface_ = |
| 446 picture_buffer_manager_.Initialize(config_.surface_id); | 375 picture_buffer_manager_.Initialize(config_.surface_id); |
| 447 if (codec_config_->surface_.IsEmpty()) | 376 if (codec_config_->surface_.IsEmpty()) |
| 448 return false; | 377 return false; |
| 449 | 378 |
| 450 on_destroying_surface_cb_ = | 379 if (!AVDACodecAllocator::Get().StartThread(this)) |
| 451 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, | |
| 452 weak_this_factory_.GetWeakPtr()); | |
| 453 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( | |
| 454 on_destroying_surface_cb_); | |
| 455 | |
| 456 if (!g_avda_codec_allocator.Get().StartThread(this)) | |
| 457 return false; | 380 return false; |
| 458 | 381 |
| 459 // If we are encrypted, then we aren't able to create the codec yet. | 382 // If we are encrypted, then we aren't able to create the codec yet. |
| 460 if (config_.is_encrypted) { | 383 if (config_.is_encrypted) { |
| 461 InitializeCdm(); | 384 InitializeCdm(); |
| 462 return true; | 385 return true; |
| 463 } | 386 } |
| 464 | 387 |
| 465 if (deferred_initialization_pending_ || defer_surface_creation_) { | 388 if (deferred_initialization_pending_ || defer_surface_creation_) { |
| 466 defer_surface_creation_ = false; | 389 defer_surface_creation_ = false; |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 950 | 873 |
| 951 if (state_ == SURFACE_DESTROYED || defer_surface_creation_) | 874 if (state_ == SURFACE_DESTROYED || defer_surface_creation_) |
| 952 NotifyFlushDone(); | 875 NotifyFlushDone(); |
| 953 else | 876 else |
| 954 StartCodecDrain(DRAIN_FOR_FLUSH); | 877 StartCodecDrain(DRAIN_FOR_FLUSH); |
| 955 } | 878 } |
| 956 | 879 |
| 957 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 880 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
| 958 DCHECK(thread_checker_.CalledOnValidThread()); | 881 DCHECK(thread_checker_.CalledOnValidThread()); |
| 959 | 882 |
| 960 // It's probably okay just to return here, since the codec will be configured | |
| 961 // asynchronously. It's unclear that any state for the new request could | |
| 962 // be different, unless somebody modifies |codec_config_| while we're already | |
| 963 // waiting for a codec. One shouldn't do that for thread safety. | |
| 964 DCHECK_NE(state_, WAITING_FOR_CODEC); | 883 DCHECK_NE(state_, WAITING_FOR_CODEC); |
| 965 | |
| 966 state_ = WAITING_FOR_CODEC; | 884 state_ = WAITING_FOR_CODEC; |
| 967 | 885 |
| 968 // Tell the picture buffer manager that we're changing codecs. The codec | |
| 969 // itself could be used normally, since we don't replace it until we're back | |
| 970 // on the main thread. However, if we're using an output surface, then the | |
| 971 // incoming codec might access that surface while the main thread is drawing. | |
| 972 // Telling the manager to forget the codec avoids this. | |
| 973 if (media_codec_) { | 886 if (media_codec_) { |
| 974 ReleaseMediaCodec(); | 887 AVDACodecAllocator::Get().ReleaseMediaCodec( |
| 888 std::move(media_codec_), codec_config_->task_type_, config_.surface_id); | |
| 975 picture_buffer_manager_.CodecChanged(nullptr); | 889 picture_buffer_manager_.CodecChanged(nullptr); |
| 976 } | 890 } |
| 977 | 891 |
| 978 codec_config_->task_type_ = | 892 codec_config_->task_type_ = AVDACodecAllocator::Get().TaskTypeForAllocation(); |
| 979 g_avda_codec_allocator.Get().TaskTypeForAllocation(); | 893 if (codec_config_->task_type_ == TaskType::FAILED_CODEC) { |
| 980 if (codec_config_->task_type_ == AVDACodecAllocator::TaskType::FAILED_CODEC) { | |
| 981 // If there is no free thread, then just fail. | 894 // If there is no free thread, then just fail. |
| 982 OnCodecConfigured(nullptr); | 895 OnCodecConfigured(nullptr); |
| 983 return; | 896 return; |
| 984 } | 897 } |
| 985 | 898 |
| 986 // If autodetection is disallowed, fall back to Chrome's software decoders | 899 // If autodetection is disallowed, fall back to Chrome's software decoders |
| 987 // instead of using the software decoders provided by MediaCodec. | 900 // instead of using the software decoders provided by MediaCodec. |
| 988 if (codec_config_->task_type_ == AVDACodecAllocator::TaskType::SW_CODEC && | 901 if (codec_config_->task_type_ == TaskType::SW_CODEC && |
| 989 IsMediaCodecSoftwareDecodingForbidden()) { | 902 IsMediaCodecSoftwareDecodingForbidden()) { |
| 990 OnCodecConfigured(nullptr); | 903 OnCodecConfigured(nullptr); |
| 991 return; | 904 return; |
| 992 } | 905 } |
| 993 | 906 |
| 994 base::PostTaskAndReplyWithResult( | 907 AVDACodecAllocator::Get().CreateMediaCodecAsync( |
| 995 g_avda_codec_allocator.Get() | 908 weak_this_factory_.GetWeakPtr(), codec_config_); |
| 996 .TaskRunnerFor(codec_config_->task_type_) | |
| 997 .get(), | |
| 998 FROM_HERE, | |
| 999 base::Bind(&AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread, | |
| 1000 codec_config_), | |
| 1001 base::Bind(&AndroidVideoDecodeAccelerator::OnCodecConfigured, | |
| 1002 weak_this_factory_.GetWeakPtr())); | |
| 1003 } | 909 } |
| 1004 | 910 |
| 1005 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { | 911 bool AndroidVideoDecodeAccelerator::ConfigureMediaCodecSynchronously() { |
| 1006 state_ = WAITING_FOR_CODEC; | 912 state_ = WAITING_FOR_CODEC; |
| 1007 | 913 |
| 1008 ReleaseMediaCodec(); | 914 codec_config_->task_type_ = AVDACodecAllocator::Get().TaskTypeForAllocation(); |
| 1009 | 915 if (codec_config_->task_type_ == TaskType::FAILED_CODEC) { |
| 1010 codec_config_->task_type_ = | |
| 1011 g_avda_codec_allocator.Get().TaskTypeForAllocation(); | |
| 1012 if (codec_config_->task_type_ == AVDACodecAllocator::TaskType::FAILED_CODEC) { | |
| 1013 OnCodecConfigured(nullptr); | 916 OnCodecConfigured(nullptr); |
| 1014 return false; | 917 return false; |
| 1015 } | 918 } |
| 1016 | 919 |
| 1017 std::unique_ptr<VideoCodecBridge> media_codec = | 920 std::unique_ptr<VideoCodecBridge> media_codec = |
| 1018 ConfigureMediaCodecOnAnyThread(codec_config_); | 921 AVDACodecAllocator::Get().CreateMediaCodecSync(codec_config_); |
| 1019 OnCodecConfigured(std::move(media_codec)); | 922 OnCodecConfigured(std::move(media_codec)); |
| 1020 return !!media_codec_; | 923 return !!media_codec_; |
| 1021 } | 924 } |
| 1022 | 925 |
| 1023 std::unique_ptr<VideoCodecBridge> | |
| 1024 AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread( | |
| 1025 scoped_refptr<CodecConfig> codec_config) { | |
| 1026 TRACE_EVENT0("media", "AVDA::ConfigureMediaCodec"); | |
| 1027 | |
| 1028 jobject media_crypto = codec_config->media_crypto_ | |
| 1029 ? codec_config->media_crypto_->obj() | |
| 1030 : nullptr; | |
| 1031 | |
| 1032 // |needs_protected_surface_| implies encrypted stream. | |
| 1033 DCHECK(!codec_config->needs_protected_surface_ || media_crypto); | |
| 1034 | |
| 1035 const bool require_software_codec = | |
| 1036 codec_config->task_type_ == AVDACodecAllocator::TaskType::SW_CODEC; | |
| 1037 | |
| 1038 std::unique_ptr<VideoCodecBridge> codec(VideoCodecBridge::CreateDecoder( | |
| 1039 codec_config->codec_, codec_config->needs_protected_surface_, | |
| 1040 codec_config->initial_expected_coded_size_, | |
| 1041 codec_config->surface_.j_surface().obj(), media_crypto, | |
| 1042 codec_config->csd0_, codec_config->csd1_, true, require_software_codec)); | |
| 1043 | |
| 1044 return codec; | |
| 1045 } | |
| 1046 | |
| 1047 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 926 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
| 1048 std::unique_ptr<VideoCodecBridge> media_codec) { | 927 std::unique_ptr<VideoCodecBridge> media_codec) { |
| 1049 DCHECK(thread_checker_.CalledOnValidThread()); | 928 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1050 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); | 929 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
| 1051 | 930 |
| 1052 // If we are supposed to notify that initialization is complete, then do so | 931 // If we are supposed to notify that initialization is complete, then do so |
| 1053 // now. Otherwise, this is a reconfiguration. | 932 // now. Otherwise, this is a reconfiguration. |
| 1054 if (deferred_initialization_pending_) { | 933 if (deferred_initialization_pending_) { |
| 1055 // Losing the output surface is not considered an error state, so notify | 934 // Losing the output surface is not considered an error state, so notify |
| 1056 // success. The client will destroy this soon. | 935 // success. The client will destroy this soon. |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1226 StartCodecDrain(DRAIN_FOR_RESET); | 1105 StartCodecDrain(DRAIN_FOR_RESET); |
| 1227 } else { | 1106 } else { |
| 1228 ResetCodecState(); | 1107 ResetCodecState(); |
| 1229 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1108 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1230 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 1109 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| 1231 weak_this_factory_.GetWeakPtr())); | 1110 weak_this_factory_.GetWeakPtr())); |
| 1232 } | 1111 } |
| 1233 } | 1112 } |
| 1234 | 1113 |
| 1235 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { | 1114 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { |
| 1115 DVLOG(1) << __func__; | |
| 1116 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1117 | |
| 1236 if (surface_id == config_.surface_id) { | 1118 if (surface_id == config_.surface_id) { |
| 1237 pending_surface_id_.reset(); | 1119 pending_surface_id_.reset(); |
| 1238 return; | 1120 return; |
| 1239 } | 1121 } |
| 1240 | 1122 |
| 1241 // Surface changes never take effect immediately, they will be handled during | 1123 // Surface changes never take effect immediately, they will be handled during |
| 1242 // DequeOutput() once we get to a good switch point or immediately during an | 1124 // DequeOutput() once we get to a good switch point or immediately during an |
| 1243 // OnDestroyingSurface() call. | 1125 // OnSurfaceDestroyed() call. |
| 1244 pending_surface_id_ = surface_id; | 1126 pending_surface_id_ = surface_id; |
| 1245 } | 1127 } |
| 1246 | 1128 |
| 1247 void AndroidVideoDecodeAccelerator::Destroy() { | 1129 void AndroidVideoDecodeAccelerator::Destroy() { |
| 1248 DVLOG(1) << __FUNCTION__; | 1130 DVLOG(1) << __FUNCTION__; |
| 1249 DCHECK(thread_checker_.CalledOnValidThread()); | 1131 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1250 | 1132 |
| 1251 picture_buffer_manager_.Destroy(output_picture_buffers_); | 1133 picture_buffer_manager_.Destroy(output_picture_buffers_); |
| 1252 | 1134 |
| 1253 client_ = nullptr; | 1135 client_ = nullptr; |
| 1254 | 1136 |
| 1255 // Some VP8 files require a complete MediaCodec drain before we can call | 1137 // Some VP8 files require a complete MediaCodec drain before we can call |
| 1256 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In | 1138 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In |
| 1257 // that case, postpone ActualDestroy() until after the drain. | 1139 // that case, postpone ActualDestroy() until after the drain. |
| 1258 if (media_codec_ && codec_config_->codec_ == kCodecVP8) { | 1140 if (media_codec_ && codec_config_->codec_ == kCodecVP8) { |
| 1259 // Clear |pending_bitstream_records_|. | 1141 // Clear |pending_bitstream_records_|. |
| 1260 while (!pending_bitstream_records_.empty()) | 1142 while (!pending_bitstream_records_.empty()) |
| 1261 pending_bitstream_records_.pop(); | 1143 pending_bitstream_records_.pop(); |
| 1262 | 1144 |
| 1263 StartCodecDrain(DRAIN_FOR_DESTROY); | 1145 StartCodecDrain(DRAIN_FOR_DESTROY); |
| 1264 } else { | 1146 } else { |
| 1265 ActualDestroy(); | 1147 ActualDestroy(); |
| 1266 } | 1148 } |
| 1267 } | 1149 } |
| 1268 | 1150 |
| 1269 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1151 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
| 1270 DVLOG(1) << __FUNCTION__; | 1152 DVLOG(1) << __FUNCTION__; |
| 1271 DCHECK(thread_checker_.CalledOnValidThread()); | 1153 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1272 | 1154 |
| 1273 if (!on_destroying_surface_cb_.is_null()) { | |
| 1274 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( | |
| 1275 on_destroying_surface_cb_); | |
| 1276 } | |
| 1277 | |
| 1278 // We no longer care about |surface_id|, in case we did before. It's okay | 1155 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1279 // if we have no surface and/or weren't the owner or a waiter. | 1156 // if we have no surface and/or weren't the owner or a waiter. |
| 1280 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); | 1157 AVDACodecAllocator::Get().DeallocateSurface(this, config_.surface_id); |
| 1281 | 1158 |
| 1282 // Note that async codec construction might still be in progress. In that | 1159 // Note that async codec construction might still be in progress. In that |
| 1283 // case, the codec will be deleted when it completes once we invalidate all | 1160 // case, the codec will be deleted when it completes once we invalidate all |
| 1284 // our weak refs. | 1161 // our weak refs. |
| 1285 weak_this_factory_.InvalidateWeakPtrs(); | 1162 weak_this_factory_.InvalidateWeakPtrs(); |
| 1163 g_avda_manager.Get().StopTimer(this); | |
|
liberato (no reviews please)
2016/11/17 07:28:19
hrm, that seems like an improvement.
| |
| 1286 if (media_codec_) { | 1164 if (media_codec_) { |
| 1287 g_avda_manager.Get().StopTimer(this); | 1165 AVDACodecAllocator::Get().ReleaseMediaCodec( |
| 1288 ReleaseMediaCodec(); | 1166 std::move(media_codec_), codec_config_->task_type_, config_.surface_id); |
| 1289 } | 1167 } |
| 1290 | 1168 |
| 1291 delete this; | 1169 delete this; |
| 1292 } | 1170 } |
| 1293 | 1171 |
| 1294 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1172 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| 1295 const base::WeakPtr<Client>& decode_client, | 1173 const base::WeakPtr<Client>& decode_client, |
| 1296 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 1174 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
| 1297 return false; | 1175 return false; |
| 1298 } | 1176 } |
| 1299 | 1177 |
| 1300 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { | 1178 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { |
| 1301 return size_; | 1179 return size_; |
| 1302 } | 1180 } |
| 1303 | 1181 |
| 1304 base::WeakPtr<gpu::gles2::GLES2Decoder> | 1182 base::WeakPtr<gpu::gles2::GLES2Decoder> |
| 1305 AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 1183 AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
| 1306 return get_gles2_decoder_cb_.Run(); | 1184 return get_gles2_decoder_cb_.Run(); |
| 1307 } | 1185 } |
| 1308 | 1186 |
| 1309 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { | 1187 void AndroidVideoDecodeAccelerator::OnSurfaceDestroyed() { |
| 1188 DVLOG(1) << __func__; | |
| 1189 TRACE_EVENT0("media", "AVDA::OnSurfaceDestroyed"); | |
| 1310 DCHECK(thread_checker_.CalledOnValidThread()); | 1190 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1311 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); | |
| 1312 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; | |
| 1313 | |
| 1314 if (surface_id != config_.surface_id) | |
| 1315 return; | |
| 1316 | 1191 |
| 1317 // If the API is available avoid having to restart the decoder in order to | 1192 // If the API is available avoid having to restart the decoder in order to |
| 1318 // leave fullscreen. If we don't clear the surface immediately during this | 1193 // leave fullscreen. If we don't clear the surface immediately during this |
| 1319 // callback, the MediaCodec will throw an error as the surface is destroyed. | 1194 // callback, the MediaCodec will throw an error as the surface is destroyed. |
| 1320 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { | 1195 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { |
| 1321 // Since we can't wait for a transition, we must invalidate all outstanding | 1196 // Since we can't wait for a transition, we must invalidate all outstanding |
| 1322 // picture buffers to avoid putting the GL system in a broken state. | 1197 // picture buffers to avoid putting the GL system in a broken state. |
| 1323 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1198 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1324 | 1199 |
| 1325 // Switch away from the surface being destroyed to a surface texture. | 1200 // Switch away from the surface being destroyed to a surface texture. |
| 1326 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID); | 1201 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID); |
| 1327 | 1202 |
| 1328 // The leaving fullscreen notification may come in before this point. | 1203 // The leaving fullscreen notification may come in before this point. |
| 1329 if (pending_surface_id_) | 1204 if (pending_surface_id_) |
| 1330 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); | 1205 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); |
| 1331 | 1206 |
| 1332 pending_surface_id_ = SurfaceManager::kNoSurfaceID; | 1207 pending_surface_id_ = SurfaceManager::kNoSurfaceID; |
| 1333 UpdateSurface(); | 1208 UpdateSurface(); |
| 1334 return; | 1209 return; |
| 1335 } | 1210 } |
| 1336 | 1211 |
| 1337 // If we're currently asynchronously configuring a codec, it will be destroyed | 1212 // If we're currently asynchronously configuring a codec, it will be destroyed |
| 1338 // when configuration completes and it notices that |state_| has changed to | 1213 // when configuration completes and it notices that |state_| has changed to |
| 1339 // SURFACE_DESTROYED. | 1214 // SURFACE_DESTROYED. |
| 1340 state_ = SURFACE_DESTROYED; | 1215 state_ = SURFACE_DESTROYED; |
| 1341 if (media_codec_) { | 1216 if (media_codec_) { |
| 1342 ReleaseMediaCodec(); | 1217 AVDACodecAllocator::Get().ReleaseMediaCodec( |
| 1218 std::move(media_codec_), codec_config_->task_type_, config_.surface_id); | |
| 1343 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1219 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
| 1344 } | 1220 } |
| 1221 | |
| 1345 // If we're draining, signal completion now because the drain can no longer | 1222 // If we're draining, signal completion now because the drain can no longer |
| 1346 // proceed. | 1223 // proceed. |
| 1347 if (drain_type_ != DRAIN_TYPE_NONE) | 1224 if (drain_type_ != DRAIN_TYPE_NONE) |
| 1348 OnDrainCompleted(); | 1225 OnDrainCompleted(); |
| 1349 } | 1226 } |
| 1350 | 1227 |
| 1351 void AndroidVideoDecodeAccelerator::InitializeCdm() { | 1228 void AndroidVideoDecodeAccelerator::InitializeCdm() { |
| 1352 DVLOG(2) << __FUNCTION__ << ": " << config_.cdm_id; | 1229 DVLOG(2) << __FUNCTION__ << ": " << config_.cdm_id; |
| 1353 | 1230 |
| 1354 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 1231 #if !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1465 } else { | 1342 } else { |
| 1466 most_recent_work_ = now; | 1343 most_recent_work_ = now; |
| 1467 } | 1344 } |
| 1468 | 1345 |
| 1469 if (should_be_running) | 1346 if (should_be_running) |
| 1470 g_avda_manager.Get().StartTimer(this); | 1347 g_avda_manager.Get().StartTimer(this); |
| 1471 else | 1348 else |
| 1472 g_avda_manager.Get().StopTimer(this); | 1349 g_avda_manager.Get().StopTimer(this); |
| 1473 } | 1350 } |
| 1474 | 1351 |
| 1475 void AndroidVideoDecodeAccelerator::ReleaseMediaCodec() { | |
| 1476 if (!media_codec_) | |
| 1477 return; | |
| 1478 | |
| 1479 // Post it to the same thread as was used to allocate it, and it'll get freed | |
| 1480 // if that thread isn't hung waiting on mediaserver. We can't release it | |
| 1481 // on this thread since it might hang up. | |
| 1482 g_avda_codec_allocator.Get() | |
| 1483 .TaskRunnerFor(codec_config_->task_type_) | |
| 1484 ->DeleteSoon(FROM_HERE, media_codec_.release()); | |
| 1485 } | |
| 1486 | |
| 1487 // static | 1352 // static |
| 1488 VideoDecodeAccelerator::Capabilities | 1353 VideoDecodeAccelerator::Capabilities |
| 1489 AndroidVideoDecodeAccelerator::GetCapabilities( | 1354 AndroidVideoDecodeAccelerator::GetCapabilities( |
| 1490 const gpu::GpuPreferences& gpu_preferences) { | 1355 const gpu::GpuPreferences& gpu_preferences) { |
| 1491 Capabilities capabilities; | 1356 Capabilities capabilities; |
| 1492 SupportedProfiles& profiles = capabilities.supported_profiles; | 1357 SupportedProfiles& profiles = capabilities.supported_profiles; |
| 1493 | 1358 |
| 1494 if (MediaCodecUtil::IsVp8DecoderAvailable()) { | 1359 if (MediaCodecUtil::IsVp8DecoderAvailable()) { |
| 1495 SupportedProfile profile; | 1360 SupportedProfile profile; |
| 1496 profile.profile = VP8PROFILE_ANY; | 1361 profile.profile = VP8PROFILE_ANY; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1587 // Prevent MediaCodec from using its internal software decoders when we have | 1452 // Prevent MediaCodec from using its internal software decoders when we have |
| 1588 // more secure and up to date versions in the renderer process. | 1453 // more secure and up to date versions in the renderer process. |
| 1589 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || | 1454 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || |
| 1590 codec_config_->codec_ == kCodecVP9); | 1455 codec_config_->codec_ == kCodecVP9); |
| 1591 } | 1456 } |
| 1592 | 1457 |
| 1593 bool AndroidVideoDecodeAccelerator::UpdateSurface() { | 1458 bool AndroidVideoDecodeAccelerator::UpdateSurface() { |
| 1594 DCHECK(pending_surface_id_); | 1459 DCHECK(pending_surface_id_); |
| 1595 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); | 1460 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); |
| 1596 | 1461 |
| 1462 // Deallocate our current surface. | |
| 1463 AVDACodecAllocator::Get().DeallocateSurface(this, config_.surface_id); | |
|
liberato (no reviews please)
2016/11/17 07:28:19
one of these has to be "no surface", i think. wor
watk
2016/11/17 20:37:05
sg will do
| |
| 1464 config_.surface_id = pending_surface_id_.value(); | |
| 1465 pending_surface_id_.reset(); | |
| 1466 | |
| 1467 // TODO(watk): Fix this so we can wait for the new surface to be allocated. | |
| 1468 if (!AVDACodecAllocator::Get().AllocateSurface(this, config_.surface_id)) { | |
| 1469 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to allocate the new surface"); | |
| 1470 return false; | |
| 1471 } | |
| 1472 | |
| 1597 // Ensure the current context is active when switching surfaces; we may need | 1473 // Ensure the current context is active when switching surfaces; we may need |
| 1598 // to create a new texture. | 1474 // to create a new texture. |
| 1599 if (!make_context_current_cb_.Run()) { | 1475 if (!make_context_current_cb_.Run()) { |
| 1600 NOTIFY_ERROR(PLATFORM_FAILURE, | 1476 NOTIFY_ERROR(PLATFORM_FAILURE, |
| 1601 "Failed to make this decoder's GL context current when " | 1477 "Failed to make this decoder's GL context current when " |
| 1602 "switching surfaces."); | 1478 "switching surfaces."); |
| 1603 return false; | 1479 return false; |
| 1604 } | 1480 } |
| 1605 | 1481 |
| 1606 config_.surface_id = pending_surface_id_.value(); | |
| 1607 codec_config_->surface_ = | 1482 codec_config_->surface_ = |
| 1608 picture_buffer_manager_.Initialize(pending_surface_id_.value()); | 1483 picture_buffer_manager_.Initialize(config_.surface_id); |
| 1609 if (codec_config_->surface_.IsEmpty()) { | 1484 if (codec_config_->surface_.IsEmpty()) { |
| 1610 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); | 1485 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); |
| 1611 return false; | 1486 return false; |
| 1612 } | 1487 } |
| 1613 | 1488 |
| 1614 if (media_codec_ && | 1489 if (media_codec_ && |
| 1615 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) { | 1490 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) { |
| 1616 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); | 1491 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); |
| 1617 return false; | 1492 return false; |
| 1618 } | 1493 } |
| 1619 | 1494 |
| 1620 pending_surface_id_.reset(); | |
| 1621 return true; | 1495 return true; |
| 1622 } | 1496 } |
| 1623 | 1497 |
| 1624 } // namespace media | 1498 } // namespace media |
| OLD | NEW |