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 |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 get_gles2_decoder_cb_(get_gles2_decoder_cb), | 230 get_gles2_decoder_cb_(get_gles2_decoder_cb), |
| 231 state_(NO_ERROR), | 231 state_(NO_ERROR), |
| 232 picturebuffers_requested_(false), | 232 picturebuffers_requested_(false), |
| 233 picture_buffer_manager_(this), | 233 picture_buffer_manager_(this), |
| 234 media_drm_bridge_cdm_context_(nullptr), | 234 media_drm_bridge_cdm_context_(nullptr), |
| 235 cdm_registration_id_(0), | 235 cdm_registration_id_(0), |
| 236 pending_input_buf_index_(-1), | 236 pending_input_buf_index_(-1), |
| 237 deferred_initialization_pending_(false), | 237 deferred_initialization_pending_(false), |
| 238 codec_needs_reset_(false), | 238 codec_needs_reset_(false), |
| 239 defer_surface_creation_(false), | 239 defer_surface_creation_(false), |
| 240 last_release_task_type_(TaskType::AUTO_CODEC), | |
| 240 weak_this_factory_(this) {} | 241 weak_this_factory_(this) {} |
| 241 | 242 |
| 242 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 243 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 243 DCHECK(thread_checker_.CalledOnValidThread()); | 244 DCHECK(thread_checker_.CalledOnValidThread()); |
| 244 g_avda_manager.Get().StopTimer(this); | 245 g_avda_manager.Get().StopTimer(this); |
| 245 AVDACodecAllocator::Instance()->StopThread(this); | 246 AVDACodecAllocator::Instance()->StopThread(this); |
| 246 | 247 |
| 247 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 248 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 248 if (!media_drm_bridge_cdm_context_) | 249 if (!media_drm_bridge_cdm_context_) |
| 249 return; | 250 return; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 } | 360 } |
| 360 | 361 |
| 361 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 362 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| 362 if (!make_context_current_cb_.Run()) { | 363 if (!make_context_current_cb_.Run()) { |
| 363 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 364 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 364 return false; | 365 return false; |
| 365 } | 366 } |
| 366 | 367 |
| 367 codec_config_->surface = | 368 codec_config_->surface = |
| 368 picture_buffer_manager_.Initialize(config_.surface_id); | 369 picture_buffer_manager_.Initialize(config_.surface_id); |
| 370 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); | |
| 369 if (codec_config_->surface.IsEmpty()) | 371 if (codec_config_->surface.IsEmpty()) |
| 370 return false; | 372 return false; |
| 371 | 373 |
| 372 if (!AVDACodecAllocator::Instance()->StartThread(this)) | 374 if (!AVDACodecAllocator::Instance()->StartThread(this)) |
| 373 return false; | 375 return false; |
| 374 | 376 |
| 375 // If we are encrypted, then we aren't able to create the codec yet. | 377 // If we are encrypted, then we aren't able to create the codec yet. |
| 376 if (config_.is_encrypted()) { | 378 if (config_.is_encrypted()) { |
| 377 InitializeCdm(); | 379 InitializeCdm(); |
| 378 return true; | 380 return true; |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 866 DCHECK(thread_checker_.CalledOnValidThread()); | 868 DCHECK(thread_checker_.CalledOnValidThread()); |
| 867 StartCodecDrain(DRAIN_FOR_FLUSH); | 869 StartCodecDrain(DRAIN_FOR_FLUSH); |
| 868 } | 870 } |
| 869 | 871 |
| 870 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 872 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
| 871 DCHECK(thread_checker_.CalledOnValidThread()); | 873 DCHECK(thread_checker_.CalledOnValidThread()); |
| 872 | 874 |
| 873 DCHECK_NE(state_, WAITING_FOR_CODEC); | 875 DCHECK_NE(state_, WAITING_FOR_CODEC); |
| 874 state_ = WAITING_FOR_CODEC; | 876 state_ = WAITING_FOR_CODEC; |
| 875 | 877 |
| 876 if (media_codec_) { | 878 ReleaseCodec(); |
| 877 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | |
| 878 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | |
| 879 picture_buffer_manager_.CodecChanged(nullptr); | |
| 880 } | |
| 881 | 879 |
| 882 base::Optional<TaskType> task_type = | 880 base::Optional<TaskType> task_type = |
| 883 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); | 881 AVDACodecAllocator::Instance()->TaskTypeForAllocation(); |
| 884 if (!task_type) { | 882 if (!task_type) { |
| 885 // If there is no free thread, then just fail. | 883 // If there is no free thread, then just fail. |
| 886 OnCodecConfigured(nullptr); | 884 OnCodecConfigured(nullptr); |
| 887 return; | 885 return; |
| 888 } | 886 } |
| 889 | 887 |
| 890 // If autodetection is disallowed, fall back to Chrome's software decoders | 888 // If autodetection is disallowed, fall back to Chrome's software decoders |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1135 | 1133 |
| 1136 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1134 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
| 1137 DVLOG(1) << __func__; | 1135 DVLOG(1) << __func__; |
| 1138 DCHECK(thread_checker_.CalledOnValidThread()); | 1136 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1139 | 1137 |
| 1140 // Note that async codec construction might still be in progress. In that | 1138 // Note that async codec construction might still be in progress. In that |
| 1141 // case, the codec will be deleted when it completes once we invalidate all | 1139 // case, the codec will be deleted when it completes once we invalidate all |
| 1142 // our weak refs. | 1140 // our weak refs. |
| 1143 weak_this_factory_.InvalidateWeakPtrs(); | 1141 weak_this_factory_.InvalidateWeakPtrs(); |
| 1144 g_avda_manager.Get().StopTimer(this); | 1142 g_avda_manager.Get().StopTimer(this); |
| 1145 if (media_codec_) { | 1143 ReleaseCodec(); |
| 1146 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | |
| 1147 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | |
| 1148 } | |
| 1149 | 1144 |
| 1150 // We no longer care about |surface_id|, in case we did before. It's okay | 1145 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1151 // if we have no surface and/or weren't the owner or a waiter. | 1146 // if we have no surface and/or weren't the owner or a waiter. |
| 1152 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); | 1147 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); |
| 1153 | 1148 |
| 1149 // Hop the SurfaceTexture release call through the task runner used last time | |
| 1150 // we released a codec. This ensures that we release the surface texture after | |
| 1151 // the codec it's attached to (if any) is released. It's not sufficient to use | |
| 1152 // |codec_config_->task_type| because that might have changed since we | |
| 1153 // released the codec this surface was attached to. | |
| 1154 if (codec_config_->surface_texture) { | |
|
watk
2017/01/17 19:02:48
This is where surface_texture is used. We store a
| |
| 1155 AVDACodecAllocator::Instance() | |
| 1156 ->TaskRunnerFor(last_release_task_type_) | |
| 1157 ->PostTaskAndReply( | |
| 1158 FROM_HERE, base::Bind(&base::DoNothing), | |
| 1159 base::Bind(&gl::SurfaceTexture::ReleaseSurfaceTexture, | |
| 1160 codec_config_->surface_texture)); | |
| 1161 } | |
| 1162 | |
| 1154 delete this; | 1163 delete this; |
| 1155 } | 1164 } |
| 1156 | 1165 |
| 1157 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1166 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| 1158 const base::WeakPtr<Client>& decode_client, | 1167 const base::WeakPtr<Client>& decode_client, |
| 1159 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 1168 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
| 1160 return false; | 1169 return false; |
| 1161 } | 1170 } |
| 1162 | 1171 |
| 1163 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { | 1172 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 1191 | 1200 |
| 1192 pending_surface_id_ = SurfaceManager::kNoSurfaceID; | 1201 pending_surface_id_ = SurfaceManager::kNoSurfaceID; |
| 1193 UpdateSurface(); | 1202 UpdateSurface(); |
| 1194 return; | 1203 return; |
| 1195 } | 1204 } |
| 1196 | 1205 |
| 1197 // If we're currently asynchronously configuring a codec, it will be destroyed | 1206 // If we're currently asynchronously configuring a codec, it will be destroyed |
| 1198 // when configuration completes and it notices that |state_| has changed to | 1207 // when configuration completes and it notices that |state_| has changed to |
| 1199 // SURFACE_DESTROYED. | 1208 // SURFACE_DESTROYED. |
| 1200 state_ = SURFACE_DESTROYED; | 1209 state_ = SURFACE_DESTROYED; |
| 1201 if (media_codec_) { | 1210 ReleaseCodec(); |
| 1202 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | |
| 1203 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | |
| 1204 picture_buffer_manager_.CodecChanged(nullptr); | |
| 1205 } | |
| 1206 | 1211 |
| 1207 // If we're draining, signal completion now because the drain can no longer | 1212 // If we're draining, signal completion now because the drain can no longer |
| 1208 // proceed. | 1213 // proceed. |
| 1209 if (drain_type_) | 1214 if (drain_type_) |
| 1210 OnDrainCompleted(); | 1215 OnDrainCompleted(); |
| 1211 } | 1216 } |
| 1212 | 1217 |
| 1213 void AndroidVideoDecodeAccelerator::InitializeCdm() { | 1218 void AndroidVideoDecodeAccelerator::InitializeCdm() { |
| 1214 DVLOG(2) << __func__ << ": " << config_.cdm_id; | 1219 DVLOG(2) << __func__ << ": " << config_.cdm_id; |
| 1215 | 1220 |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1459 | 1464 |
| 1460 // Ensure the current context is active when switching surfaces; we may need | 1465 // Ensure the current context is active when switching surfaces; we may need |
| 1461 // to create a new texture. | 1466 // to create a new texture. |
| 1462 if (success && !make_context_current_cb_.Run()) { | 1467 if (success && !make_context_current_cb_.Run()) { |
| 1463 NOTIFY_ERROR(PLATFORM_FAILURE, | 1468 NOTIFY_ERROR(PLATFORM_FAILURE, |
| 1464 "Failed to make this decoder's GL context current when " | 1469 "Failed to make this decoder's GL context current when " |
| 1465 "switching surfaces."); | 1470 "switching surfaces."); |
| 1466 success = false; | 1471 success = false; |
| 1467 } | 1472 } |
| 1468 | 1473 |
| 1474 gl::ScopedJavaSurface new_surface; | |
| 1469 if (success) { | 1475 if (success) { |
| 1470 codec_config_->surface = picture_buffer_manager_.Initialize(new_surface_id); | 1476 new_surface = picture_buffer_manager_.Initialize(new_surface_id); |
| 1471 if (codec_config_->surface.IsEmpty()) { | 1477 if (new_surface.IsEmpty()) { |
| 1472 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); | 1478 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); |
| 1473 success = false; | 1479 success = false; |
| 1474 } | 1480 } |
| 1475 } | 1481 } |
| 1476 | 1482 |
| 1477 if (success && media_codec_ && | 1483 if (success && media_codec_ && |
| 1478 !media_codec_->SetSurface(codec_config_->surface.j_surface().obj())) { | 1484 !media_codec_->SetSurface(new_surface.j_surface().obj())) { |
| 1479 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); | 1485 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); |
| 1480 success = false; | 1486 success = false; |
| 1481 } | 1487 } |
| 1482 | 1488 |
| 1483 if (success) { | 1489 if (success) { |
| 1484 config_.surface_id = new_surface_id; | 1490 config_.surface_id = new_surface_id; |
| 1491 codec_config_->surface = std::move(new_surface); | |
| 1492 codec_config_->surface_texture = picture_buffer_manager_.surface_texture(); | |
| 1485 } else { | 1493 } else { |
| 1486 // This might be called from OnSurfaceDestroyed(), so we have to release the | 1494 // This might be called from OnSurfaceDestroyed(), so we have to release the |
| 1487 // MediaCodec if we failed to switch the surface. | 1495 // MediaCodec if we failed to switch the surface. |
| 1488 if (media_codec_) { | 1496 ReleaseCodec(); |
| 1489 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | |
| 1490 std::move(media_codec_), codec_config_->task_type, | |
| 1491 previous_surface_id); | |
| 1492 picture_buffer_manager_.CodecChanged(nullptr); | |
| 1493 } | |
| 1494 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); | 1497 AVDACodecAllocator::Instance()->DeallocateSurface(this, new_surface_id); |
| 1495 } | 1498 } |
| 1496 | 1499 |
| 1497 // Regardless of whether we succeeded, we no longer own the previous surface. | 1500 // Regardless of whether we succeeded, we no longer own the previous surface. |
| 1498 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); | 1501 AVDACodecAllocator::Instance()->DeallocateSurface(this, previous_surface_id); |
| 1499 | 1502 |
| 1500 return success; | 1503 return success; |
| 1501 } | 1504 } |
| 1502 | 1505 |
| 1506 void AndroidVideoDecodeAccelerator::ReleaseCodec() { | |
| 1507 if (!media_codec_) | |
| 1508 return; | |
| 1509 | |
| 1510 picture_buffer_manager_.CodecChanged(nullptr); | |
| 1511 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | |
| 1512 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | |
| 1513 last_release_task_type_ = codec_config_->task_type; | |
| 1514 } | |
| 1515 | |
| 1503 } // namespace media | 1516 } // namespace media |
| OLD | NEW |