| 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 |