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 "content/common/gpu/media/android_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/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 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 is_encrypted_(false), | 312 is_encrypted_(false), |
| 313 state_(NO_ERROR), | 313 state_(NO_ERROR), |
| 314 picturebuffers_requested_(false), | 314 picturebuffers_requested_(false), |
| 315 drain_type_(DRAIN_TYPE_NONE), | 315 drain_type_(DRAIN_TYPE_NONE), |
| 316 media_drm_bridge_cdm_context_(nullptr), | 316 media_drm_bridge_cdm_context_(nullptr), |
| 317 cdm_registration_id_(0), | 317 cdm_registration_id_(0), |
| 318 pending_input_buf_index_(-1), | 318 pending_input_buf_index_(-1), |
| 319 error_sequence_token_(0), | 319 error_sequence_token_(0), |
| 320 defer_errors_(false), | 320 defer_errors_(false), |
| 321 deferred_initialization_pending_(false), | 321 deferred_initialization_pending_(false), |
| 322 surface_id_(media::VideoDecodeAccelerator::Config::kNoSurfaceID), | |
| 322 weak_this_factory_(this) {} | 323 weak_this_factory_(this) {} |
| 323 | 324 |
| 324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 325 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 325 DCHECK(thread_checker_.CalledOnValidThread()); | 326 DCHECK(thread_checker_.CalledOnValidThread()); |
| 326 g_avda_timer.Pointer()->StopTimer(this); | 327 g_avda_timer.Pointer()->StopTimer(this); |
| 327 g_avda_timer.Pointer()->StopThread(this); | 328 g_avda_timer.Pointer()->StopThread(this); |
| 328 | 329 |
| 329 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 330 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 330 if (!media_drm_bridge_cdm_context_) | 331 if (!media_drm_bridge_cdm_context_) |
| 331 return; | 332 return; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 409 } else { | 410 } else { |
| 410 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; | 411 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; |
| 411 strategy_.reset(new AndroidCopyingBackingStrategy(this)); | 412 strategy_.reset(new AndroidCopyingBackingStrategy(this)); |
| 412 } | 413 } |
| 413 | 414 |
| 414 if (!make_context_current_cb_.Run()) { | 415 if (!make_context_current_cb_.Run()) { |
| 415 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 416 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 416 return false; | 417 return false; |
| 417 } | 418 } |
| 418 | 419 |
| 419 codec_config_->surface_ = strategy_->Initialize(config.surface_id); | 420 surface_id_ = config.surface_id; |
| 421 codec_config_->surface_ = strategy_->Initialize(surface_id_); | |
| 420 if (codec_config_->surface_.IsEmpty()) { | 422 if (codec_config_->surface_.IsEmpty()) { |
| 421 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " | 423 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " |
| 422 "Java surface is empty."; | 424 "Java surface is empty."; |
| 423 return false; | 425 return false; |
| 424 } | 426 } |
| 425 | 427 |
| 428 on_destroying_surface_cb_ = | |
|
liberato (no reviews please)
2016/04/27 16:50:04
all of the callback code might be better in the de
watk
2016/04/27 18:54:04
I'm not sure if I agree. I think this is simpler i
liberato (no reviews please)
2016/04/27 21:00:37
what brought it up is that AVDA didn't even record
watk
2016/04/27 21:14:07
Gotcha, well since you're not too worried I'll def
| |
| 429 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, | |
| 430 weak_this_factory_.GetWeakPtr()); | |
| 431 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( | |
| 432 on_destroying_surface_cb_); | |
| 433 | |
| 426 // TODO(watk,liberato): move this into the strategy. | 434 // TODO(watk,liberato): move this into the strategy. |
| 427 scoped_refptr<gfx::SurfaceTexture> surface_texture = | 435 scoped_refptr<gfx::SurfaceTexture> surface_texture = |
| 428 strategy_->GetSurfaceTexture(); | 436 strategy_->GetSurfaceTexture(); |
| 429 if (surface_texture) { | 437 if (surface_texture) { |
| 430 on_frame_available_handler_ = | 438 on_frame_available_handler_ = |
| 431 new OnFrameAvailableHandler(this, surface_texture); | 439 new OnFrameAvailableHandler(this, surface_texture); |
| 432 } | 440 } |
| 433 | 441 |
| 434 // Start the thread for async configuration, even if we don't need it now. | 442 // Start the thread for async configuration, even if we don't need it now. |
| 435 // ResetCodecState might rebuild the codec later, for example. | 443 // ResetCodecState might rebuild the codec later, for example. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 | 505 |
| 498 NOTIMPLEMENTED(); | 506 NOTIMPLEMENTED(); |
| 499 NotifyInitializationComplete(false); | 507 NotifyInitializationComplete(false); |
| 500 | 508 |
| 501 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 509 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 502 } | 510 } |
| 503 | 511 |
| 504 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { | 512 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { |
| 505 DCHECK(thread_checker_.CalledOnValidThread()); | 513 DCHECK(thread_checker_.CalledOnValidThread()); |
| 506 TRACE_EVENT0("media", "AVDA::DoIOTask"); | 514 TRACE_EVENT0("media", "AVDA::DoIOTask"); |
| 507 if (state_ == ERROR || state_ == WAITING_FOR_CODEC) | 515 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || |
| 516 state_ == SURFACE_DESTROYED) { | |
| 508 return; | 517 return; |
| 518 } | |
| 509 | 519 |
| 510 strategy_->MaybeRenderEarly(); | 520 strategy_->MaybeRenderEarly(); |
| 511 bool did_work = QueueInput(); | 521 bool did_work = QueueInput(); |
| 512 while (DequeueOutput()) | 522 while (DequeueOutput()) |
| 513 did_work = true; | 523 did_work = true; |
| 514 | 524 |
| 515 ManageTimer(did_work || start_timer); | 525 ManageTimer(did_work || start_timer); |
| 516 } | 526 } |
| 517 | 527 |
| 518 bool AndroidVideoDecodeAccelerator::QueueInput() { | 528 bool AndroidVideoDecodeAccelerator::QueueInput() { |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 999 return std::unique_ptr<media::VideoCodecBridge>( | 1009 return std::unique_ptr<media::VideoCodecBridge>( |
| 1000 media::VideoCodecBridge::CreateDecoder( | 1010 media::VideoCodecBridge::CreateDecoder( |
| 1001 codec_config->codec_, codec_config->needs_protected_surface_, | 1011 codec_config->codec_, codec_config->needs_protected_surface_, |
| 1002 codec_config->initial_expected_coded_size_, | 1012 codec_config->initial_expected_coded_size_, |
| 1003 codec_config->surface_.j_surface().obj(), media_crypto, true)); | 1013 codec_config->surface_.j_surface().obj(), media_crypto, true)); |
| 1004 } | 1014 } |
| 1005 | 1015 |
| 1006 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 1016 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
| 1007 std::unique_ptr<media::VideoCodecBridge> media_codec) { | 1017 std::unique_ptr<media::VideoCodecBridge> media_codec) { |
| 1008 DCHECK(thread_checker_.CalledOnValidThread()); | 1018 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1009 DCHECK_EQ(state_, WAITING_FOR_CODEC); | 1019 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
| 1010 | |
| 1011 media_codec_ = std::move(media_codec); | |
| 1012 | 1020 |
| 1013 // Record one instance of the codec being initialized. | 1021 // Record one instance of the codec being initialized. |
| 1014 RecordFormatChangedMetric(FormatChangedValue::CodecInitialized); | 1022 RecordFormatChangedMetric(FormatChangedValue::CodecInitialized); |
| 1015 | 1023 |
| 1016 strategy_->CodecChanged(media_codec_.get()); | |
| 1017 | |
| 1018 // If we are supposed to notify that initialization is complete, then do so | 1024 // If we are supposed to notify that initialization is complete, then do so |
| 1019 // now. Otherwise, this is a reconfiguration. | 1025 // now. Otherwise, this is a reconfiguration. |
| 1020 if (deferred_initialization_pending_) { | 1026 if (deferred_initialization_pending_) { |
| 1021 NotifyInitializationComplete(!!media_codec_); | 1027 // Losing the output surface is not considered an error state, so notify |
| 1028 // success. The client will destroy this soon. | |
| 1029 NotifyInitializationComplete(state_ == SURFACE_DESTROYED ? true | |
| 1030 : !!media_codec); | |
| 1022 deferred_initialization_pending_ = false; | 1031 deferred_initialization_pending_ = false; |
| 1023 } | 1032 } |
| 1024 | 1033 |
| 1034 if (state_ == SURFACE_DESTROYED) | |
|
liberato (no reviews please)
2016/04/27 16:50:04
please add a comment that this will release the me
watk
2016/04/27 18:54:04
Done.
| |
| 1035 return; | |
| 1036 | |
| 1037 media_codec_ = std::move(media_codec); | |
| 1038 strategy_->CodecChanged(media_codec_.get()); | |
| 1025 if (!media_codec_) { | 1039 if (!media_codec_) { |
| 1026 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); | 1040 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); |
| 1027 return; | 1041 return; |
| 1028 } | 1042 } |
| 1029 | 1043 |
| 1030 state_ = NO_ERROR; | 1044 state_ = NO_ERROR; |
| 1031 | 1045 |
| 1032 ManageTimer(true); | 1046 ManageTimer(true); |
| 1033 } | 1047 } |
| 1034 | 1048 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1090 } | 1104 } |
| 1091 drain_type_ = DRAIN_TYPE_NONE; | 1105 drain_type_ = DRAIN_TYPE_NONE; |
| 1092 } | 1106 } |
| 1093 | 1107 |
| 1094 void AndroidVideoDecodeAccelerator::ResetCodecState( | 1108 void AndroidVideoDecodeAccelerator::ResetCodecState( |
| 1095 const base::Closure& done_cb) { | 1109 const base::Closure& done_cb) { |
| 1096 DCHECK(thread_checker_.CalledOnValidThread()); | 1110 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1097 | 1111 |
| 1098 // If there is already a reset in flight, then that counts. This can really | 1112 // If there is already a reset in flight, then that counts. This can really |
| 1099 // only happen if somebody calls Reset. | 1113 // only happen if somebody calls Reset. |
| 1100 if (state_ == WAITING_FOR_CODEC) { | 1114 // If the surface is destroyed there's nothing to do. |
| 1115 if (state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED) { | |
| 1101 if (!done_cb.is_null()) | 1116 if (!done_cb.is_null()) |
| 1102 done_cb.Run(); | 1117 done_cb.Run(); |
| 1103 return; | 1118 return; |
| 1104 } | 1119 } |
| 1105 | 1120 |
| 1106 bitstream_buffers_in_decoder_.clear(); | 1121 bitstream_buffers_in_decoder_.clear(); |
| 1107 | 1122 |
| 1108 if (pending_input_buf_index_ != -1) { | 1123 if (pending_input_buf_index_ != -1) { |
| 1109 // The data for that index exists in the input buffer, but corresponding | 1124 // The data for that index exists in the input buffer, but corresponding |
| 1110 // shm block been deleted. Check that it is safe to flush the coec, i.e. | 1125 // shm block been deleted. Check that it is safe to flush the coec, i.e. |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1217 StartCodecDrain(DRAIN_FOR_DESTROY); | 1232 StartCodecDrain(DRAIN_FOR_DESTROY); |
| 1218 } else { | 1233 } else { |
| 1219 ActualDestroy(); | 1234 ActualDestroy(); |
| 1220 } | 1235 } |
| 1221 } | 1236 } |
| 1222 | 1237 |
| 1223 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1238 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
| 1224 DVLOG(1) << __FUNCTION__; | 1239 DVLOG(1) << __FUNCTION__; |
| 1225 DCHECK(thread_checker_.CalledOnValidThread()); | 1240 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1226 | 1241 |
| 1242 if (!on_destroying_surface_cb_.is_null()) { | |
| 1243 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( | |
| 1244 on_destroying_surface_cb_); | |
| 1245 } | |
| 1246 | |
| 1227 // Note that async codec construction might still be in progress. In that | 1247 // Note that async codec construction might still be in progress. In that |
| 1228 // case, the codec will be deleted when it completes once we invalidate all | 1248 // case, the codec will be deleted when it completes once we invalidate all |
| 1229 // our weak refs. | 1249 // our weak refs. |
| 1230 weak_this_factory_.InvalidateWeakPtrs(); | 1250 weak_this_factory_.InvalidateWeakPtrs(); |
| 1231 if (media_codec_) { | 1251 if (media_codec_) { |
| 1232 g_avda_timer.Pointer()->StopTimer(this); | 1252 g_avda_timer.Pointer()->StopTimer(this); |
| 1233 media_codec_.reset(); | 1253 media_codec_.reset(); |
| 1234 } | 1254 } |
| 1235 delete this; | 1255 delete this; |
| 1236 } | 1256 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1270 | 1290 |
| 1271 DCHECK_LE(1u, picture_buffer.internal_texture_ids().size()); | 1291 DCHECK_LE(1u, picture_buffer.internal_texture_ids().size()); |
| 1272 gpu::gles2::TextureRef* texture_ref = | 1292 gpu::gles2::TextureRef* texture_ref = |
| 1273 texture_manager->GetTexture(picture_buffer.internal_texture_ids()[0]); | 1293 texture_manager->GetTexture(picture_buffer.internal_texture_ids()[0]); |
| 1274 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, | 1294 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, |
| 1275 nullptr); | 1295 nullptr); |
| 1276 | 1296 |
| 1277 return texture_ref; | 1297 return texture_ref; |
| 1278 } | 1298 } |
| 1279 | 1299 |
| 1300 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { | |
| 1301 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1302 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); | |
| 1303 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; | |
| 1304 | |
| 1305 if (surface_id != surface_id_) | |
| 1306 return; | |
| 1307 | |
| 1308 // If we're currently asynchronously configuring a codec, it will be destroyed | |
| 1309 // when configuration completes and it notices that |state_| has changed to | |
| 1310 // SURFACE_DESTROYED. | |
| 1311 state_ = SURFACE_DESTROYED; | |
| 1312 if (media_codec_) { | |
| 1313 media_codec_.reset(); | |
| 1314 strategy_->CodecChanged(media_codec_.get()); | |
|
liberato (no reviews please)
2016/04/27 16:50:04
should this also clear |drain_type_|, for complete
watk
2016/04/27 18:54:04
Good call, I think this was broken if a drain was
liberato (no reviews please)
2016/04/27 21:00:37
actually, i didn't think about it that much. good
| |
| 1315 } | |
| 1316 } | |
| 1317 | |
| 1280 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { | 1318 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { |
| 1281 // Remember: this may be on any thread. | 1319 // Remember: this may be on any thread. |
| 1282 DCHECK(strategy_); | 1320 DCHECK(strategy_); |
| 1283 strategy_->OnFrameAvailable(); | 1321 strategy_->OnFrameAvailable(); |
| 1284 } | 1322 } |
| 1285 | 1323 |
| 1286 void AndroidVideoDecodeAccelerator::PostError( | 1324 void AndroidVideoDecodeAccelerator::PostError( |
| 1287 const ::tracked_objects::Location& from_here, | 1325 const ::tracked_objects::Location& from_here, |
| 1288 media::VideoDecodeAccelerator::Error error) { | 1326 media::VideoDecodeAccelerator::Error error) { |
| 1289 base::MessageLoop::current()->PostDelayedTask( | 1327 base::MessageLoop::current()->PostDelayedTask( |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1458 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { | 1496 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { |
| 1459 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: | 1497 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: |
| 1460 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1498 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| 1461 } | 1499 } |
| 1462 } | 1500 } |
| 1463 | 1501 |
| 1464 return capabilities; | 1502 return capabilities; |
| 1465 } | 1503 } |
| 1466 | 1504 |
| 1467 } // namespace content | 1505 } // namespace content |
| OLD | NEW |