Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: content/common/gpu/media/android_video_decode_accelerator.cc

Issue 1920093003: media: Handle output SurfaceView destruction in AVDA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@svteardown
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698