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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 304 state_(NO_ERROR), | 304 state_(NO_ERROR), |
| 305 picturebuffers_requested_(false), | 305 picturebuffers_requested_(false), |
| 306 picture_buffer_manager_(this), | 306 picture_buffer_manager_(this), |
| 307 drain_type_(DRAIN_TYPE_NONE), | 307 drain_type_(DRAIN_TYPE_NONE), |
| 308 media_drm_bridge_cdm_context_(nullptr), | 308 media_drm_bridge_cdm_context_(nullptr), |
| 309 cdm_registration_id_(0), | 309 cdm_registration_id_(0), |
| 310 pending_input_buf_index_(-1), | 310 pending_input_buf_index_(-1), |
| 311 deferred_initialization_pending_(false), | 311 deferred_initialization_pending_(false), |
| 312 codec_needs_reset_(false), | 312 codec_needs_reset_(false), |
| 313 defer_surface_creation_(false), | 313 defer_surface_creation_(false), |
| 314 surface_id_(SurfaceManager::kNoSurfaceID), | |
| 315 weak_this_factory_(this) {} | 314 weak_this_factory_(this) {} |
| 316 | 315 |
| 317 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 316 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 318 DCHECK(thread_checker_.CalledOnValidThread()); | 317 DCHECK(thread_checker_.CalledOnValidThread()); |
| 319 g_avda_manager.Get().StopTimer(this); | 318 g_avda_manager.Get().StopTimer(this); |
| 320 g_avda_codec_allocator.Get().StopThread(this); | 319 g_avda_codec_allocator.Get().StopThread(this); |
| 321 | 320 |
| 322 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 321 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 323 if (!media_drm_bridge_cdm_context_) | 322 if (!media_drm_bridge_cdm_context_) |
| 324 return; | 323 return; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 << " is not hardware accelerated"; | 382 << " is not hardware accelerated"; |
| 384 return false; | 383 return false; |
| 385 } | 384 } |
| 386 | 385 |
| 387 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 386 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
| 388 if (!gles_decoder) { | 387 if (!gles_decoder) { |
| 389 DLOG(ERROR) << "Failed to get gles2 decoder instance."; | 388 DLOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 390 return false; | 389 return false; |
| 391 } | 390 } |
| 392 | 391 |
| 393 // If SetSurface() was called before initialize, pick up the surface. | 392 // SetSurface() can't be called before Initialize(), so we pick up our first |
| 394 if (pending_surface_id_) { | 393 // surface ID from the codec configuration. |
| 395 surface_id_ = pending_surface_id_.value(); | 394 DCHECK(!pending_surface_id_); |
|
dcheng
2016/11/16 00:58:45
This isn't a new issue, but it makes me concerned
DaleCurtis
2016/11/16 01:04:29
pending_surface_id_ is a base::Optional() so this
| |
| 396 pending_surface_id_.reset(); | |
| 397 } | |
| 398 | 395 |
| 399 // If we're low on resources, we may decide to defer creation of the surface | 396 // If we're low on resources, we may decide to defer creation of the surface |
| 400 // until the codec is actually used. | 397 // until the codec is actually used. |
| 401 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(surface_id_, | 398 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, |
| 402 codec_config_->codec_)) { | 399 codec_config_->codec_)) { |
| 403 DCHECK(!deferred_initialization_pending_); | 400 DCHECK(!deferred_initialization_pending_); |
| 404 | 401 |
| 405 // We should never be here if a SurfaceView is required. | 402 // We should never be here if a SurfaceView is required. |
| 406 DCHECK_EQ(surface_id_, SurfaceManager::kNoSurfaceID); | 403 DCHECK_EQ(config_.surface_id, SurfaceManager::kNoSurfaceID); |
| 407 DCHECK(g_avda_manager.Get().AllocateSurface(surface_id_, this)); | 404 DCHECK(g_avda_manager.Get().AllocateSurface(config_.surface_id, this)); |
|
dcheng
2016/11/16 00:58:45
Why do we call this in a DCHECK()? Isn't it a no-o
DaleCurtis
2016/11/16 01:04:29
It is with the current code, it's prevention again
dcheng
2016/11/16 01:06:33
It seems weird to call something called AllocateX
DaleCurtis
2016/11/16 01:16:15
Will leave for now and let watk@ remove with upcom
| |
| 408 | 405 |
| 409 defer_surface_creation_ = true; | 406 defer_surface_creation_ = true; |
| 410 NotifyInitializationComplete(true); | 407 NotifyInitializationComplete(true); |
| 411 return true; | 408 return true; |
| 412 } | 409 } |
| 413 | 410 |
| 414 // We signaled that we support deferred initialization, so see if the client | 411 // We signaled that we support deferred initialization, so see if the client |
| 415 // does also. | 412 // does also. |
| 416 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | 413 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
| 417 if (config_.is_encrypted && !deferred_initialization_pending_) { | 414 if (config_.is_encrypted && !deferred_initialization_pending_) { |
| 418 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; | 415 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; |
| 419 return false; | 416 return false; |
| 420 } | 417 } |
| 421 | 418 |
| 422 if (g_avda_manager.Get().AllocateSurface(surface_id_, this)) { | 419 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { |
| 423 // We have successfully owned the surface, so finish initialization now. | 420 // We have successfully owned the surface, so finish initialization now. |
| 424 return InitializePictureBufferManager(); | 421 return InitializePictureBufferManager(); |
| 425 } | 422 } |
| 426 | 423 |
| 427 // We have to wait for some other AVDA instance to free up the surface. | 424 // We have to wait for some other AVDA instance to free up the surface. |
| 428 // OnSurfaceAvailable will be called when it's available. | 425 // OnSurfaceAvailable will be called when it's available. |
| 429 return true; | 426 return true; |
| 430 } | 427 } |
| 431 | 428 |
| 432 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { | 429 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
| 433 DCHECK(deferred_initialization_pending_); | 430 DCHECK(deferred_initialization_pending_); |
| 434 DCHECK(!defer_surface_creation_); | 431 DCHECK(!defer_surface_creation_); |
| 435 | 432 |
| 436 if (!success || !InitializePictureBufferManager()) { | 433 if (!success || !InitializePictureBufferManager()) { |
| 437 NotifyInitializationComplete(false); | 434 NotifyInitializationComplete(false); |
| 438 deferred_initialization_pending_ = false; | 435 deferred_initialization_pending_ = false; |
| 439 } | 436 } |
| 440 } | 437 } |
| 441 | 438 |
| 442 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 439 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| 443 if (!make_context_current_cb_.Run()) { | 440 if (!make_context_current_cb_.Run()) { |
| 444 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 441 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 445 return false; | 442 return false; |
| 446 } | 443 } |
| 447 | 444 |
| 448 codec_config_->surface_ = picture_buffer_manager_.Initialize(surface_id_); | 445 codec_config_->surface_ = |
| 446 picture_buffer_manager_.Initialize(config_.surface_id); | |
| 449 if (codec_config_->surface_.IsEmpty()) | 447 if (codec_config_->surface_.IsEmpty()) |
| 450 return false; | 448 return false; |
| 451 | 449 |
| 452 on_destroying_surface_cb_ = | 450 on_destroying_surface_cb_ = |
| 453 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, | 451 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, |
| 454 weak_this_factory_.GetWeakPtr()); | 452 weak_this_factory_.GetWeakPtr()); |
| 455 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( | 453 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( |
| 456 on_destroying_surface_cb_); | 454 on_destroying_surface_cb_); |
| 457 | 455 |
| 458 if (!g_avda_codec_allocator.Get().StartThread(this)) | 456 if (!g_avda_codec_allocator.Get().StartThread(this)) |
| (...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1228 StartCodecDrain(DRAIN_FOR_RESET); | 1226 StartCodecDrain(DRAIN_FOR_RESET); |
| 1229 } else { | 1227 } else { |
| 1230 ResetCodecState(); | 1228 ResetCodecState(); |
| 1231 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1229 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1232 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 1230 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| 1233 weak_this_factory_.GetWeakPtr())); | 1231 weak_this_factory_.GetWeakPtr())); |
| 1234 } | 1232 } |
| 1235 } | 1233 } |
| 1236 | 1234 |
| 1237 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { | 1235 void AndroidVideoDecodeAccelerator::SetSurface(int32_t surface_id) { |
| 1238 if (surface_id == surface_id_) { | 1236 if (surface_id == config_.surface_id) { |
| 1239 pending_surface_id_.reset(); | 1237 pending_surface_id_.reset(); |
| 1240 return; | 1238 return; |
| 1241 } | 1239 } |
| 1242 | 1240 |
| 1243 // Surface changes never take effect immediately, they will be handled during | 1241 // Surface changes never take effect immediately, they will be handled during |
| 1244 // DequeOutput() once we get to a good switch point or immediately during an | 1242 // DequeOutput() once we get to a good switch point or immediately during an |
| 1245 // OnDestroyingSurface() call. | 1243 // OnDestroyingSurface() call. |
| 1246 pending_surface_id_ = surface_id; | 1244 pending_surface_id_ = surface_id; |
| 1247 } | 1245 } |
| 1248 | 1246 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1272 DVLOG(1) << __FUNCTION__; | 1270 DVLOG(1) << __FUNCTION__; |
| 1273 DCHECK(thread_checker_.CalledOnValidThread()); | 1271 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1274 | 1272 |
| 1275 if (!on_destroying_surface_cb_.is_null()) { | 1273 if (!on_destroying_surface_cb_.is_null()) { |
| 1276 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( | 1274 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( |
| 1277 on_destroying_surface_cb_); | 1275 on_destroying_surface_cb_); |
| 1278 } | 1276 } |
| 1279 | 1277 |
| 1280 // We no longer care about |surface_id|, in case we did before. It's okay | 1278 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1281 // if we have no surface and/or weren't the owner or a waiter. | 1279 // if we have no surface and/or weren't the owner or a waiter. |
| 1282 g_avda_manager.Get().DeallocateSurface(surface_id_, this); | 1280 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); |
| 1283 | 1281 |
| 1284 // Note that async codec construction might still be in progress. In that | 1282 // Note that async codec construction might still be in progress. In that |
| 1285 // case, the codec will be deleted when it completes once we invalidate all | 1283 // case, the codec will be deleted when it completes once we invalidate all |
| 1286 // our weak refs. | 1284 // our weak refs. |
| 1287 weak_this_factory_.InvalidateWeakPtrs(); | 1285 weak_this_factory_.InvalidateWeakPtrs(); |
| 1288 if (media_codec_) { | 1286 if (media_codec_) { |
| 1289 g_avda_manager.Get().StopTimer(this); | 1287 g_avda_manager.Get().StopTimer(this); |
| 1290 ReleaseMediaCodec(); | 1288 ReleaseMediaCodec(); |
| 1291 } | 1289 } |
| 1292 | 1290 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1306 base::WeakPtr<gpu::gles2::GLES2Decoder> | 1304 base::WeakPtr<gpu::gles2::GLES2Decoder> |
| 1307 AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 1305 AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
| 1308 return get_gles2_decoder_cb_.Run(); | 1306 return get_gles2_decoder_cb_.Run(); |
| 1309 } | 1307 } |
| 1310 | 1308 |
| 1311 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { | 1309 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { |
| 1312 DCHECK(thread_checker_.CalledOnValidThread()); | 1310 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1313 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); | 1311 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); |
| 1314 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; | 1312 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; |
| 1315 | 1313 |
| 1316 if (surface_id != surface_id_) | 1314 if (surface_id != config_.surface_id) |
| 1317 return; | 1315 return; |
| 1318 | 1316 |
| 1319 // If the API is available avoid having to restart the decoder in order to | 1317 // If the API is available avoid having to restart the decoder in order to |
| 1320 // leave fullscreen. If we don't clear the surface immediately during this | 1318 // leave fullscreen. If we don't clear the surface immediately during this |
| 1321 // callback, the MediaCodec will throw an error as the surface is destroyed. | 1319 // callback, the MediaCodec will throw an error as the surface is destroyed. |
| 1322 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { | 1320 if (base::android::BuildInfo::GetInstance()->sdk_int() >= 23) { |
| 1323 // Since we can't wait for a transition, we must invalidate all outstanding | 1321 // Since we can't wait for a transition, we must invalidate all outstanding |
| 1324 // picture buffers to avoid putting the GL system in a broken state. | 1322 // picture buffers to avoid putting the GL system in a broken state. |
| 1325 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); | 1323 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1326 | 1324 |
| 1327 // Switch away from the surface being destroyed to a surface texture. | 1325 // Switch away from the surface being destroyed to a surface texture. |
| 1328 DCHECK_NE(surface_id_, SurfaceManager::kNoSurfaceID); | 1326 DCHECK_NE(config_.surface_id, SurfaceManager::kNoSurfaceID); |
| 1329 | 1327 |
| 1330 // The leaving fullscreen notification may come in before this point. | 1328 // The leaving fullscreen notification may come in before this point. |
| 1331 if (pending_surface_id_) | 1329 if (pending_surface_id_) |
| 1332 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); | 1330 DCHECK_EQ(pending_surface_id_.value(), SurfaceManager::kNoSurfaceID); |
| 1333 | 1331 |
| 1334 pending_surface_id_ = SurfaceManager::kNoSurfaceID; | 1332 pending_surface_id_ = SurfaceManager::kNoSurfaceID; |
| 1335 UpdateSurface(); | 1333 UpdateSurface(); |
| 1336 return; | 1334 return; |
| 1337 } | 1335 } |
| 1338 | 1336 |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1587 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1585 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
| 1588 const { | 1586 const { |
| 1589 // Prevent MediaCodec from using its internal software decoders when we have | 1587 // Prevent MediaCodec from using its internal software decoders when we have |
| 1590 // more secure and up to date versions in the renderer process. | 1588 // more secure and up to date versions in the renderer process. |
| 1591 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || | 1589 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || |
| 1592 codec_config_->codec_ == kCodecVP9); | 1590 codec_config_->codec_ == kCodecVP9); |
| 1593 } | 1591 } |
| 1594 | 1592 |
| 1595 bool AndroidVideoDecodeAccelerator::UpdateSurface() { | 1593 bool AndroidVideoDecodeAccelerator::UpdateSurface() { |
| 1596 DCHECK(pending_surface_id_); | 1594 DCHECK(pending_surface_id_); |
| 1597 DCHECK_NE(surface_id_, pending_surface_id_.value()); | 1595 DCHECK_NE(config_.surface_id, pending_surface_id_.value()); |
| 1598 | 1596 |
| 1599 // Ensure the current context is active when switching surfaces; we may need | 1597 // Ensure the current context is active when switching surfaces; we may need |
| 1600 // to create a new texture. | 1598 // to create a new texture. |
| 1601 if (!make_context_current_cb_.Run()) { | 1599 if (!make_context_current_cb_.Run()) { |
| 1602 NOTIFY_ERROR(PLATFORM_FAILURE, | 1600 NOTIFY_ERROR(PLATFORM_FAILURE, |
| 1603 "Failed to make this decoder's GL context current when " | 1601 "Failed to make this decoder's GL context current when " |
| 1604 "switching surfaces."); | 1602 "switching surfaces."); |
| 1605 return false; | 1603 return false; |
| 1606 } | 1604 } |
| 1607 | 1605 |
| 1608 surface_id_ = pending_surface_id_.value(); | 1606 config_.surface_id = pending_surface_id_.value(); |
| 1609 codec_config_->surface_ = | 1607 codec_config_->surface_ = |
| 1610 picture_buffer_manager_.Initialize(pending_surface_id_.value()); | 1608 picture_buffer_manager_.Initialize(pending_surface_id_.value()); |
| 1611 if (codec_config_->surface_.IsEmpty()) { | 1609 if (codec_config_->surface_.IsEmpty()) { |
| 1612 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); | 1610 NOTIFY_ERROR(PLATFORM_FAILURE, "Failed to switch surfaces."); |
| 1613 return false; | 1611 return false; |
| 1614 } | 1612 } |
| 1615 | 1613 |
| 1616 if (media_codec_ && | 1614 if (media_codec_ && |
| 1617 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) { | 1615 !media_codec_->SetSurface(codec_config_->surface_.j_surface().obj())) { |
| 1618 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); | 1616 NOTIFY_ERROR(PLATFORM_FAILURE, "MediaCodec failed to switch surfaces."); |
| 1619 return false; | 1617 return false; |
| 1620 } | 1618 } |
| 1621 | 1619 |
| 1622 pending_surface_id_.reset(); | 1620 pending_surface_id_.reset(); |
| 1623 return true; | 1621 return true; |
| 1624 } | 1622 } |
| 1625 | 1623 |
| 1626 } // namespace media | 1624 } // namespace media |
| OLD | NEW |