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 |
11 #include "base/android/build_info.h" | 11 #include "base/android/build_info.h" |
12 #include "base/auto_reset.h" | 12 #include "base/auto_reset.h" |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
15 #include "base/callback_helpers.h" | 15 #include "base/callback_helpers.h" |
16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
17 #include "base/lazy_instance.h" | 17 #include "base/lazy_instance.h" |
18 #include "base/logging.h" | 18 #include "base/logging.h" |
19 #include "base/message_loop/message_loop.h" | 19 #include "base/message_loop/message_loop.h" |
20 #include "base/metrics/histogram.h" | 20 #include "base/metrics/histogram.h" |
| 21 #include "base/sys_info.h" |
21 #include "base/task_runner_util.h" | 22 #include "base/task_runner_util.h" |
22 #include "base/threading/thread_checker.h" | 23 #include "base/threading/thread_checker.h" |
23 #include "base/threading/thread_task_runner_handle.h" | 24 #include "base/threading/thread_task_runner_handle.h" |
24 #include "base/trace_event/trace_event.h" | 25 #include "base/trace_event/trace_event.h" |
25 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 26 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
26 #include "gpu/command_buffer/service/mailbox_manager.h" | 27 #include "gpu/command_buffer/service/mailbox_manager.h" |
27 #include "gpu/ipc/service/gpu_channel.h" | 28 #include "gpu/ipc/service/gpu_channel.h" |
28 #include "media/base/android/media_codec_bridge.h" | 29 #include "media/base/android/media_codec_bridge.h" |
29 #include "media/base/android/media_codec_util.h" | 30 #include "media/base/android/media_codec_util.h" |
30 #include "media/base/bind_to_current_loop.h" | 31 #include "media/base/bind_to_current_loop.h" |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 surface_waiter_map_.erase(iter); | 318 surface_waiter_map_.erase(iter); |
318 return; | 319 return; |
319 } | 320 } |
320 | 321 |
321 // Promote |waiter| to be the owner. | 322 // Promote |waiter| to be the owner. |
322 iter->second.owner = waiter; | 323 iter->second.owner = waiter; |
323 iter->second.waiter = nullptr; | 324 iter->second.waiter = nullptr; |
324 waiter->OnSurfaceAvailable(true); | 325 waiter->OnSurfaceAvailable(true); |
325 } | 326 } |
326 | 327 |
| 328 // On low end devices (< KitKat is always low-end due to buggy MediaCodec), |
| 329 // defer the surface creation until the codec is actually used if we know no |
| 330 // software fallback exists. |
| 331 bool ShouldDeferSurfaceCreation(int surface_id, VideoCodec codec) { |
| 332 return surface_id == AndroidVideoDecodeAccelerator::Config::kNoSurfaceID && |
| 333 codec == kCodecH264 && !thread_avda_instances_.empty() && |
| 334 (base::android::BuildInfo::GetInstance()->sdk_int() <= 18 || |
| 335 base::SysInfo::IsLowEndDevice()); |
| 336 } |
| 337 |
327 private: | 338 private: |
328 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; | 339 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; |
329 | 340 |
330 AVDAManager() | 341 AVDAManager() |
331 : construction_thread_("AVDAThread"), weak_this_factory_(this) {} | 342 : construction_thread_("AVDAThread"), weak_this_factory_(this) {} |
332 ~AVDAManager() { NOTREACHED(); } | 343 ~AVDAManager() { NOTREACHED(); } |
333 | 344 |
334 void RunTimer() { | 345 void RunTimer() { |
335 { | 346 { |
336 // Call out to all AVDA instances, some of which may attempt to remove | 347 // Call out to all AVDA instances, some of which may attempt to remove |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 state_(NO_ERROR), | 429 state_(NO_ERROR), |
419 picturebuffers_requested_(false), | 430 picturebuffers_requested_(false), |
420 drain_type_(DRAIN_TYPE_NONE), | 431 drain_type_(DRAIN_TYPE_NONE), |
421 media_drm_bridge_cdm_context_(nullptr), | 432 media_drm_bridge_cdm_context_(nullptr), |
422 cdm_registration_id_(0), | 433 cdm_registration_id_(0), |
423 pending_input_buf_index_(-1), | 434 pending_input_buf_index_(-1), |
424 error_sequence_token_(0), | 435 error_sequence_token_(0), |
425 defer_errors_(false), | 436 defer_errors_(false), |
426 deferred_initialization_pending_(false), | 437 deferred_initialization_pending_(false), |
427 codec_needs_reset_(false), | 438 codec_needs_reset_(false), |
| 439 defer_surface_creation_(false), |
428 weak_this_factory_(this) {} | 440 weak_this_factory_(this) {} |
429 | 441 |
430 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 442 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
431 DCHECK(thread_checker_.CalledOnValidThread()); | 443 DCHECK(thread_checker_.CalledOnValidThread()); |
432 g_avda_manager.Get().StopTimer(this); | 444 g_avda_manager.Get().StopTimer(this); |
433 g_avda_manager.Get().StopThread(this); | 445 g_avda_manager.Get().StopThread(this); |
434 | 446 |
435 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 447 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
436 if (!media_drm_bridge_cdm_context_) | 448 if (!media_drm_bridge_cdm_context_) |
437 return; | 449 return; |
(...skipping 26 matching lines...) Expand all Loading... |
464 } | 476 } |
465 | 477 |
466 DCHECK(client); | 478 DCHECK(client); |
467 client_ = client; | 479 client_ = client; |
468 config_ = config; | 480 config_ = config; |
469 codec_config_ = new CodecConfig(); | 481 codec_config_ = new CodecConfig(); |
470 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile); | 482 codec_config_->codec_ = VideoCodecProfileToVideoCodec(config.profile); |
471 codec_config_->initial_expected_coded_size_ = | 483 codec_config_->initial_expected_coded_size_ = |
472 config.initial_expected_coded_size; | 484 config.initial_expected_coded_size; |
473 | 485 |
474 // We signalled that we support deferred initialization, so see if the client | |
475 // does also. | |
476 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; | |
477 | |
478 if (config_.is_encrypted && !deferred_initialization_pending_) { | |
479 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; | |
480 return false; | |
481 } | |
482 | |
483 if (codec_config_->codec_ != kCodecVP8 && | 486 if (codec_config_->codec_ != kCodecVP8 && |
484 codec_config_->codec_ != kCodecVP9 && | 487 codec_config_->codec_ != kCodecVP9 && |
485 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 488 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
486 codec_config_->codec_ != kCodecHEVC && | 489 codec_config_->codec_ != kCodecHEVC && |
487 #endif | 490 #endif |
488 codec_config_->codec_ != kCodecH264) { | 491 codec_config_->codec_ != kCodecH264) { |
489 LOG(ERROR) << "Unsupported profile: " << config.profile; | 492 LOG(ERROR) << "Unsupported profile: " << config.profile; |
490 return false; | 493 return false; |
491 } | 494 } |
492 | 495 |
493 // Only use MediaCodec for VP8/9 if it's likely backed by hardware | 496 // Only use MediaCodec for VP8/9 if it's likely backed by hardware |
494 // or if the stream is encrypted. | 497 // or if the stream is encrypted. |
495 if (IsMediaCodecSoftwareDecodingForbidden() && | 498 if (IsMediaCodecSoftwareDecodingForbidden() && |
496 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_, | 499 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_, |
497 MEDIA_CODEC_DECODER)) { | 500 MEDIA_CODEC_DECODER)) { |
498 DVLOG(1) << "Initialization failed: " | 501 DVLOG(1) << "Initialization failed: " |
499 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9") | 502 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9") |
500 << " is not hardware accelerated"; | 503 << " is not hardware accelerated"; |
501 return false; | 504 return false; |
502 } | 505 } |
503 | 506 |
504 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 507 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
505 if (!gles_decoder) { | 508 if (!gles_decoder) { |
506 LOG(ERROR) << "Failed to get gles2 decoder instance."; | 509 LOG(ERROR) << "Failed to get gles2 decoder instance."; |
507 return false; | 510 return false; |
508 } | 511 } |
509 | 512 |
510 if (!make_context_current_cb_.Run()) { | 513 // If we're low on resources, we may decide to defer creation of the surface |
511 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 514 // until the codec is actually used. |
| 515 if (g_avda_manager.Get().ShouldDeferSurfaceCreation(config_.surface_id, |
| 516 codec_config_->codec_)) { |
| 517 DCHECK(!deferred_initialization_pending_); |
| 518 |
| 519 // We should never be here if a SurfaceView is required. |
| 520 DCHECK_EQ(config_.surface_id, Config::kNoSurfaceID); |
| 521 DCHECK(g_avda_manager.Get().AllocateSurface(config_.surface_id, this)); |
| 522 |
| 523 defer_surface_creation_ = true; |
| 524 NotifyInitializationComplete(true); |
| 525 return true; |
| 526 } |
| 527 |
| 528 // We signaled that we support deferred initialization, so see if the client |
| 529 // does also. |
| 530 deferred_initialization_pending_ = config.is_deferred_initialization_allowed; |
| 531 if (config_.is_encrypted && !deferred_initialization_pending_) { |
| 532 DLOG(ERROR) << "Deferred initialization must be used for encrypted streams"; |
512 return false; | 533 return false; |
513 } | 534 } |
514 | 535 |
515 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { | 536 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { |
516 // We have succesfully owned the surface, so finish initialization now. | 537 // We have successfully owned the surface, so finish initialization now. |
517 return InitializePictureBufferManager(); | 538 return InitializePictureBufferManager(); |
518 } | 539 } |
519 | 540 |
520 // We have to wait for some other AVDA instance to free up the surface. | 541 // We have to wait for some other AVDA instance to free up the surface. |
521 // OnSurfaceAvailable will be called when it's available. | 542 // OnSurfaceAvailable will be called when it's available. |
522 return true; | 543 return true; |
523 } | 544 } |
524 | 545 |
525 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { | 546 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
526 DCHECK(deferred_initialization_pending_); | 547 DCHECK(deferred_initialization_pending_); |
| 548 DCHECK(!defer_surface_creation_); |
527 | 549 |
528 if (!success || !InitializePictureBufferManager()) { | 550 if (!success || !InitializePictureBufferManager()) { |
529 NotifyInitializationComplete(false); | 551 NotifyInitializationComplete(false); |
530 deferred_initialization_pending_ = false; | 552 deferred_initialization_pending_ = false; |
531 } | 553 } |
532 } | 554 } |
533 | 555 |
534 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { | 556 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| 557 if (!make_context_current_cb_.Run()) { |
| 558 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 559 return false; |
| 560 } |
| 561 |
535 codec_config_->surface_ = | 562 codec_config_->surface_ = |
536 picture_buffer_manager_.Initialize(this, config_.surface_id); | 563 picture_buffer_manager_.Initialize(this, config_.surface_id); |
537 if (codec_config_->surface_.IsEmpty()) | 564 if (codec_config_->surface_.IsEmpty()) |
538 return false; | 565 return false; |
539 | 566 |
540 on_destroying_surface_cb_ = | 567 on_destroying_surface_cb_ = |
541 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, | 568 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, |
542 weak_this_factory_.GetWeakPtr()); | 569 weak_this_factory_.GetWeakPtr()); |
543 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( | 570 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( |
544 on_destroying_surface_cb_); | 571 on_destroying_surface_cb_); |
545 | 572 |
546 if (!g_avda_manager.Get().StartThread(this)) | 573 if (!g_avda_manager.Get().StartThread(this)) |
547 return false; | 574 return false; |
548 | 575 |
549 // If we are encrypted, then we aren't able to create the codec yet. | 576 // If we are encrypted, then we aren't able to create the codec yet. |
550 if (config_.is_encrypted) { | 577 if (config_.is_encrypted) { |
551 InitializeCdm(); | 578 InitializeCdm(); |
552 return true; | 579 return true; |
553 } | 580 } |
554 | 581 |
555 if (deferred_initialization_pending_) { | 582 if (deferred_initialization_pending_ || defer_surface_creation_) { |
| 583 defer_surface_creation_ = false; |
556 ConfigureMediaCodecAsynchronously(); | 584 ConfigureMediaCodecAsynchronously(); |
557 return true; | 585 return true; |
558 } | 586 } |
559 | 587 |
560 // If the client doesn't support deferred initialization (WebRTC), then we | 588 // If the client doesn't support deferred initialization (WebRTC), then we |
561 // should complete it now and return a meaningful result. Note that it would | 589 // should complete it now and return a meaningful result. Note that it would |
562 // be nice if we didn't have to worry about starting codec configuration at | 590 // be nice if we didn't have to worry about starting codec configuration at |
563 // all (::Initialize or the wrapper can do it), but then they have to remember | 591 // all (::Initialize or the wrapper can do it), but then they have to remember |
564 // not to start codec config if we have to wait for the cdm. It's somewhat | 592 // not to start codec config if we have to wait for the cdm. It's somewhat |
565 // clearer for us to handle both cases. | 593 // clearer for us to handle both cases. |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 } | 811 } |
784 | 812 |
785 DVLOG(3) << __FUNCTION__ | 813 DVLOG(3) << __FUNCTION__ |
786 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); | 814 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); |
787 | 815 |
788 // Don't request picture buffers if we already have some. This avoids | 816 // Don't request picture buffers if we already have some. This avoids |
789 // having to dismiss the existing buffers which may actively reference | 817 // having to dismiss the existing buffers which may actively reference |
790 // decoded images. Breaking their connection to the decoded image will | 818 // decoded images. Breaking their connection to the decoded image will |
791 // cause rendering of black frames. Instead, we let the existing | 819 // cause rendering of black frames. Instead, we let the existing |
792 // PictureBuffers live on and we simply update their size the next time | 820 // PictureBuffers live on and we simply update their size the next time |
793 // they're attachted to an image of the new resolution. See the | 821 // they're attached to an image of the new resolution. See the |
794 // size update in |SendDecodedFrameToClient| and https://crbug/587994. | 822 // size update in |SendDecodedFrameToClient| and https://crbug/587994. |
795 if (output_picture_buffers_.empty() && !picturebuffers_requested_) { | 823 if (output_picture_buffers_.empty() && !picturebuffers_requested_) { |
796 picturebuffers_requested_ = true; | 824 picturebuffers_requested_ = true; |
797 base::ThreadTaskRunnerHandle::Get()->PostTask( | 825 base::ThreadTaskRunnerHandle::Get()->PostTask( |
798 FROM_HERE, | 826 FROM_HERE, |
799 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, | 827 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, |
800 weak_this_factory_.GetWeakPtr())); | 828 weak_this_factory_.GetWeakPtr())); |
801 return false; | 829 return false; |
802 } | 830 } |
803 | 831 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
921 | 949 |
922 // Connect the PictureBuffer to the decoded frame. | 950 // Connect the PictureBuffer to the decoded frame. |
923 picture_buffer_manager_.UseCodecBufferForPictureBuffer(codec_buffer_index, | 951 picture_buffer_manager_.UseCodecBufferForPictureBuffer(codec_buffer_index, |
924 picture_buffer); | 952 picture_buffer); |
925 } | 953 } |
926 | 954 |
927 void AndroidVideoDecodeAccelerator::Decode( | 955 void AndroidVideoDecodeAccelerator::Decode( |
928 const BitstreamBuffer& bitstream_buffer) { | 956 const BitstreamBuffer& bitstream_buffer) { |
929 DCHECK(thread_checker_.CalledOnValidThread()); | 957 DCHECK(thread_checker_.CalledOnValidThread()); |
930 | 958 |
| 959 if (defer_surface_creation_ && !InitializePictureBufferManager()) { |
| 960 POST_ERROR(PLATFORM_FAILURE, |
| 961 "Failed deferred surface and MediaCodec initialization."); |
| 962 return; |
| 963 } |
| 964 |
931 // If we previously deferred a codec restart, take care of it now. This can | 965 // If we previously deferred a codec restart, take care of it now. This can |
932 // happen on older devices where configuration changes require a codec reset. | 966 // happen on older devices where configuration changes require a codec reset. |
933 if (codec_needs_reset_) { | 967 if (codec_needs_reset_) { |
934 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE); | 968 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE); |
935 ResetCodecState(); | 969 ResetCodecState(); |
936 } | 970 } |
937 | 971 |
938 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { | 972 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { |
939 DecodeBuffer(bitstream_buffer); | 973 DecodeBuffer(bitstream_buffer); |
940 return; | 974 return; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 } | 1054 } |
1021 | 1055 |
1022 picture_buffer_manager_.ReuseOnePictureBuffer(it->second); | 1056 picture_buffer_manager_.ReuseOnePictureBuffer(it->second); |
1023 DoIOTask(true); | 1057 DoIOTask(true); |
1024 } | 1058 } |
1025 | 1059 |
1026 void AndroidVideoDecodeAccelerator::Flush() { | 1060 void AndroidVideoDecodeAccelerator::Flush() { |
1027 DVLOG(1) << __FUNCTION__; | 1061 DVLOG(1) << __FUNCTION__; |
1028 DCHECK(thread_checker_.CalledOnValidThread()); | 1062 DCHECK(thread_checker_.CalledOnValidThread()); |
1029 | 1063 |
1030 if (state_ == SURFACE_DESTROYED) | 1064 if (state_ == SURFACE_DESTROYED || defer_surface_creation_) |
1031 NotifyFlushDone(); | 1065 NotifyFlushDone(); |
1032 else | 1066 else |
1033 StartCodecDrain(DRAIN_FOR_FLUSH); | 1067 StartCodecDrain(DRAIN_FOR_FLUSH); |
1034 } | 1068 } |
1035 | 1069 |
1036 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 1070 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
1037 DCHECK(thread_checker_.CalledOnValidThread()); | 1071 DCHECK(thread_checker_.CalledOnValidThread()); |
1038 | 1072 |
1039 // It's probably okay just to return here, since the codec will be configured | 1073 // It's probably okay just to return here, since the codec will be configured |
1040 // asynchronously. It's unclear that any state for the new request could | 1074 // asynchronously. It's unclear that any state for the new request could |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1251 // We might increment error_sequence_token here to cancel any delayed errors, | 1285 // We might increment error_sequence_token here to cancel any delayed errors, |
1252 // but right now it's unclear that it's safe to do so. If we are in an error | 1286 // but right now it's unclear that it's safe to do so. If we are in an error |
1253 // state because of a codec error, then it would be okay. Otherwise, it's | 1287 // state because of a codec error, then it would be okay. Otherwise, it's |
1254 // less obvious that we are exiting the error state. Since deferred errors | 1288 // less obvious that we are exiting the error state. Since deferred errors |
1255 // are only intended for fullscreen transitions right now, we take the more | 1289 // are only intended for fullscreen transitions right now, we take the more |
1256 // conservative approach and let the errors post. | 1290 // conservative approach and let the errors post. |
1257 // TODO(liberato): revisit this once we sort out the error state a bit more. | 1291 // TODO(liberato): revisit this once we sort out the error state a bit more. |
1258 | 1292 |
1259 // Flush the codec if possible, or create a new one if not. | 1293 // Flush the codec if possible, or create a new one if not. |
1260 if (!did_codec_error_happen && | 1294 if (!did_codec_error_happen && |
1261 !media::MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { | 1295 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
1262 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec."; | 1296 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec."; |
1263 media_codec_->Flush(); | 1297 media_codec_->Flush(); |
1264 // Since we just flushed all the output buffers, make sure that nothing is | 1298 // Since we just flushed all the output buffers, make sure that nothing is |
1265 // using them. | 1299 // using them. |
1266 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1300 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
1267 } else { | 1301 } else { |
1268 DVLOG(3) << __FUNCTION__ | 1302 DVLOG(3) << __FUNCTION__ |
1269 << " Deleting the MediaCodec and creating a new one."; | 1303 << " Deleting the MediaCodec and creating a new one."; |
1270 g_avda_manager.Get().StopTimer(this); | 1304 g_avda_manager.Get().StopTimer(this); |
1271 ConfigureMediaCodecAsynchronously(); | 1305 ConfigureMediaCodecAsynchronously(); |
1272 } | 1306 } |
1273 } | 1307 } |
1274 | 1308 |
1275 void AndroidVideoDecodeAccelerator::Reset() { | 1309 void AndroidVideoDecodeAccelerator::Reset() { |
1276 DVLOG(1) << __FUNCTION__; | 1310 DVLOG(1) << __FUNCTION__; |
1277 DCHECK(thread_checker_.CalledOnValidThread()); | 1311 DCHECK(thread_checker_.CalledOnValidThread()); |
1278 TRACE_EVENT0("media", "AVDA::Reset"); | 1312 TRACE_EVENT0("media", "AVDA::Reset"); |
1279 | 1313 |
| 1314 if (defer_surface_creation_) { |
| 1315 DCHECK(!media_codec_); |
| 1316 DCHECK(pending_bitstream_records_.empty()); |
| 1317 DCHECK_EQ(state_, NO_ERROR); |
| 1318 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1319 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| 1320 weak_this_factory_.GetWeakPtr())); |
| 1321 return; |
| 1322 } |
| 1323 |
1280 while (!pending_bitstream_records_.empty()) { | 1324 while (!pending_bitstream_records_.empty()) { |
1281 int32_t bitstream_buffer_id = | 1325 int32_t bitstream_buffer_id = |
1282 pending_bitstream_records_.front().buffer.id(); | 1326 pending_bitstream_records_.front().buffer.id(); |
1283 pending_bitstream_records_.pop(); | 1327 pending_bitstream_records_.pop(); |
1284 | 1328 |
1285 if (bitstream_buffer_id != -1) { | 1329 if (bitstream_buffer_id != -1) { |
1286 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1330 base::ThreadTaskRunnerHandle::Get()->PostTask( |
1287 FROM_HERE, | 1331 FROM_HERE, |
1288 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, | 1332 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, |
1289 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); | 1333 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1628 capabilities.flags = | 1672 capabilities.flags = |
1629 VideoDecodeAccelerator::Capabilities::SUPPORTS_DEFERRED_INITIALIZATION; | 1673 VideoDecodeAccelerator::Capabilities::SUPPORTS_DEFERRED_INITIALIZATION; |
1630 capabilities.flags |= | 1674 capabilities.flags |= |
1631 VideoDecodeAccelerator::Capabilities::NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; | 1675 VideoDecodeAccelerator::Capabilities::NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; |
1632 | 1676 |
1633 // If we're using threaded texture mailboxes the COPY_REQUIRED flag must be | 1677 // If we're using threaded texture mailboxes the COPY_REQUIRED flag must be |
1634 // set on the video frames (http://crbug.com/582170), and SurfaceView output | 1678 // set on the video frames (http://crbug.com/582170), and SurfaceView output |
1635 // is disabled (http://crbug.com/582170). | 1679 // is disabled (http://crbug.com/582170). |
1636 if (gpu_preferences.enable_threaded_texture_mailboxes) { | 1680 if (gpu_preferences.enable_threaded_texture_mailboxes) { |
1637 capabilities.flags |= | 1681 capabilities.flags |= |
1638 media::VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY; | 1682 VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY; |
1639 } else if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { | 1683 } else if (MediaCodecUtil::IsSurfaceViewOutputSupported()) { |
1640 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: | 1684 capabilities.flags |= |
1641 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1685 VideoDecodeAccelerator::Capabilities::SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
1642 } | 1686 } |
1643 | 1687 |
1644 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) | 1688 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) |
1645 for (const auto& supported_profile : kSupportedHevcProfiles) { | 1689 for (const auto& supported_profile : kSupportedHevcProfiles) { |
1646 SupportedProfile profile; | 1690 SupportedProfile profile; |
1647 profile.profile = supported_profile; | 1691 profile.profile = supported_profile; |
1648 profile.min_resolution.SetSize(0, 0); | 1692 profile.min_resolution.SetSize(0, 0); |
1649 profile.max_resolution.SetSize(3840, 2160); | 1693 profile.max_resolution.SetSize(3840, 2160); |
1650 profiles.push_back(profile); | 1694 profiles.push_back(profile); |
1651 } | 1695 } |
1652 #endif | 1696 #endif |
1653 | 1697 |
1654 return capabilities; | 1698 return capabilities; |
1655 } | 1699 } |
1656 | 1700 |
1657 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1701 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
1658 const { | 1702 const { |
1659 // Prevent MediaCodec from using its internal software decoders when we have | 1703 // Prevent MediaCodec from using its internal software decoders when we have |
1660 // more secure and up to date versions in the renderer process. | 1704 // more secure and up to date versions in the renderer process. |
1661 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || | 1705 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || |
1662 codec_config_->codec_ == kCodecVP9); | 1706 codec_config_->codec_ == kCodecVP9); |
1663 } | 1707 } |
1664 | 1708 |
1665 } // namespace media | 1709 } // namespace media |
OLD | NEW |