| 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 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 if (timer_avda_instances_.empty()) | 162 if (timer_avda_instances_.empty()) |
| 163 io_timer_.Stop(); | 163 io_timer_.Stop(); |
| 164 } | 164 } |
| 165 | 165 |
| 166 // |avda| would like to use |surface_id|. If it is not busy, then mark it | 166 // |avda| would like to use |surface_id|. If it is not busy, then mark it |
| 167 // as busy and return true. If it is busy, then replace any existing waiter, | 167 // as busy and return true. If it is busy, then replace any existing waiter, |
| 168 // make |avda| the current waiter, and return false. Any existing waiter | 168 // make |avda| the current waiter, and return false. Any existing waiter |
| 169 // is assumed to be on the way out, so we fail its allocation request. | 169 // is assumed to be on the way out, so we fail its allocation request. |
| 170 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { | 170 bool AllocateSurface(int surface_id, AndroidVideoDecodeAccelerator* avda) { |
| 171 // Nobody has to wait for no surface. | 171 // Nobody has to wait for no surface. |
| 172 if (surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID) | 172 if (surface_id == SurfaceManager::kNoSurfaceID) |
| 173 return true; | 173 return true; |
| 174 | 174 |
| 175 auto iter = surface_waiter_map_.find(surface_id); | 175 auto iter = surface_waiter_map_.find(surface_id); |
| 176 if (iter == surface_waiter_map_.end()) { | 176 if (iter == surface_waiter_map_.end()) { |
| 177 // SurfaceView isn't allocated. Succeed. | 177 // SurfaceView isn't allocated. Succeed. |
| 178 surface_waiter_map_[surface_id].owner = avda; | 178 surface_waiter_map_[surface_id].owner = avda; |
| 179 return true; | 179 return true; |
| 180 } | 180 } |
| 181 | 181 |
| 182 // SurfaceView is already allocated. | 182 // SurfaceView is already allocated. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 // Promote |waiter| to be the owner. | 218 // Promote |waiter| to be the owner. |
| 219 iter->second.owner = waiter; | 219 iter->second.owner = waiter; |
| 220 iter->second.waiter = nullptr; | 220 iter->second.waiter = nullptr; |
| 221 waiter->OnSurfaceAvailable(true); | 221 waiter->OnSurfaceAvailable(true); |
| 222 } | 222 } |
| 223 | 223 |
| 224 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), | 224 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), |
| 225 // defer the surface creation until the codec is actually used if we know no | 225 // defer the surface creation until the codec is actually used if we know no |
| 226 // software fallback exists. | 226 // software fallback exists. |
| 227 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { | 227 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { |
| 228 return surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID && | 228 return surface_id == SurfaceManager::kNoSurfaceID && codec == kCodecH264 && |
| 229 codec == kCodecH264 && | |
| 230 g_avda_codec_allocator.Get().IsAnyRegisteredAVDA() && | 229 g_avda_codec_allocator.Get().IsAnyRegisteredAVDA() && |
| 231 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || | 230 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || |
| 232 base::SysInfo::IsLowEndDevice()); | 231 base::SysInfo::IsLowEndDevice()); |
| 233 } | 232 } |
| 234 | 233 |
| 235 private: | 234 private: |
| 236 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; | 235 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; |
| 237 | 236 |
| 238 AVDAManager() {} | 237 AVDAManager() {} |
| 239 ~AVDAManager() { NOTREACHED(); } | 238 ~AVDAManager() { NOTREACHED(); } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 picture_buffer_manager_(this), | 311 picture_buffer_manager_(this), |
| 313 drain_type_(DRAIN_TYPE_NONE), | 312 drain_type_(DRAIN_TYPE_NONE), |
| 314 media_drm_bridge_cdm_context_(nullptr), | 313 media_drm_bridge_cdm_context_(nullptr), |
| 315 cdm_registration_id_(0), | 314 cdm_registration_id_(0), |
| 316 pending_input_buf_index_(-1), | 315 pending_input_buf_index_(-1), |
| 317 error_sequence_token_(0), | 316 error_sequence_token_(0), |
| 318 defer_errors_(false), | 317 defer_errors_(false), |
| 319 deferred_initialization_pending_(false), | 318 deferred_initialization_pending_(false), |
| 320 codec_needs_reset_(false), | 319 codec_needs_reset_(false), |
| 321 defer_surface_creation_(false), | 320 defer_surface_creation_(false), |
| 321 surface_id_(SurfaceManager::kNoSurfaceID), |
| 322 weak_this_factory_(this) {} | 322 weak_this_factory_(this) {} |
| 323 | 323 |
| 324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 325 DCHECK(thread_checker_.CalledOnValidThread()); | 325 DCHECK(thread_checker_.CalledOnValidThread()); |
| 326 g_avda_manager.Get().StopTimer(this); | 326 g_avda_manager.Get().StopTimer(this); |
| 327 g_avda_codec_allocator.Get().StopThread(this); | 327 g_avda_codec_allocator.Get().StopThread(this); |
| 328 | 328 |
| 329 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 329 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 330 if (!media_drm_bridge_cdm_context_) | 330 if (!media_drm_bridge_cdm_context_) |
| 331 return; | 331 return; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 390 << " is not hardware accelerated"; | 390 << " is not hardware accelerated"; |
| 391 return false; | 391 return false; |
| 392 } | 392 } |
| 393 | 393 |
| 394 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 394 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
| 395 if (!gles_decoder) { | 395 if (!gles_decoder) { |
| 396 DLOG(ERROR) << "Failed to get gles2 decoder instance."; | 396 DLOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 397 return false; | 397 return false; |
| 398 } | 398 } |
| 399 | 399 |
| 400 // If SetSurface() was called before initialize, pick up the surface. |
| 401 if (pending_surface_id_) { |
| 402 surface_id_ = pending_surface_id_.value(); |
| 403 pending_surface_id_.reset(); |
| 404 } |
| 405 |
| 400 // If we're low on resources, we may decide to defer creation of the surface | 406 // If we're low on resources, we may decide to defer creation of the surface |
| 401 // until the codec is actually used. | 407 // until the codec is actually used. |
| 402 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, | 408 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(surface_id_, |
| 403 codec_config_->codec_)) { | 409 codec_config_->codec_)) { |
| 404 DCHECK(!deferred_initialization_pending_); | 410 DCHECK(!deferred_initialization_pending_); |
| 405 | 411 |
| 406 // We should never be here if a SurfaceView is required. | 412 // We should never be here if a SurfaceView is required. |
| 407 DCHECK_EQ(config_.surface_id, Config::kNoSurfaceID); | 413 DCHECK_EQ(surface_id_, SurfaceManager::kNoSurfaceID); |
| 408 DCHECK(g_avda_manager.Get().AllocateSurface(config_.surface_id, this)); | 414 DCHECK(g_avda_manager.Get().AllocateSurface(surface_id_, this)); |
| 409 | 415 |
| 410 defer_surface_creation_ = true; | 416 defer_surface_creation_ = true; |
| 411 NotifyInitializationComplete(true); | 417 NotifyInitializationComplete(true); |
| 412 return true; | 418 return true; |
| 413 } | 419 } |
| 414 | 420 |
| 415 // We signaled that we support deferred initialization, so see if the client | 421 // We signaled that we support deferred initialization, so see if the client |
| 416 // does also. | 422 // does also. |
| 417 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 423 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
| 418 if (config_.is_encrypted && !deferred_initialization_pending_) { | 424 if (config_.is_encrypted && !deferred_initialization_pending_) { |
| 419 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; | 425 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; |
| 420 return false; | 426 return false; |
| 421 } | 427 } |
| 422 | 428 |
| 423 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { | 429 if (g_avda_manager.Get().AllocateSurface(surface_id_, this)) { |
| 424 // We have successfully owned the surface, so finish initialization now. | 430 // We have successfully owned the surface, so finish initialization now. |
| 425 return InitializePictureBufferManager(); | 431 return InitializePictureBufferManager(); |
| 426 } | 432 } |
| 427 | 433 |
| 428 // We have to wait for some other AVDA instance to free up the surface. | 434 // We have to wait for some other AVDA instance to free up the surface. |
| 429 // OnSurfaceAvailable will be called when it's available. | 435 // OnSurfaceAvailable will be called when it's available. |
| 430 return true; | 436 return true; |
| 431 } | 437 } |
| 432 | 438 |
| 433 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { | 439 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
| 434 DCHECK(deferred_initialization_pending_); | 440 DCHECK(deferred_initialization_pending_); |
| 435 DCHECK(!defer_surface_creation_); | 441 DCHECK(!defer_surface_creation_); |
| 436 | 442 |
| 437 if (!success || !InitializePictureBufferManager()) { | 443 if (!success || !InitializePictureBufferManager()) { |
| 438 NotifyInitializationComplete(false); | 444 NotifyInitializationComplete(false); |
| 439 deferred_initialization_pending_ = false; | 445 deferred_initialization_pending_ = false; |
| 440 } | 446 } |
| 441 } | 447 } |
| 442 | 448 |
| 443 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 449 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| 444 if (!make_context_current_cb_.Run()) { | 450 if (!make_context_current_cb_.Run()) { |
| 445 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 451 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 446 return false; | 452 return false; |
| 447 } | 453 } |
| 448 | 454 |
| 449 codec_config_->surface_ = | 455 codec_config_->surface_ = picture_buffer_manager_.Initialize(surface_id_); |
| 450 picture_buffer_manager_.Initialize(config_.surface_id); | |
| 451 if (codec_config_->surface_.IsEmpty()) | 456 if (codec_config_->surface_.IsEmpty()) |
| 452 return false; | 457 return false; |
| 453 | 458 |
| 454 on_destroying_surface_cb_ = | 459 on_destroying_surface_cb_ = |
| 455 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, | 460 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, |
| 456 weak_this_factory_.GetWeakPtr()); | 461 weak_this_factory_.GetWeakPtr()); |
| 457 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( | 462 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( |
| 458 on_destroying_surface_cb_); | 463 on_destroying_surface_cb_); |
| 459 | 464 |
| 460 if (!g_avda_codec_allocator.Get().StartThread(this)) | 465 if (!g_avda_codec_allocator.Get().StartThread(this)) |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 if (picturebuffers_requested_ && output_picture_buffers_.empty() && | 652 if (picturebuffers_requested_ && output_picture_buffers_.empty() && |
| 648 !IsDrainingForResetOrDestroy()) { | 653 !IsDrainingForResetOrDestroy()) { |
| 649 return false; | 654 return false; |
| 650 } | 655 } |
| 651 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() && | 656 if (!output_picture_buffers_.empty() && free_picture_ids_.empty() && |
| 652 !IsDrainingForResetOrDestroy()) { | 657 !IsDrainingForResetOrDestroy()) { |
| 653 // Don't have any picture buffer to send. Need to wait. | 658 // Don't have any picture buffer to send. Need to wait. |
| 654 return false; | 659 return false; |
| 655 } | 660 } |
| 656 | 661 |
| 662 // If we're waiting to switch surfaces pause output release until we have all |
| 663 // picture buffers returned. This is so we can ensure the right flags are set |
| 664 // on the picture buffers returned to the client. |
| 665 if (pending_surface_id_) { |
| 666 if (picture_buffer_manager_.HasUnrenderedPictures()) |
| 667 return false; |
| 668 if (!UpdateSurface()) |
| 669 return false; |
| 670 } |
| 671 |
| 657 bool eos = false; | 672 bool eos = false; |
| 658 base::TimeDelta presentation_timestamp; | 673 base::TimeDelta presentation_timestamp; |
| 659 int32_t buf_index = 0; | 674 int32_t buf_index = 0; |
| 660 do { | 675 do { |
| 661 size_t offset = 0; | 676 size_t offset = 0; |
| 662 size_t size = 0; | 677 size_t size = 0; |
| 663 | 678 |
| 664 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); | 679 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); |
| 665 MediaCodecStatus status = media_codec_->DequeueOutputBuffer( | 680 MediaCodecStatus status = media_codec_->DequeueOutputBuffer( |
| 666 NoWaitTimeOut, &buf_index, &offset, &size, &presentation_timestamp, | 681 NoWaitTimeOut, &buf_index, &offset, &size, &presentation_timestamp, |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 877 const BitstreamBuffer& bitstream_buffer) { | 892 const BitstreamBuffer& bitstream_buffer) { |
| 878 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer)); | 893 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer)); |
| 879 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", | 894 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", |
| 880 pending_bitstream_records_.size()); | 895 pending_bitstream_records_.size()); |
| 881 | 896 |
| 882 DoIOTask(true); | 897 DoIOTask(true); |
| 883 } | 898 } |
| 884 | 899 |
| 885 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { | 900 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { |
| 886 if (client_) { | 901 if (client_) { |
| 887 client_->ProvidePictureBuffers( | 902 // Allocate a picture buffer that is the actual frame size. Note that it |
| 888 kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1, | 903 // will be an external texture anyway, so it doesn't allocate an image of |
| 889 picture_buffer_manager_.GetPictureBufferSize(), | 904 // that size. It's important to get the coded size right, so that |
| 890 picture_buffer_manager_.GetTextureTarget()); | 905 // VideoLayerImpl doesn't try to scale the texture when building the quad |
| 906 // for it. |
| 907 client_->ProvidePictureBuffers(kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1, |
| 908 size_, |
| 909 AVDAPictureBufferManager::kTextureTarget); |
| 891 } | 910 } |
| 892 } | 911 } |
| 893 | 912 |
| 894 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( | 913 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( |
| 895 const std::vector<PictureBuffer>& buffers) { | 914 const std::vector<PictureBuffer>& buffers) { |
| 896 DCHECK(thread_checker_.CalledOnValidThread()); | 915 DCHECK(thread_checker_.CalledOnValidThread()); |
| 897 DCHECK(output_picture_buffers_.empty()); | 916 DCHECK(output_picture_buffers_.empty()); |
| 898 DCHECK(free_picture_ids_.empty()); | 917 DCHECK(free_picture_ids_.empty()); |
| 899 | 918 |
| 900 if (buffers.size() < kNumPictureBuffers) { | 919 if (buffers.size() < kNumPictureBuffers) { |
| 901 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); | 920 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); |
| 902 return; | 921 return; |
| 903 } | 922 } |
| 904 | 923 |
| 905 const bool have_context = make_context_current_cb_.Run(); | 924 const bool have_context = make_context_current_cb_.Run(); |
| 906 LOG_IF(WARNING, !have_context) | 925 LOG_IF(WARNING, !have_context) |
| 907 << "Failed to make GL context current for Assign, continuing."; | 926 << "Failed to make GL context current for Assign, continuing."; |
| 908 | 927 |
| 909 for (size_t i = 0; i < buffers.size(); ++i) { | 928 for (size_t i = 0; i < buffers.size(); ++i) { |
| 910 if (buffers[i].size() != picture_buffer_manager_.GetPictureBufferSize()) { | 929 DCHECK(buffers[i].size() == size_); |
| 911 POST_ERROR(INVALID_ARGUMENT, | |
| 912 "Invalid picture buffer size assigned. Wanted " | |
| 913 << size_.ToString() << ", but got " | |
| 914 << buffers[i].size().ToString()); | |
| 915 return; | |
| 916 } | |
| 917 int32_t id = buffers[i].id(); | 930 int32_t id = buffers[i].id(); |
| 918 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); | 931 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); |
| 919 free_picture_ids_.push(id); | 932 free_picture_ids_.push(id); |
| 920 | 933 |
| 921 picture_buffer_manager_.AssignOnePictureBuffer(buffers[i], have_context); | 934 picture_buffer_manager_.AssignOnePictureBuffer(buffers[i], have_context); |
| 922 } | 935 } |
| 923 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); | 936 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
| 924 DoIOTask(true); | 937 DoIOTask(true); |
| 925 } | 938 } |
| 926 | 939 |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1234 // Postpone ResetCodecState() after the drain. | 1247 // Postpone ResetCodecState() after the drain. |
| 1235 StartCodecDrain(DRAIN_FOR_RESET); | 1248 StartCodecDrain(DRAIN_FOR_RESET); |
| 1236 } else { | 1249 } else { |
| 1237 ResetCodecState(); | 1250 ResetCodecState(); |
| 1238 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1251 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1239 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 1252 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| 1240 weak_this_factory_.GetWeakPtr())); | 1253 weak_this_factory_.GetWeakPtr())); |
| 1241 } | 1254 } |
| 1242 } | 1255 } |
| 1243 | 1256 |
| 1257 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { |
| 1258 if (surface_id == surface_id_) { |
| 1259 pending_surface_id_.reset(); |
| 1260 return; |
| 1261 } |
| 1262 |
| 1263 // Surface changes never take effect immediately, they will be handled during |
| 1264 // DequeOutput() once we get to a good switch point or immediately during an |
| 1265 // OnDestroyingSurface() call. |
| 1266 pending_surface_id_ = surface_id; |
| 1267 } |
| 1268 |
| 1244 void AndroidVideoDecodeAccelerator::Destroy() { | 1269 void AndroidVideoDecodeAccelerator::Destroy() { |
| 1245 DVLOG(1) << __FUNCTION__; | 1270 DVLOG(1) << __FUNCTION__; |
| 1246 DCHECK(thread_checker_.CalledOnValidThread()); | 1271 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1247 | 1272 |
| 1248 picture_buffer_manager_.Destroy(output_picture_buffers_); | 1273 picture_buffer_manager_.Destroy(output_picture_buffers_); |
| 1249 | 1274 |
| 1250 client_ = nullptr; | 1275 client_ = nullptr; |
| 1251 | 1276 |
| 1252 // Some VP8 files require a complete MediaCodec drain before we can call | 1277 // Some VP8 files require a complete MediaCodec drain before we can call |
| 1253 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In | 1278 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1267 DVLOG(1) << __FUNCTION__; | 1292 DVLOG(1) << __FUNCTION__; |
| 1268 DCHECK(thread_checker_.CalledOnValidThread()); | 1293 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1269 | 1294 |
| 1270 if (!on_destroying_surface_cb_.is_null()) { | 1295 if (!on_destroying_surface_cb_.is_null()) { |
| 1271 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( | 1296 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( |
| 1272 on_destroying_surface_cb_); | 1297 on_destroying_surface_cb_); |
| 1273 } | 1298 } |
| 1274 | 1299 |
| 1275 // We no longer care about |surface_id|, in case we did before. It's okay | 1300 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1276 // if we have no surface and/or weren't the owner or a waiter. | 1301 // if we have no surface and/or weren't the owner or a waiter. |
| 1277 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); | 1302 g_avda_manager.Get().DeallocateSurface(surface_id_, this); |
| 1278 | 1303 |
| 1279 // Note that async codec construction might still be in progress. In that | 1304 // Note that async codec construction might still be in progress. In that |
| 1280 // case, the codec will be deleted when it completes once we invalidate all | 1305 // case, the codec will be deleted when it completes once we invalidate all |
| 1281 // our weak refs. | 1306 // our weak refs. |
| 1282 weak_this_factory_.InvalidateWeakPtrs(); | 1307 weak_this_factory_.InvalidateWeakPtrs(); |
| 1283 if (media_codec_) { | 1308 if (media_codec_) { |
| 1284 g_avda_manager.Get().StopTimer(this); | 1309 g_avda_manager.Get().StopTimer(this); |
| 1285 ReleaseMediaCodec(); | 1310 ReleaseMediaCodec(); |
| 1286 } | 1311 } |
| 1287 | 1312 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1301 base::WeakPtr<gpu::gles2::GLES2Decoder> | 1326 base::WeakPtr<gpu::gles2::GLES2Decoder> |
| 1302 AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 1327 AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
| 1303 return get_gles2_decoder_cb_.Run(); | 1328 return get_gles2_decoder_cb_.Run(); |
| 1304 } | 1329 } |
| 1305 | 1330 |
| 1306 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { | 1331 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { |
| 1307 DCHECK(thread_checker_.CalledOnValidThread()); | 1332 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1308 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); | 1333 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); |
| 1309 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; | 1334 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; |
| 1310 | 1335 |
| 1311 if (surface_id != config_.surface_id) | 1336 if (surface_id != surface_id_) |
| 1312 return; | 1337 return; |
| 1313 | 1338 |
| 1339 // If the API is available avoid having to restart the decoder in order to |
| 1340 // leave fullscreen. If we don't clear the surface immediately during this |
| 1341 // callback, the MediaCodec will throw an error as the surface is destroyed. |
| 1342 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { |
| 1343 // Since we can't wait for a transition, we must invalidate all outstanding |
| 1344 // picture buffers to avoid putting the GL system in a broken state. |
| 1345 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1346 |
| 1347 // Switch away from the surface being destroyed to a surface texture. |
| 1348 DCHECK_NE(surface_id_, SurfaceManager::kNoSurfaceID); |
| 1349 |
| 1350 // The leaving fullscreen notification may come in before this point. |
| 1351 if (pending_surface_id_) |
| 1352 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); |
| 1353 |
| 1354 pending_surface_id_ = SurfaceManager::kNoSurfaceID; |
| 1355 UpdateSurface(); |
| 1356 return; |
| 1357 } |
| 1358 |
| 1314 // If we're currently asynchronously configuring a codec, it will be destroyed | 1359 // If we're currently asynchronously configuring a codec, it will be destroyed |
| 1315 // when configuration completes and it notices that |state_| has changed to | 1360 // when configuration completes and it notices that |state_| has changed to |
| 1316 // SURFACE_DESTROYED. | 1361 // SURFACE_DESTROYED. |
| 1317 state_ = SURFACE_DESTROYED; | 1362 state_ = SURFACE_DESTROYED; |
| 1318 if (media_codec_) { | 1363 if (media_codec_) { |
| 1319 ReleaseMediaCodec(); | 1364 ReleaseMediaCodec(); |
| 1320 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1365 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
| 1321 } | 1366 } |
| 1322 // If we're draining, signal completion now because the drain can no longer | 1367 // If we're draining, signal completion now because the drain can no longer |
| 1323 // proceed. | 1368 // proceed. |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1577 } | 1622 } |
| 1578 | 1623 |
| 1579 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1624 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
| 1580 const { | 1625 const { |
| 1581 // Prevent MediaCodec from using its internal software decoders when we have | 1626 // Prevent MediaCodec from using its internal software decoders when we have |
| 1582 // more secure and up to date versions in the renderer process. | 1627 // more secure and up to date versions in the renderer process. |
| 1583 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || | 1628 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || |
| 1584 codec_config_->codec_ == kCodecVP9); | 1629 codec_config_->codec_ == kCodecVP9); |
| 1585 } | 1630 } |
| 1586 | 1631 |
| 1632 bool AndroidVideoDecodeAccelerator::UpdateSurface() { |
| 1633 DCHECK(pending_surface_id_); |
| 1634 DCHECK_NE(surface_id_, pending_surface_id_.value()); |
| 1635 |
| 1636 // Ensure the current context is active when switching surfaces; we may need |
| 1637 // to create a new texture. |
| 1638 if (!make_context_current_cb_.Run()) { |
| 1639 POST_ERROR(PLATFORM_FAILURE, |
| 1640 "Failed to make this decoder's GL context current when " |
| 1641 "switching surfaces."); |
| 1642 return false; |
| 1643 } |
| 1644 |
| 1645 surface_id_ = pending_surface_id_.value(); |
| 1646 codec_config_->surface_ = |
| 1647 picture_buffer_manager_.Initialize(pending_surface_id_.value()); |
| 1648 if (codec_config_->surface_.IsEmpty()) { |
| 1649 POST_ERROR(PLATFORM_FAILURE, "An error occurred while switching surfaces."); |
| 1650 return false; |
| 1651 } |
| 1652 |
| 1653 if (media_codec_ && |
| 1654 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) { |
| 1655 POST_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); |
| 1656 return false; |
| 1657 } |
| 1658 |
| 1659 pending_surface_id_.reset(); |
| 1660 return true; |
| 1661 } |
| 1662 |
| 1587 } // namespace media | 1663 } // namespace media |
| OLD | NEW |