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 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 is_encrypted_(false), | 311 is_encrypted_(false), |
| 312 state_(NO_ERROR), | 312 state_(NO_ERROR), |
| 313 picturebuffers_requested_(false), | 313 picturebuffers_requested_(false), |
| 314 drain_type_(DRAIN_TYPE_NONE), | 314 drain_type_(DRAIN_TYPE_NONE), |
| 315 media_drm_bridge_cdm_context_(nullptr), | 315 media_drm_bridge_cdm_context_(nullptr), |
| 316 cdm_registration_id_(0), | 316 cdm_registration_id_(0), |
| 317 pending_input_buf_index_(-1), | 317 pending_input_buf_index_(-1), |
| 318 error_sequence_token_(0), | 318 error_sequence_token_(0), |
| 319 defer_errors_(false), | 319 defer_errors_(false), |
| 320 deferred_initialization_pending_(false), | 320 deferred_initialization_pending_(false), |
| 321 surface_id_(media::VideoDecodeAccelerator::Config::kNoSurfaceID), | |
| 321 weak_this_factory_(this) {} | 322 weak_this_factory_(this) {} |
| 322 | 323 |
| 323 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
| 324 DCHECK(thread_checker_.CalledOnValidThread()); | 325 DCHECK(thread_checker_.CalledOnValidThread()); |
| 325 g_avda_timer.Pointer()->StopTimer(this); | 326 g_avda_timer.Pointer()->StopTimer(this); |
| 326 g_avda_timer.Pointer()->StopThread(this); | 327 g_avda_timer.Pointer()->StopThread(this); |
| 327 | 328 |
| 328 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 329 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 329 if (!media_drm_bridge_cdm_context_) | 330 if (!media_drm_bridge_cdm_context_) |
| 330 return; | 331 return; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 } else { | 409 } else { |
| 409 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; | 410 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; |
| 410 strategy_.reset(new AndroidCopyingBackingStrategy(this)); | 411 strategy_.reset(new AndroidCopyingBackingStrategy(this)); |
| 411 } | 412 } |
| 412 | 413 |
| 413 if (!make_context_current_cb_.Run()) { | 414 if (!make_context_current_cb_.Run()) { |
| 414 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 415 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 415 return false; | 416 return false; |
| 416 } | 417 } |
| 417 | 418 |
| 418 codec_config_->surface_ = strategy_->Initialize(config.surface_id); | 419 surface_id_ = config.surface_id; |
| 420 codec_config_->surface_ = strategy_->Initialize(surface_id_); | |
| 419 if (codec_config_->surface_.IsEmpty()) { | 421 if (codec_config_->surface_.IsEmpty()) { |
| 420 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " | 422 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " |
| 421 "Java surface is empty."; | 423 "Java surface is empty."; |
| 422 return false; | 424 return false; |
| 423 } | 425 } |
| 424 | 426 |
| 427 on_destroying_surface_cb_ = | |
| 428 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, | |
| 429 weak_this_factory_.GetWeakPtr()); | |
| 430 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( | |
| 431 on_destroying_surface_cb_); | |
| 432 | |
| 425 // TODO(watk,liberato): move this into the strategy. | 433 // TODO(watk,liberato): move this into the strategy. |
| 426 scoped_refptr<gfx::SurfaceTexture> surface_texture = | 434 scoped_refptr<gfx::SurfaceTexture> surface_texture = |
| 427 strategy_->GetSurfaceTexture(); | 435 strategy_->GetSurfaceTexture(); |
| 428 if (surface_texture) { | 436 if (surface_texture) { |
| 429 on_frame_available_handler_ = | 437 on_frame_available_handler_ = |
| 430 new OnFrameAvailableHandler(this, surface_texture); | 438 new OnFrameAvailableHandler(this, surface_texture); |
| 431 } | 439 } |
| 432 | 440 |
| 433 // Start the thread for async configuration, even if we don't need it now. | 441 // Start the thread for async configuration, even if we don't need it now. |
| 434 // ResetCodecState might rebuild the codec later, for example. | 442 // ResetCodecState might rebuild the codec later, for example. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 | 504 |
| 497 NOTIMPLEMENTED(); | 505 NOTIMPLEMENTED(); |
| 498 NotifyInitializationComplete(false); | 506 NotifyInitializationComplete(false); |
| 499 | 507 |
| 500 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 508 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 501 } | 509 } |
| 502 | 510 |
| 503 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { | 511 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { |
| 504 DCHECK(thread_checker_.CalledOnValidThread()); | 512 DCHECK(thread_checker_.CalledOnValidThread()); |
| 505 TRACE_EVENT0("media", "AVDA::DoIOTask"); | 513 TRACE_EVENT0("media", "AVDA::DoIOTask"); |
| 506 if (state_ == ERROR || state_ == WAITING_FOR_CODEC) | 514 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || |
| 515 state_ == SURFACE_DESTROYED) { | |
| 507 return; | 516 return; |
| 517 } | |
| 508 | 518 |
| 509 strategy_->MaybeRenderEarly(); | 519 strategy_->MaybeRenderEarly(); |
| 510 bool did_work = QueueInput(); | 520 bool did_work = QueueInput(); |
| 511 while (DequeueOutput()) | 521 while (DequeueOutput()) |
| 512 did_work = true; | 522 did_work = true; |
| 513 | 523 |
| 514 ManageTimer(did_work || start_timer); | 524 ManageTimer(did_work || start_timer); |
| 515 } | 525 } |
| 516 | 526 |
| 517 bool AndroidVideoDecodeAccelerator::QueueInput() { | 527 bool AndroidVideoDecodeAccelerator::QueueInput() { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 667 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); | 677 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); |
| 668 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( | 678 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( |
| 669 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp, | 679 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp, |
| 670 &eos, NULL); | 680 &eos, NULL); |
| 671 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status, | 681 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status, |
| 672 "presentation_timestamp (ms)", | 682 "presentation_timestamp (ms)", |
| 673 presentation_timestamp.InMilliseconds()); | 683 presentation_timestamp.InMilliseconds()); |
| 674 | 684 |
| 675 switch (status) { | 685 switch (status) { |
| 676 case media::MEDIA_CODEC_ERROR: | 686 case media::MEDIA_CODEC_ERROR: |
| 677 // Do not post an error if we are draining for reset and destroy. | 687 // Do not post an error if we are draining for reset or destroy. |
| 678 // Instead, run the drain completion task. | 688 // Instead, run the drain completion task. |
| 679 if (IsDrainingForResetOrDestroy()) { | 689 if (IsDrainingForResetOrDestroy()) { |
| 680 DVLOG(1) << __FUNCTION__ << ": error while codec draining"; | 690 DVLOG(1) << __FUNCTION__ << ": error while codec draining"; |
| 681 state_ = ERROR; | 691 state_ = ERROR; |
| 682 OnDrainCompleted(); | 692 OnDrainCompleted(); |
| 683 } else { | 693 } else { |
| 684 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); | 694 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); |
| 685 } | 695 } |
| 686 return false; | 696 return false; |
| 687 | 697 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 933 } | 943 } |
| 934 | 944 |
| 935 strategy_->ReuseOnePictureBuffer(i->second); | 945 strategy_->ReuseOnePictureBuffer(i->second); |
| 936 DoIOTask(true); | 946 DoIOTask(true); |
| 937 } | 947 } |
| 938 | 948 |
| 939 void AndroidVideoDecodeAccelerator::Flush() { | 949 void AndroidVideoDecodeAccelerator::Flush() { |
| 940 DVLOG(1) << __FUNCTION__; | 950 DVLOG(1) << __FUNCTION__; |
| 941 DCHECK(thread_checker_.CalledOnValidThread()); | 951 DCHECK(thread_checker_.CalledOnValidThread()); |
| 942 | 952 |
| 943 StartCodecDrain(DRAIN_FOR_FLUSH); | 953 if (state_ == SURFACE_DESTROYED) { |
| 954 NotifyFlushDone(); | |
| 955 } else { | |
| 956 StartCodecDrain(DRAIN_FOR_FLUSH); | |
| 957 } | |
| 944 } | 958 } |
| 945 | 959 |
| 946 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 960 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
| 947 DCHECK(thread_checker_.CalledOnValidThread()); | 961 DCHECK(thread_checker_.CalledOnValidThread()); |
| 948 | 962 |
| 949 // It's probably okay just to return here, since the codec will be configured | 963 // It's probably okay just to return here, since the codec will be configured |
| 950 // asynchronously. It's unclear that any state for the new request could | 964 // asynchronously. It's unclear that any state for the new request could |
| 951 // be different, unless somebody modifies |codec_config_| while we're already | 965 // be different, unless somebody modifies |codec_config_| while we're already |
| 952 // waiting for a codec. One shouldn't do that for thread safety. | 966 // waiting for a codec. One shouldn't do that for thread safety. |
| 953 DCHECK_NE(state_, WAITING_FOR_CODEC); | 967 DCHECK_NE(state_, WAITING_FOR_CODEC); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 999 return std::unique_ptr<media::VideoCodecBridge>( | 1013 return std::unique_ptr<media::VideoCodecBridge>( |
| 1000 media::VideoCodecBridge::CreateDecoder( | 1014 media::VideoCodecBridge::CreateDecoder( |
| 1001 codec_config->codec_, codec_config->needs_protected_surface_, | 1015 codec_config->codec_, codec_config->needs_protected_surface_, |
| 1002 codec_config->initial_expected_coded_size_, | 1016 codec_config->initial_expected_coded_size_, |
| 1003 codec_config->surface_.j_surface().obj(), media_crypto, true)); | 1017 codec_config->surface_.j_surface().obj(), media_crypto, true)); |
| 1004 } | 1018 } |
| 1005 | 1019 |
| 1006 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 1020 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
| 1007 std::unique_ptr<media::VideoCodecBridge> media_codec) { | 1021 std::unique_ptr<media::VideoCodecBridge> media_codec) { |
| 1008 DCHECK(thread_checker_.CalledOnValidThread()); | 1022 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1009 DCHECK_EQ(state_, WAITING_FOR_CODEC); | 1023 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
| 1010 | |
| 1011 media_codec_ = std::move(media_codec); | |
| 1012 | 1024 |
| 1013 // Record one instance of the codec being initialized. | 1025 // Record one instance of the codec being initialized. |
| 1014 RecordFormatChangedMetric(FormatChangedValue::CodecInitialized); | 1026 RecordFormatChangedMetric(FormatChangedValue::CodecInitialized); |
| 1015 | 1027 |
| 1016 strategy_->CodecChanged(media_codec_.get()); | |
| 1017 | |
| 1018 // If we are supposed to notify that initialization is complete, then do so | 1028 // If we are supposed to notify that initialization is complete, then do so |
| 1019 // now. Otherwise, this is a reconfiguration. | 1029 // now. Otherwise, this is a reconfiguration. |
| 1020 if (deferred_initialization_pending_) { | 1030 if (deferred_initialization_pending_) { |
| 1021 NotifyInitializationComplete(!!media_codec_); | 1031 // Losing the output surface is not considered an error state, so notify |
| 1032 // success. The client will destroy this soon. | |
| 1033 NotifyInitializationComplete(state_ == SURFACE_DESTROYED ? true | |
| 1034 : !!media_codec); | |
| 1022 deferred_initialization_pending_ = false; | 1035 deferred_initialization_pending_ = false; |
| 1023 } | 1036 } |
| 1024 | 1037 |
| 1038 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, | |
| 1039 // then the codec is already invalid so we return early and drop it. | |
| 1040 if (state_ == SURFACE_DESTROYED) | |
| 1041 return; | |
| 1042 | |
| 1043 media_codec_ = std::move(media_codec); | |
| 1044 strategy_->CodecChanged(media_codec_.get()); | |
| 1025 if (!media_codec_) { | 1045 if (!media_codec_) { |
| 1026 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); | 1046 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); |
| 1027 return; | 1047 return; |
| 1028 } | 1048 } |
| 1029 | 1049 |
| 1030 state_ = NO_ERROR; | 1050 state_ = NO_ERROR; |
| 1031 | 1051 |
| 1032 ManageTimer(true); | 1052 ManageTimer(true); |
| 1033 } | 1053 } |
| 1034 | 1054 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1090 } | 1110 } |
| 1091 drain_type_ = DRAIN_TYPE_NONE; | 1111 drain_type_ = DRAIN_TYPE_NONE; |
| 1092 } | 1112 } |
| 1093 | 1113 |
| 1094 void AndroidVideoDecodeAccelerator::ResetCodecState( | 1114 void AndroidVideoDecodeAccelerator::ResetCodecState( |
| 1095 const base::Closure& done_cb) { | 1115 const base::Closure& done_cb) { |
| 1096 DCHECK(thread_checker_.CalledOnValidThread()); | 1116 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1097 | 1117 |
| 1098 // If there is already a reset in flight, then that counts. This can really | 1118 // If there is already a reset in flight, then that counts. This can really |
| 1099 // only happen if somebody calls Reset. | 1119 // only happen if somebody calls Reset. |
| 1100 if (state_ == WAITING_FOR_CODEC) { | 1120 // If the surface is destroyed there's nothing to do. |
| 1121 if (state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED) { | |
| 1101 if (!done_cb.is_null()) | 1122 if (!done_cb.is_null()) |
| 1102 done_cb.Run(); | 1123 done_cb.Run(); |
| 1103 return; | 1124 return; |
| 1104 } | 1125 } |
| 1105 | 1126 |
| 1106 bitstream_buffers_in_decoder_.clear(); | 1127 bitstream_buffers_in_decoder_.clear(); |
| 1107 | 1128 |
| 1108 if (pending_input_buf_index_ != -1) { | 1129 if (pending_input_buf_index_ != -1) { |
| 1109 // The data for that index exists in the input buffer, but corresponding | 1130 // 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. | 1131 // 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); | 1238 StartCodecDrain(DRAIN_FOR_DESTROY); |
| 1218 } else { | 1239 } else { |
| 1219 ActualDestroy(); | 1240 ActualDestroy(); |
| 1220 } | 1241 } |
| 1221 } | 1242 } |
| 1222 | 1243 |
| 1223 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1244 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
| 1224 DVLOG(1) << __FUNCTION__; | 1245 DVLOG(1) << __FUNCTION__; |
| 1225 DCHECK(thread_checker_.CalledOnValidThread()); | 1246 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1226 | 1247 |
| 1248 if (!on_destroying_surface_cb_.is_null()) { | |
| 1249 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( | |
| 1250 on_destroying_surface_cb_); | |
| 1251 } | |
| 1252 | |
| 1227 // Note that async codec construction might still be in progress. In that | 1253 // 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 | 1254 // case, the codec will be deleted when it completes once we invalidate all |
| 1229 // our weak refs. | 1255 // our weak refs. |
| 1230 weak_this_factory_.InvalidateWeakPtrs(); | 1256 weak_this_factory_.InvalidateWeakPtrs(); |
| 1231 if (media_codec_) { | 1257 if (media_codec_) { |
| 1232 g_avda_timer.Pointer()->StopTimer(this); | 1258 g_avda_timer.Pointer()->StopTimer(this); |
| 1233 media_codec_.reset(); | 1259 media_codec_.reset(); |
| 1234 } | 1260 } |
| 1235 delete this; | 1261 delete this; |
| 1236 } | 1262 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1270 | 1296 |
| 1271 DCHECK_LE(1u, picture_buffer.internal_texture_ids().size()); | 1297 DCHECK_LE(1u, picture_buffer.internal_texture_ids().size()); |
| 1272 gpu::gles2::TextureRef* texture_ref = | 1298 gpu::gles2::TextureRef* texture_ref = |
| 1273 texture_manager->GetTexture(picture_buffer.internal_texture_ids()[0]); | 1299 texture_manager->GetTexture(picture_buffer.internal_texture_ids()[0]); |
| 1274 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, | 1300 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, |
| 1275 nullptr); | 1301 nullptr); |
| 1276 | 1302 |
| 1277 return texture_ref; | 1303 return texture_ref; |
| 1278 } | 1304 } |
| 1279 | 1305 |
| 1306 void SynchronouslyDrainCodec() { | |
| 1307 // The timeout for dequeueing input/output buffers picked mostly arbitrarily. | |
| 1308 // It's about as long as a working MediaCodec might conceivably delay before | |
| 1309 // returning something. If the timeout is exceeded the MediaCodec might hang | |
| 1310 // when we try to delete it later, but that's effectively the same thing as | |
| 1311 // waiting longer here anyway. | |
| 1312 const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(3); | |
| 1313 strategy_->ReleaseCodecBuffers(output_picture_buffers_); | |
| 1314 | |
| 1315 // If we're in the middle of a drain already, don't queue another EOS; just | |
| 1316 // drain until we get the one already queued. | |
| 1317 if (drain_type_ != DRAIN_TYPE_NONE) { | |
| 1318 int input_buf_index = -1; | |
| 1319 media::MediaCodecStatus status = | |
| 1320 media_codec_->DequeueInputBuffer(kTimeout, &input_buf_index); | |
|
liberato (no reviews please)
2016/05/04 14:19:56
input buffers might become available after we deco
watk
2016/05/04 18:18:46
Do we care about input buffers? We only need to qu
liberato (no reviews please)
2016/05/04 18:30:00
my concern is how does one know that an input buff
| |
| 1321 if (status != media::MEDIA_CODEC_OK) | |
| 1322 return; | |
| 1323 DCHECK_NE(input_buf_index, -1); | |
| 1324 | |
| 1325 media_codec_->QueueEOS(input_buf_index); | |
| 1326 } | |
| 1327 | |
| 1328 // Drain all of the output buffers. | |
| 1329 for (;;) { | |
| 1330 int32_t buf_index = -1; | |
| 1331 size_t offset = 0; | |
| 1332 size_t size = 0; | |
| 1333 base::TimeDelta presentation_timestamp; | |
| 1334 bool eos = false; | |
| 1335 media::MediaCodecStatus status = | |
| 1336 media_codec_->DequeueOutputBuffer(kTimeout, &buf_index, &offset, &size, | |
| 1337 &presentation_timestamp, &eos, NULL); | |
| 1338 switch (status) { | |
| 1339 case media::MEDIA_CODEC_ERROR: | |
| 1340 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: | |
| 1341 return; | |
| 1342 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: | |
| 1343 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: | |
| 1344 continue; | |
| 1345 case media::MEDIA_CODEC_OK: | |
| 1346 DCHECK_GE(buf_index, 0); | |
| 1347 if (eos) | |
| 1348 return; | |
| 1349 media_codec_->ReleaseOutputBuffer(buf_index, false); | |
| 1350 } | |
| 1351 } | |
| 1352 } | |
| 1353 | |
| 1354 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { | |
| 1355 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 1356 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); | |
| 1357 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; | |
| 1358 | |
| 1359 if (surface_id != surface_id_) | |
| 1360 return; | |
| 1361 | |
| 1362 // Some VP8 files require a complete MediaCodec drain before we can call | |
| 1363 // MediaCodec.flush() or MediaCodec.reset() so we must synchronously drain | |
| 1364 // the MediaCodec here. http://crbug.com/598963. | |
| 1365 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) | |
| 1366 SynchronouslyDrainCodec(); | |
| 1367 | |
| 1368 // If we're currently asynchronously configuring a codec, it will be destroyed | |
| 1369 // when configuration completes and it notices that |state_| has changed to | |
| 1370 // SURFACE_DESTROYED. | |
| 1371 state_ = SURFACE_DESTROYED; | |
| 1372 if (media_codec_) { | |
| 1373 media_codec_.reset(); | |
| 1374 strategy_->CodecChanged(media_codec_.get()); | |
| 1375 } | |
| 1376 | |
| 1377 // If we're draining, signal completion now because either the drain was | |
| 1378 // finished above, or the drain can no longer proceed anyway. | |
| 1379 if (drain_type_ != DRAIN_TYPE_NONE) | |
| 1380 OnDrainCompleted(); | |
| 1381 } | |
| 1382 | |
| 1280 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { | 1383 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { |
| 1281 // Remember: this may be on any thread. | 1384 // Remember: this may be on any thread. |
| 1282 DCHECK(strategy_); | 1385 DCHECK(strategy_); |
| 1283 strategy_->OnFrameAvailable(); | 1386 strategy_->OnFrameAvailable(); |
| 1284 } | 1387 } |
| 1285 | 1388 |
| 1286 void AndroidVideoDecodeAccelerator::PostError( | 1389 void AndroidVideoDecodeAccelerator::PostError( |
| 1287 const ::tracked_objects::Location& from_here, | 1390 const ::tracked_objects::Location& from_here, |
| 1288 media::VideoDecodeAccelerator::Error error) { | 1391 media::VideoDecodeAccelerator::Error error) { |
| 1289 base::MessageLoop::current()->PostDelayedTask( | 1392 base::MessageLoop::current()->PostDelayedTask( |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1458 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { | 1561 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { |
| 1459 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: | 1562 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: |
| 1460 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1563 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| 1461 } | 1564 } |
| 1462 } | 1565 } |
| 1463 | 1566 |
| 1464 return capabilities; | 1567 return capabilities; |
| 1465 } | 1568 } |
| 1466 | 1569 |
| 1467 } // namespace media | 1570 } // namespace media |
| OLD | NEW |