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 15 matching lines...) Expand all Loading... | |
| 26 #include "gpu/command_buffer/service/mailbox_manager.h" | 26 #include "gpu/command_buffer/service/mailbox_manager.h" |
| 27 #include "gpu/ipc/service/gpu_channel.h" | 27 #include "gpu/ipc/service/gpu_channel.h" |
| 28 #include "media/base/android/media_codec_bridge.h" | 28 #include "media/base/android/media_codec_bridge.h" |
| 29 #include "media/base/android/media_codec_util.h" | 29 #include "media/base/android/media_codec_util.h" |
| 30 #include "media/base/bind_to_current_loop.h" | 30 #include "media/base/bind_to_current_loop.h" |
| 31 #include "media/base/bitstream_buffer.h" | 31 #include "media/base/bitstream_buffer.h" |
| 32 #include "media/base/limits.h" | 32 #include "media/base/limits.h" |
| 33 #include "media/base/media.h" | 33 #include "media/base/media.h" |
| 34 #include "media/base/timestamp_constants.h" | 34 #include "media/base/timestamp_constants.h" |
| 35 #include "media/base/video_decoder_config.h" | 35 #include "media/base/video_decoder_config.h" |
| 36 #include "media/gpu/android_copying_backing_strategy.h" | 36 #include "media/gpu/avda_picture_buffer_manager.h" |
| 37 #include "media/gpu/android_deferred_rendering_backing_strategy.h" | |
| 38 #include "media/gpu/avda_return_on_failure.h" | |
| 39 #include "media/gpu/shared_memory_region.h" | 37 #include "media/gpu/shared_memory_region.h" |
| 40 #include "media/video/picture.h" | 38 #include "media/video/picture.h" |
| 41 #include "ui/gl/android/scoped_java_surface.h" | 39 #include "ui/gl/android/scoped_java_surface.h" |
| 42 #include "ui/gl/android/surface_texture.h" | 40 #include "ui/gl/android/surface_texture.h" |
| 43 #include "ui/gl/gl_bindings.h" | 41 #include "ui/gl/gl_bindings.h" |
| 44 | 42 |
| 45 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 43 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 46 #include "media/mojo/services/mojo_cdm_service.h" | 44 #include "media/mojo/services/mojo_cdm_service.h" |
| 47 #endif | 45 #endif |
| 48 | 46 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 CodecInitialized = false, | 117 CodecInitialized = false, |
| 120 MissingFormatChanged = true | 118 MissingFormatChanged = true |
| 121 }; | 119 }; |
| 122 | 120 |
| 123 inline void RecordFormatChangedMetric(FormatChangedValue value) { | 121 inline void RecordFormatChangedMetric(FormatChangedValue value) { |
| 124 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.MissingFormatChanged", !!value); | 122 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.MissingFormatChanged", !!value); |
| 125 } | 123 } |
| 126 | 124 |
| 127 } // namespace | 125 } // namespace |
| 128 | 126 |
| 129 // Handle OnFrameAvailable callbacks safely. Since they occur asynchronously, | |
| 130 // we take care that the AVDA that wants them still exists. A WeakPtr to | |
| 131 // the AVDA would be preferable, except that OnFrameAvailable callbacks can | |
| 132 // occur off the gpu main thread. We also can't guarantee when the | |
| 133 // SurfaceTexture will quit sending callbacks to coordinate with the | |
| 134 // destruction of the AVDA, so we have a separate object that the cb can own. | |
| 135 class AndroidVideoDecodeAccelerator::OnFrameAvailableHandler | |
| 136 : public base::RefCountedThreadSafe<OnFrameAvailableHandler> { | |
| 137 public: | |
| 138 // We do not retain ownership of |owner|. It must remain valid until | |
| 139 // after ClearOwner() is called. This will register with | |
| 140 // |surface_texture| to receive OnFrameAvailable callbacks. | |
| 141 OnFrameAvailableHandler( | |
| 142 AndroidVideoDecodeAccelerator* owner, | |
| 143 const scoped_refptr<gl::SurfaceTexture>& surface_texture) | |
| 144 : owner_(owner) { | |
| 145 // Note that the callback owns a strong ref to us. | |
| 146 surface_texture->SetFrameAvailableCallbackOnAnyThread( | |
| 147 base::Bind(&OnFrameAvailableHandler::OnFrameAvailable, | |
| 148 scoped_refptr<OnFrameAvailableHandler>(this))); | |
| 149 } | |
| 150 | |
| 151 // Forget about our owner, which is required before one deletes it. | |
| 152 // No further callbacks will happen once this completes. | |
| 153 void ClearOwner() { | |
| 154 base::AutoLock lock(lock_); | |
| 155 // No callback can happen until we release the lock. | |
| 156 owner_ = nullptr; | |
| 157 } | |
| 158 | |
| 159 // Call back into our owner if it hasn't been deleted. | |
| 160 void OnFrameAvailable() { | |
| 161 base::AutoLock auto_lock(lock_); | |
| 162 // |owner_| can't be deleted while we have the lock. | |
| 163 if (owner_) | |
| 164 owner_->OnFrameAvailable(); | |
| 165 } | |
| 166 | |
| 167 private: | |
| 168 friend class base::RefCountedThreadSafe<OnFrameAvailableHandler>; | |
| 169 virtual ~OnFrameAvailableHandler() {} | |
| 170 | |
| 171 // Protects changes to owner_. | |
| 172 base::Lock lock_; | |
| 173 | |
| 174 // AVDA that wants the OnFrameAvailable callback. | |
| 175 AndroidVideoDecodeAccelerator* owner_; | |
| 176 | |
| 177 DISALLOW_COPY_AND_ASSIGN(OnFrameAvailableHandler); | |
| 178 }; | |
| 179 | |
| 180 // AVDAManager manages shared resources for a number of AVDA instances. | 127 // AVDAManager manages shared resources for a number of AVDA instances. |
| 181 // Its responsibilities include: | 128 // Its responsibilities include: |
| 182 // - Starting and stopping a shared "construction" thread for instantiating and | 129 // - Starting and stopping a shared "construction" thread for instantiating and |
| 183 // releasing MediaCodecs. | 130 // releasing MediaCodecs. |
| 184 // - Detecting when a task has hung on the construction thread so AVDAs can | 131 // - Detecting when a task has hung on the construction thread so AVDAs can |
| 185 // stop using it. | 132 // stop using it. |
| 186 // - Running a RepeatingTimer so that AVDAs can get a regular callback to | 133 // - Running a RepeatingTimer so that AVDAs can get a regular callback to |
| 187 // DoIOTask(). | 134 // DoIOTask(). |
| 188 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when | 135 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when |
| 189 // surfaces are released. | 136 // surfaces are released. |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 539 // or if the stream is encrypted. | 486 // or if the stream is encrypted. |
| 540 if (IsMediaCodecSoftwareDecodingForbidden() && | 487 if (IsMediaCodecSoftwareDecodingForbidden() && |
| 541 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_, | 488 VideoCodecBridge::IsKnownUnaccelerated(codec_config_->codec_, |
| 542 MEDIA_CODEC_DECODER)) { | 489 MEDIA_CODEC_DECODER)) { |
| 543 DVLOG(1) << "Initialization failed: " | 490 DVLOG(1) << "Initialization failed: " |
| 544 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9") | 491 << (codec_config_->codec_ == kCodecVP8 ? "vp8" : "vp9") |
| 545 << " is not hardware accelerated"; | 492 << " is not hardware accelerated"; |
| 546 return false; | 493 return false; |
| 547 } | 494 } |
| 548 | 495 |
| 549 auto gles_decoder = get_gles2_decoder_cb_.Run(); | 496 auto gles_decoder = get_gles2_decoder_cb_.Run(); |
|
Pawel Osciak
2016/09/01 01:04:29
I think gles_decoder is not needed anymore? Could
watk
2016/09/01 17:03:33
I would love to, but we still use it. We pass it t
Pawel Osciak
2016/09/02 06:03:03
I see, thanks!
| |
| 550 if (!gles_decoder) { | 497 if (!gles_decoder) { |
| 551 LOG(ERROR) << "Failed to get gles2 decoder instance."; | 498 LOG(ERROR) << "Failed to get gles2 decoder instance."; |
| 552 return false; | 499 return false; |
| 553 } | 500 } |
| 554 | 501 |
| 555 const gpu::GpuPreferences& gpu_preferences = | |
| 556 gles_decoder->GetContextGroup()->gpu_preferences(); | |
| 557 | |
| 558 if (UseDeferredRenderingStrategy(gpu_preferences)) { | |
| 559 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; | |
| 560 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this)); | |
| 561 } else { | |
| 562 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; | |
| 563 strategy_.reset(new AndroidCopyingBackingStrategy(this)); | |
| 564 } | |
| 565 | |
| 566 if (!make_context_current_cb_.Run()) { | 502 if (!make_context_current_cb_.Run()) { |
| 567 LOG(ERROR) << "Failed to make this decoder's GL context current."; | 503 LOG(ERROR) << "Failed to make this decoder's GL context current."; |
| 568 return false; | 504 return false; |
| 569 } | 505 } |
| 570 | 506 |
| 571 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { | 507 if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { |
| 572 // We have succesfully owned the surface, so finish initialization now. | 508 // We have succesfully owned the surface, so finish initialization now. |
| 573 return InitializeStrategy(); | 509 return InitializePictureBufferManager(); |
| 574 } | 510 } |
| 575 | 511 |
| 576 // We have to wait for some other AVDA instance to free up the surface. | 512 // We have to wait for some other AVDA instance to free up the surface. |
| 577 // OnSurfaceAvailable will be called when it's available. | 513 // OnSurfaceAvailable will be called when it's available. |
| 578 return true; | 514 return true; |
| 579 } | 515 } |
| 580 | 516 |
| 581 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { | 517 void AndroidVideoDecodeAccelerator::OnSurfaceAvailable(bool success) { |
| 582 DCHECK(deferred_initialization_pending_); | 518 DCHECK(deferred_initialization_pending_); |
| 583 | 519 |
| 584 if (!success || !InitializeStrategy()) { | 520 if (!success || !InitializePictureBufferManager()) { |
| 585 NotifyInitializationComplete(false); | 521 NotifyInitializationComplete(false); |
| 586 deferred_initialization_pending_ = false; | 522 deferred_initialization_pending_ = false; |
| 587 } | 523 } |
| 588 } | 524 } |
| 589 | 525 |
| 590 bool AndroidVideoDecodeAccelerator::InitializeStrategy() { | 526 bool AndroidVideoDecodeAccelerator::InitializePictureBufferManager() { |
| 591 codec_config_->surface_ = strategy_->Initialize(config_.surface_id); | 527 codec_config_->surface_ = |
| 592 if (codec_config_->surface_.IsEmpty()) { | 528 picture_buffer_manager_.Initialize(this, config_.surface_id); |
| 593 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " | 529 if (codec_config_->surface_.IsEmpty()) |
| 594 "Java surface is empty."; | |
| 595 return false; | 530 return false; |
| 596 } | |
| 597 | 531 |
| 598 on_destroying_surface_cb_ = | 532 on_destroying_surface_cb_ = |
| 599 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, | 533 base::Bind(&AndroidVideoDecodeAccelerator::OnDestroyingSurface, |
| 600 weak_this_factory_.GetWeakPtr()); | 534 weak_this_factory_.GetWeakPtr()); |
| 601 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( | 535 AVDASurfaceTracker::GetInstance()->RegisterOnDestroyingSurfaceCallback( |
| 602 on_destroying_surface_cb_); | 536 on_destroying_surface_cb_); |
| 603 | 537 |
| 604 // TODO(watk,liberato): move this into the strategy. | |
| 605 scoped_refptr<gl::SurfaceTexture> surface_texture = | |
| 606 strategy_->GetSurfaceTexture(); | |
| 607 if (surface_texture) { | |
| 608 on_frame_available_handler_ = | |
| 609 new OnFrameAvailableHandler(this, surface_texture); | |
| 610 } | |
| 611 | |
| 612 if (!g_avda_manager.Get().StartThread(this)) | 538 if (!g_avda_manager.Get().StartThread(this)) |
| 613 return false; | 539 return false; |
| 614 | 540 |
| 615 // If we are encrypted, then we aren't able to create the codec yet. | 541 // If we are encrypted, then we aren't able to create the codec yet. |
| 616 if (config_.is_encrypted) { | 542 if (config_.is_encrypted) { |
| 617 InitializeCdm(); | 543 InitializeCdm(); |
| 618 return true; | 544 return true; |
| 619 } | 545 } |
| 620 | 546 |
| 621 if (deferred_initialization_pending_) { | 547 if (deferred_initialization_pending_) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 633 } | 559 } |
| 634 | 560 |
| 635 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { | 561 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { |
| 636 DCHECK(thread_checker_.CalledOnValidThread()); | 562 DCHECK(thread_checker_.CalledOnValidThread()); |
| 637 TRACE_EVENT0("media", "AVDA::DoIOTask"); | 563 TRACE_EVENT0("media", "AVDA::DoIOTask"); |
| 638 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || | 564 if (state_ == ERROR || state_ == WAITING_FOR_CODEC || |
| 639 state_ == SURFACE_DESTROYED) { | 565 state_ == SURFACE_DESTROYED) { |
| 640 return; | 566 return; |
| 641 } | 567 } |
| 642 | 568 |
| 643 strategy_->MaybeRenderEarly(); | 569 picture_buffer_manager_.MaybeRenderEarly(); |
| 644 bool did_work = false, did_input = false, did_output = false; | 570 bool did_work = false, did_input = false, did_output = false; |
| 645 do { | 571 do { |
| 646 did_input = QueueInput(); | 572 did_input = QueueInput(); |
| 647 did_output = DequeueOutput(); | 573 did_output = DequeueOutput(); |
| 648 if (did_input || did_output) | 574 if (did_input || did_output) |
| 649 did_work = true; | 575 did_work = true; |
| 650 } while (did_input || did_output); | 576 } while (did_input || did_output); |
| 651 | 577 |
| 652 ManageTimer(did_work || start_timer); | 578 ManageTimer(did_work || start_timer); |
| 653 } | 579 } |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 946 | 872 |
| 947 if (!make_context_current_cb_.Run()) { | 873 if (!make_context_current_cb_.Run()) { |
| 948 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); | 874 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); |
| 949 return; | 875 return; |
| 950 } | 876 } |
| 951 | 877 |
| 952 int32_t picture_buffer_id = free_picture_ids_.front(); | 878 int32_t picture_buffer_id = free_picture_ids_.front(); |
| 953 free_picture_ids_.pop(); | 879 free_picture_ids_.pop(); |
| 954 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); | 880 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
| 955 | 881 |
| 956 const auto& i = output_picture_buffers_.find(picture_buffer_id); | 882 const auto it = output_picture_buffers_.find(picture_buffer_id); |
| 957 if (i == output_picture_buffers_.end()) { | 883 if (it == output_picture_buffers_.end()) { |
| 958 POST_ERROR(PLATFORM_FAILURE, | 884 POST_ERROR(PLATFORM_FAILURE, |
| 959 "Can't find PictureBuffer id: " << picture_buffer_id); | 885 "Can't find PictureBuffer id: " << picture_buffer_id); |
| 960 return; | 886 return; |
| 961 } | 887 } |
| 962 | 888 |
| 963 bool size_changed = false; | 889 PictureBuffer& picture_buffer = it->second; |
| 964 if (i->second.size() != size_) { | 890 const bool size_changed = picture_buffer.size() != size_; |
| 965 // Size may have changed due to resolution change since the last time this | 891 if (size_changed) |
| 966 // PictureBuffer was used. | 892 picture_buffer.set_size(size_); |
| 967 strategy_->UpdatePictureBufferSize(&i->second, size_); | |
| 968 size_changed = true; | |
| 969 } | |
| 970 | 893 |
| 971 const bool allow_overlay = strategy_->ArePicturesOverlayable(); | 894 const bool allow_overlay = picture_buffer_manager_.ArePicturesOverlayable(); |
| 972 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.FrameSentAsOverlay", allow_overlay); | 895 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.FrameSentAsOverlay", allow_overlay); |
| 973 Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_), | 896 Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_), |
| 974 allow_overlay); | 897 allow_overlay); |
| 975 picture.set_size_changed(size_changed); | 898 picture.set_size_changed(size_changed); |
| 976 | 899 |
| 977 // Notify picture ready before calling UseCodecBufferForPictureBuffer() since | 900 // Notify picture ready before calling UseCodecBufferForPictureBuffer() since |
| 978 // that process may be slow and shouldn't delay delivery of the frame to the | 901 // that process may be slow and shouldn't delay delivery of the frame to the |
| 979 // renderer. The picture is only used on the same thread as this method is | 902 // renderer. The picture is only used on the same thread as this method is |
| 980 // called, so it is safe to do this. | 903 // called, so it is safe to do this. |
| 981 NotifyPictureReady(picture); | 904 NotifyPictureReady(picture); |
| 982 | 905 |
| 983 // Connect the PictureBuffer to the decoded frame, via whatever mechanism the | 906 // Connect the PictureBuffer to the decoded frame. |
| 984 // strategy likes. | 907 picture_buffer_manager_.UseCodecBufferForPictureBuffer(codec_buffer_index, |
| 985 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); | 908 picture_buffer); |
| 986 } | 909 } |
| 987 | 910 |
| 988 void AndroidVideoDecodeAccelerator::Decode( | 911 void AndroidVideoDecodeAccelerator::Decode( |
| 989 const BitstreamBuffer& bitstream_buffer) { | 912 const BitstreamBuffer& bitstream_buffer) { |
| 990 DCHECK(thread_checker_.CalledOnValidThread()); | 913 DCHECK(thread_checker_.CalledOnValidThread()); |
| 991 | 914 |
| 992 // If we previously deferred a codec restart, take care of it now. This can | 915 // If we previously deferred a codec restart, take care of it now. This can |
| 993 // happen on older devices where configuration changes require a codec reset. | 916 // happen on older devices where configuration changes require a codec reset. |
| 994 if (codec_needs_reset_) { | 917 if (codec_needs_reset_) { |
| 995 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE); | 918 DCHECK_EQ(drain_type_, DRAIN_TYPE_NONE); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1019 const BitstreamBuffer& bitstream_buffer) { | 942 const BitstreamBuffer& bitstream_buffer) { |
| 1020 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer)); | 943 pending_bitstream_records_.push(BitstreamRecord(bitstream_buffer)); |
| 1021 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", | 944 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", |
| 1022 pending_bitstream_records_.size()); | 945 pending_bitstream_records_.size()); |
| 1023 | 946 |
| 1024 DoIOTask(true); | 947 DoIOTask(true); |
| 1025 } | 948 } |
| 1026 | 949 |
| 1027 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { | 950 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { |
| 1028 if (client_) { | 951 if (client_) { |
| 1029 client_->ProvidePictureBuffers(kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1, | 952 client_->ProvidePictureBuffers( |
| 1030 strategy_->GetPictureBufferSize(), | 953 kNumPictureBuffers, PIXEL_FORMAT_UNKNOWN, 1, |
| 1031 strategy_->GetTextureTarget()); | 954 picture_buffer_manager_.GetPictureBufferSize(), |
| 955 picture_buffer_manager_.GetTextureTarget()); | |
| 1032 } | 956 } |
| 1033 } | 957 } |
| 1034 | 958 |
| 1035 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( | 959 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( |
| 1036 const std::vector<PictureBuffer>& buffers) { | 960 const std::vector<PictureBuffer>& buffers) { |
| 1037 DCHECK(thread_checker_.CalledOnValidThread()); | 961 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1038 DCHECK(output_picture_buffers_.empty()); | 962 DCHECK(output_picture_buffers_.empty()); |
| 1039 DCHECK(free_picture_ids_.empty()); | 963 DCHECK(free_picture_ids_.empty()); |
| 1040 | 964 |
| 1041 if (buffers.size() < kNumPictureBuffers) { | 965 if (buffers.size() < kNumPictureBuffers) { |
| 1042 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); | 966 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); |
| 1043 return; | 967 return; |
| 1044 } | 968 } |
| 1045 | 969 |
| 1046 const bool have_context = make_context_current_cb_.Run(); | 970 const bool have_context = make_context_current_cb_.Run(); |
| 1047 LOG_IF(WARNING, !have_context) | 971 LOG_IF(WARNING, !have_context) |
| 1048 << "Failed to make GL context current for Assign, continuing."; | 972 << "Failed to make GL context current for Assign, continuing."; |
| 1049 | 973 |
| 1050 for (size_t i = 0; i < buffers.size(); ++i) { | 974 for (size_t i = 0; i < buffers.size(); ++i) { |
| 1051 if (buffers[i].size() != strategy_->GetPictureBufferSize()) { | 975 if (buffers[i].size() != picture_buffer_manager_.GetPictureBufferSize()) { |
| 1052 POST_ERROR(INVALID_ARGUMENT, | 976 POST_ERROR(INVALID_ARGUMENT, |
| 1053 "Invalid picture buffer size assigned. Wanted " | 977 "Invalid picture buffer size assigned. Wanted " |
| 1054 << size_.ToString() << ", but got " | 978 << size_.ToString() << ", but got " |
| 1055 << buffers[i].size().ToString()); | 979 << buffers[i].size().ToString()); |
| 1056 return; | 980 return; |
| 1057 } | 981 } |
| 1058 int32_t id = buffers[i].id(); | 982 int32_t id = buffers[i].id(); |
| 1059 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); | 983 output_picture_buffers_.insert(std::make_pair(id, buffers[i])); |
| 1060 free_picture_ids_.push(id); | 984 free_picture_ids_.push(id); |
| 1061 | 985 |
| 1062 strategy_->AssignOnePictureBuffer(buffers[i], have_context); | 986 picture_buffer_manager_.AssignOnePictureBuffer(buffers[i], have_context); |
| 1063 } | 987 } |
| 1064 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); | 988 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
| 1065 DoIOTask(true); | 989 DoIOTask(true); |
| 1066 } | 990 } |
| 1067 | 991 |
| 1068 void AndroidVideoDecodeAccelerator::ReusePictureBuffer( | 992 void AndroidVideoDecodeAccelerator::ReusePictureBuffer( |
| 1069 int32_t picture_buffer_id) { | 993 int32_t picture_buffer_id) { |
| 1070 DCHECK(thread_checker_.CalledOnValidThread()); | 994 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1071 | 995 |
| 1072 free_picture_ids_.push(picture_buffer_id); | 996 free_picture_ids_.push(picture_buffer_id); |
| 1073 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); | 997 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); |
| 1074 | 998 |
| 1075 OutputBufferMap::const_iterator i = | 999 auto it = output_picture_buffers_.find(picture_buffer_id); |
| 1076 output_picture_buffers_.find(picture_buffer_id); | 1000 if (it == output_picture_buffers_.end()) { |
| 1077 if (i == output_picture_buffers_.end()) { | |
| 1078 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " | 1001 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " |
| 1079 << picture_buffer_id); | 1002 << picture_buffer_id); |
| 1080 return; | 1003 return; |
| 1081 } | 1004 } |
| 1082 | 1005 |
| 1083 strategy_->ReuseOnePictureBuffer(i->second); | 1006 picture_buffer_manager_.ReuseOnePictureBuffer(it->second); |
| 1084 DoIOTask(true); | 1007 DoIOTask(true); |
| 1085 } | 1008 } |
| 1086 | 1009 |
| 1087 void AndroidVideoDecodeAccelerator::Flush() { | 1010 void AndroidVideoDecodeAccelerator::Flush() { |
| 1088 DVLOG(1) << __FUNCTION__; | 1011 DVLOG(1) << __FUNCTION__; |
| 1089 DCHECK(thread_checker_.CalledOnValidThread()); | 1012 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1090 | 1013 |
| 1091 if (state_ == SURFACE_DESTROYED) | 1014 if (state_ == SURFACE_DESTROYED) |
| 1092 NotifyFlushDone(); | 1015 NotifyFlushDone(); |
| 1093 else | 1016 else |
| 1094 StartCodecDrain(DRAIN_FOR_FLUSH); | 1017 StartCodecDrain(DRAIN_FOR_FLUSH); |
| 1095 } | 1018 } |
| 1096 | 1019 |
| 1097 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { | 1020 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { |
| 1098 DCHECK(thread_checker_.CalledOnValidThread()); | 1021 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1099 | 1022 |
| 1100 // It's probably okay just to return here, since the codec will be configured | 1023 // It's probably okay just to return here, since the codec will be configured |
| 1101 // asynchronously. It's unclear that any state for the new request could | 1024 // asynchronously. It's unclear that any state for the new request could |
| 1102 // be different, unless somebody modifies |codec_config_| while we're already | 1025 // be different, unless somebody modifies |codec_config_| while we're already |
| 1103 // waiting for a codec. One shouldn't do that for thread safety. | 1026 // waiting for a codec. One shouldn't do that for thread safety. |
| 1104 DCHECK_NE(state_, WAITING_FOR_CODEC); | 1027 DCHECK_NE(state_, WAITING_FOR_CODEC); |
| 1105 | 1028 |
| 1106 state_ = WAITING_FOR_CODEC; | 1029 state_ = WAITING_FOR_CODEC; |
| 1107 | 1030 |
| 1108 // Tell the strategy that we're changing codecs. The codec itself could be | 1031 // Tell the picture buffer manager that we're changing codecs. The codec |
| 1109 // used normally, since we don't replace it until we're back on the main | 1032 // itself could be used normally, since we don't replace it until we're back |
| 1110 // thread. However, if we're using an output surface, then the incoming codec | 1033 // on the main thread. However, if we're using an output surface, then the |
| 1111 // might access that surface while the main thread is drawing. Telling the | 1034 // incoming codec might access that surface while the main thread is drawing. |
| 1112 // strategy to forget the codec avoids this. | 1035 // Telling the manager to forget the codec avoids this. |
| 1113 if (media_codec_) { | 1036 if (media_codec_) { |
| 1114 ReleaseMediaCodec(); | 1037 ReleaseMediaCodec(); |
| 1115 strategy_->CodecChanged(nullptr); | 1038 picture_buffer_manager_.CodecChanged(nullptr); |
| 1116 } | 1039 } |
| 1117 | 1040 |
| 1118 // Choose whether to autodetect the codec type. Note that we do this after | 1041 // Choose whether to autodetect the codec type. Note that we do this after |
| 1119 // releasing any outgoing codec, so that |codec_config_| still matches the | 1042 // releasing any outgoing codec, so that |codec_config_| still matches the |
| 1120 // outgoing codec for ReleaseMediaCodec(). | 1043 // outgoing codec for ReleaseMediaCodec(). |
| 1121 codec_config_->allow_autodetection_ = | 1044 codec_config_->allow_autodetection_ = |
| 1122 !g_avda_manager.Get().IsConstructionThreadLikelyHung(); | 1045 !g_avda_manager.Get().IsConstructionThreadLikelyHung(); |
| 1123 | 1046 |
| 1124 // If autodetection is disallowed, fall back to Chrome's software decoders | 1047 // If autodetection is disallowed, fall back to Chrome's software decoders |
| 1125 // instead of using the software decoders provided by MediaCodec. | 1048 // instead of using the software decoders provided by MediaCodec. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1198 deferred_initialization_pending_ = false; | 1121 deferred_initialization_pending_ = false; |
| 1199 } | 1122 } |
| 1200 | 1123 |
| 1201 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, | 1124 // If |state_| changed to SURFACE_DESTROYED while we were configuring a codec, |
| 1202 // then the codec is already invalid so we return early and drop it. | 1125 // then the codec is already invalid so we return early and drop it. |
| 1203 if (state_ == SURFACE_DESTROYED) | 1126 if (state_ == SURFACE_DESTROYED) |
| 1204 return; | 1127 return; |
| 1205 | 1128 |
| 1206 DCHECK(!media_codec_); | 1129 DCHECK(!media_codec_); |
| 1207 media_codec_ = std::move(media_codec); | 1130 media_codec_ = std::move(media_codec); |
| 1208 strategy_->CodecChanged(media_codec_.get()); | 1131 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
| 1209 if (!media_codec_) { | 1132 if (!media_codec_) { |
| 1210 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); | 1133 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); |
| 1211 return; | 1134 return; |
| 1212 } | 1135 } |
| 1213 | 1136 |
| 1214 state_ = NO_ERROR; | 1137 state_ = NO_ERROR; |
| 1215 | 1138 |
| 1216 ManageTimer(true); | 1139 ManageTimer(true); |
| 1217 } | 1140 } |
| 1218 | 1141 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1317 // conservative approach and let the errors post. | 1240 // conservative approach and let the errors post. |
| 1318 // TODO(liberato): revisit this once we sort out the error state a bit more. | 1241 // TODO(liberato): revisit this once we sort out the error state a bit more. |
| 1319 | 1242 |
| 1320 // Flush the codec if possible, or create a new one if not. | 1243 // Flush the codec if possible, or create a new one if not. |
| 1321 if (!did_codec_error_happen && | 1244 if (!did_codec_error_happen && |
| 1322 !media::MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { | 1245 !media::MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
| 1323 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec."; | 1246 DVLOG(3) << __FUNCTION__ << " Flushing MediaCodec."; |
| 1324 media_codec_->Flush(); | 1247 media_codec_->Flush(); |
| 1325 // Since we just flushed all the output buffers, make sure that nothing is | 1248 // Since we just flushed all the output buffers, make sure that nothing is |
| 1326 // using them. | 1249 // using them. |
| 1327 strategy_->CodecChanged(media_codec_.get()); | 1250 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
| 1328 } else { | 1251 } else { |
| 1329 DVLOG(3) << __FUNCTION__ | 1252 DVLOG(3) << __FUNCTION__ |
| 1330 << " Deleting the MediaCodec and creating a new one."; | 1253 << " Deleting the MediaCodec and creating a new one."; |
| 1331 g_avda_manager.Get().StopTimer(this); | 1254 g_avda_manager.Get().StopTimer(this); |
| 1332 ConfigureMediaCodecAsynchronously(); | 1255 ConfigureMediaCodecAsynchronously(); |
| 1333 } | 1256 } |
| 1334 } | 1257 } |
| 1335 | 1258 |
| 1336 void AndroidVideoDecodeAccelerator::Reset() { | 1259 void AndroidVideoDecodeAccelerator::Reset() { |
| 1337 DVLOG(1) << __FUNCTION__; | 1260 DVLOG(1) << __FUNCTION__; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1349 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, | 1272 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, |
| 1350 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); | 1273 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); |
| 1351 } | 1274 } |
| 1352 } | 1275 } |
| 1353 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); | 1276 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); |
| 1354 bitstreams_notified_in_advance_.clear(); | 1277 bitstreams_notified_in_advance_.clear(); |
| 1355 | 1278 |
| 1356 // Any error that is waiting to post can be ignored. | 1279 // Any error that is waiting to post can be ignored. |
| 1357 error_sequence_token_++; | 1280 error_sequence_token_++; |
| 1358 | 1281 |
| 1359 DCHECK(strategy_); | 1282 picture_buffer_manager_.ReleaseCodecBuffers(output_picture_buffers_); |
| 1360 strategy_->ReleaseCodecBuffers(output_picture_buffers_); | |
| 1361 | 1283 |
| 1362 // Some VP8 files require complete MediaCodec drain before we can call | 1284 // Some VP8 files require complete MediaCodec drain before we can call |
| 1363 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. | 1285 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. |
| 1364 if (media_codec_ && codec_config_->codec_ == kCodecVP8 && | 1286 if (media_codec_ && codec_config_->codec_ == kCodecVP8 && |
| 1365 !bitstream_buffers_in_decoder_.empty()) { | 1287 !bitstream_buffers_in_decoder_.empty()) { |
| 1366 // Postpone ResetCodecState() after the drain. | 1288 // Postpone ResetCodecState() after the drain. |
| 1367 StartCodecDrain(DRAIN_FOR_RESET); | 1289 StartCodecDrain(DRAIN_FOR_RESET); |
| 1368 } else { | 1290 } else { |
| 1369 ResetCodecState(); | 1291 ResetCodecState(); |
| 1370 base::ThreadTaskRunnerHandle::Get()->PostTask( | 1292 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 1371 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, | 1293 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, |
| 1372 weak_this_factory_.GetWeakPtr())); | 1294 weak_this_factory_.GetWeakPtr())); |
| 1373 } | 1295 } |
| 1374 } | 1296 } |
| 1375 | 1297 |
| 1376 void AndroidVideoDecodeAccelerator::Destroy() { | 1298 void AndroidVideoDecodeAccelerator::Destroy() { |
| 1377 DVLOG(1) << __FUNCTION__; | 1299 DVLOG(1) << __FUNCTION__; |
| 1378 DCHECK(thread_checker_.CalledOnValidThread()); | 1300 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1379 | 1301 |
| 1380 bool have_context = make_context_current_cb_.Run(); | 1302 picture_buffer_manager_.Destroy(output_picture_buffers_); |
| 1381 if (!have_context) | |
| 1382 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; | |
| 1383 | |
| 1384 if (strategy_) | |
| 1385 strategy_->BeginCleanup(have_context, output_picture_buffers_); | |
| 1386 | |
| 1387 // If we have an OnFrameAvailable handler, tell it that we're going away. | |
| 1388 if (on_frame_available_handler_) { | |
| 1389 on_frame_available_handler_->ClearOwner(); | |
| 1390 on_frame_available_handler_ = nullptr; | |
| 1391 } | |
| 1392 | 1303 |
| 1393 client_ = nullptr; | 1304 client_ = nullptr; |
| 1394 | 1305 |
| 1395 // Some VP8 files require complete MediaCodec drain before we can call | 1306 // Some VP8 files require a complete MediaCodec drain before we can call |
| 1396 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963. | 1307 // MediaCodec.flush() or MediaCodec.release(). http://crbug.com/598963. In |
| 1308 // that case, postpone ActualDestroy() until after the drain. | |
| 1397 if (media_codec_ && codec_config_->codec_ == kCodecVP8) { | 1309 if (media_codec_ && codec_config_->codec_ == kCodecVP8) { |
| 1398 // Clear pending_bitstream_records_. | 1310 // Clear |pending_bitstream_records_|. |
| 1399 while (!pending_bitstream_records_.empty()) | 1311 while (!pending_bitstream_records_.empty()) |
| 1400 pending_bitstream_records_.pop(); | 1312 pending_bitstream_records_.pop(); |
| 1401 | 1313 |
| 1402 // Postpone ActualDestroy after the drain. | |
| 1403 StartCodecDrain(DRAIN_FOR_DESTROY); | 1314 StartCodecDrain(DRAIN_FOR_DESTROY); |
| 1404 } else { | 1315 } else { |
| 1405 ActualDestroy(); | 1316 ActualDestroy(); |
| 1406 } | 1317 } |
| 1407 } | 1318 } |
| 1408 | 1319 |
| 1409 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1320 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
| 1410 DVLOG(1) << __FUNCTION__; | 1321 DVLOG(1) << __FUNCTION__; |
| 1411 DCHECK(thread_checker_.CalledOnValidThread()); | 1322 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1412 | 1323 |
| 1413 if (!on_destroying_surface_cb_.is_null()) { | 1324 if (!on_destroying_surface_cb_.is_null()) { |
| 1414 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( | 1325 AVDASurfaceTracker::GetInstance()->UnregisterOnDestroyingSurfaceCallback( |
| 1415 on_destroying_surface_cb_); | 1326 on_destroying_surface_cb_); |
| 1416 } | 1327 } |
| 1417 | 1328 |
| 1418 if (strategy_) | |
| 1419 strategy_->EndCleanup(); | |
| 1420 | |
| 1421 // We no longer care about |surface_id|, in case we did before. It's okay | 1329 // We no longer care about |surface_id|, in case we did before. It's okay |
| 1422 // if we have no surface and/or weren't the owner or a waiter. | 1330 // if we have no surface and/or weren't the owner or a waiter. |
| 1423 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); | 1331 g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); |
| 1424 | 1332 |
| 1425 // Note that async codec construction might still be in progress. In that | 1333 // Note that async codec construction might still be in progress. In that |
| 1426 // case, the codec will be deleted when it completes once we invalidate all | 1334 // case, the codec will be deleted when it completes once we invalidate all |
| 1427 // our weak refs. | 1335 // our weak refs. |
| 1428 weak_this_factory_.InvalidateWeakPtrs(); | 1336 weak_this_factory_.InvalidateWeakPtrs(); |
| 1429 if (media_codec_) { | 1337 if (media_codec_) { |
| 1430 g_avda_manager.Get().StopTimer(this); | 1338 g_avda_manager.Get().StopTimer(this); |
| 1431 ReleaseMediaCodec(); | 1339 ReleaseMediaCodec(); |
| 1432 } | 1340 } |
| 1341 | |
| 1433 delete this; | 1342 delete this; |
| 1434 } | 1343 } |
| 1435 | 1344 |
| 1436 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( | 1345 bool AndroidVideoDecodeAccelerator::TryToSetupDecodeOnSeparateThread( |
| 1437 const base::WeakPtr<Client>& decode_client, | 1346 const base::WeakPtr<Client>& decode_client, |
| 1438 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { | 1347 const scoped_refptr<base::SingleThreadTaskRunner>& decode_task_runner) { |
| 1439 return false; | 1348 return false; |
| 1440 } | 1349 } |
| 1441 | 1350 |
| 1442 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { | 1351 const gfx::Size& AndroidVideoDecodeAccelerator::GetSize() const { |
| 1443 return size_; | 1352 return size_; |
| 1444 } | 1353 } |
| 1445 | 1354 |
| 1446 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() | |
| 1447 const { | |
| 1448 return thread_checker_; | |
| 1449 } | |
| 1450 | |
| 1451 base::WeakPtr<gpu::gles2::GLES2Decoder> | 1355 base::WeakPtr<gpu::gles2::GLES2Decoder> |
| 1452 AndroidVideoDecodeAccelerator::GetGlDecoder() const { | 1356 AndroidVideoDecodeAccelerator::GetGlDecoder() const { |
| 1453 return get_gles2_decoder_cb_.Run(); | 1357 return get_gles2_decoder_cb_.Run(); |
| 1454 } | 1358 } |
| 1455 | 1359 |
| 1456 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture( | |
| 1457 const PictureBuffer& picture_buffer) { | |
| 1458 auto gles_decoder = GetGlDecoder(); | |
| 1459 RETURN_ON_FAILURE(this, gles_decoder, "Failed to get GL decoder", | |
| 1460 ILLEGAL_STATE, nullptr); | |
| 1461 RETURN_ON_FAILURE(this, gles_decoder->GetContextGroup(), | |
| 1462 "Null gles_decoder->GetContextGroup()", ILLEGAL_STATE, | |
| 1463 nullptr); | |
| 1464 gpu::gles2::TextureManager* texture_manager = | |
| 1465 gles_decoder->GetContextGroup()->texture_manager(); | |
| 1466 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager", | |
| 1467 ILLEGAL_STATE, nullptr); | |
| 1468 | |
| 1469 DCHECK_LE(1u, picture_buffer.internal_texture_ids().size()); | |
| 1470 gpu::gles2::TextureRef* texture_ref = | |
| 1471 texture_manager->GetTexture(picture_buffer.internal_texture_ids()[0]); | |
| 1472 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE, | |
| 1473 nullptr); | |
| 1474 | |
| 1475 return texture_ref; | |
| 1476 } | |
| 1477 | |
| 1478 scoped_refptr<gl::SurfaceTexture> | |
| 1479 AndroidVideoDecodeAccelerator::CreateAttachedSurfaceTexture( | |
| 1480 GLuint* service_id) { | |
| 1481 GLuint texture_id; | |
| 1482 glGenTextures(1, &texture_id); | |
| 1483 | |
| 1484 glActiveTexture(GL_TEXTURE0); | |
| 1485 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id); | |
| 1486 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 1487 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 1488 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 1489 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 1490 | |
| 1491 auto gl_decoder = GetGlDecoder(); | |
| 1492 gl_decoder->RestoreTextureUnitBindings(0); | |
| 1493 gl_decoder->RestoreActiveTexture(); | |
| 1494 DCHECK_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError()); | |
| 1495 | |
| 1496 *service_id = texture_id; | |
| 1497 // Previously, to reduce context switching, we used to create an unattached | |
| 1498 // SurfaceTexture and attach it lazily in the compositor's context. But that | |
| 1499 // was flaky because SurfaceTexture#detachFromGLContext() is buggy on a lot of | |
| 1500 // devices. Now we attach it to the current context, which means we might have | |
| 1501 // to context switch later to call updateTexImage(). Fortunately, if virtual | |
| 1502 // contexts are in use, we won't have to context switch. | |
| 1503 return gl::SurfaceTexture::Create(texture_id); | |
| 1504 } | |
| 1505 | |
| 1506 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { | 1360 void AndroidVideoDecodeAccelerator::OnDestroyingSurface(int surface_id) { |
| 1507 DCHECK(thread_checker_.CalledOnValidThread()); | 1361 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1508 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); | 1362 TRACE_EVENT0("media", "AVDA::OnDestroyingSurface"); |
| 1509 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; | 1363 DVLOG(1) << __FUNCTION__ << " surface_id: " << surface_id; |
| 1510 | 1364 |
| 1511 if (surface_id != config_.surface_id) | 1365 if (surface_id != config_.surface_id) |
| 1512 return; | 1366 return; |
| 1513 | 1367 |
| 1514 // If we're currently asynchronously configuring a codec, it will be destroyed | 1368 // If we're currently asynchronously configuring a codec, it will be destroyed |
| 1515 // when configuration completes and it notices that |state_| has changed to | 1369 // when configuration completes and it notices that |state_| has changed to |
| 1516 // SURFACE_DESTROYED. | 1370 // SURFACE_DESTROYED. |
| 1517 state_ = SURFACE_DESTROYED; | 1371 state_ = SURFACE_DESTROYED; |
| 1518 if (media_codec_) { | 1372 if (media_codec_) { |
| 1519 ReleaseMediaCodec(); | 1373 ReleaseMediaCodec(); |
| 1520 strategy_->CodecChanged(media_codec_.get()); | 1374 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
| 1521 } | 1375 } |
| 1522 // If we're draining, signal completion now because the drain can no longer | 1376 // If we're draining, signal completion now because the drain can no longer |
| 1523 // proceed. | 1377 // proceed. |
| 1524 if (drain_type_ != DRAIN_TYPE_NONE) | 1378 if (drain_type_ != DRAIN_TYPE_NONE) |
| 1525 OnDrainCompleted(); | 1379 OnDrainCompleted(); |
| 1526 } | 1380 } |
| 1527 | 1381 |
| 1528 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { | |
| 1529 // Remember: this may be on any thread. | |
| 1530 DCHECK(strategy_); | |
| 1531 strategy_->OnFrameAvailable(); | |
| 1532 } | |
| 1533 | |
| 1534 void AndroidVideoDecodeAccelerator::PostError( | 1382 void AndroidVideoDecodeAccelerator::PostError( |
| 1535 const ::tracked_objects::Location& from_here, | 1383 const ::tracked_objects::Location& from_here, |
| 1536 VideoDecodeAccelerator::Error error) { | 1384 VideoDecodeAccelerator::Error error) { |
| 1537 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 1385 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 1538 from_here, | 1386 from_here, |
| 1539 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, | 1387 base::Bind(&AndroidVideoDecodeAccelerator::NotifyError, |
| 1540 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_), | 1388 weak_this_factory_.GetWeakPtr(), error, error_sequence_token_), |
| 1541 (defer_errors_ ? ErrorPostingDelay : base::TimeDelta())); | 1389 (defer_errors_ ? ErrorPostingDelay : base::TimeDelta())); |
| 1542 state_ = ERROR; | 1390 state_ = ERROR; |
| 1543 } | 1391 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1686 // or not. | 1534 // or not. |
| 1687 if (!codec_config_->allow_autodetection_) { | 1535 if (!codec_config_->allow_autodetection_) { |
| 1688 media_codec_.reset(); | 1536 media_codec_.reset(); |
| 1689 } else { | 1537 } else { |
| 1690 g_avda_manager.Get().ConstructionTaskRunner()->DeleteSoon( | 1538 g_avda_manager.Get().ConstructionTaskRunner()->DeleteSoon( |
| 1691 FROM_HERE, media_codec_.release()); | 1539 FROM_HERE, media_codec_.release()); |
| 1692 } | 1540 } |
| 1693 } | 1541 } |
| 1694 | 1542 |
| 1695 // static | 1543 // static |
| 1696 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy( | |
| 1697 const gpu::GpuPreferences& gpu_preferences) { | |
| 1698 return true; | |
| 1699 } | |
| 1700 | |
| 1701 // static | |
| 1702 VideoDecodeAccelerator::Capabilities | 1544 VideoDecodeAccelerator::Capabilities |
| 1703 AndroidVideoDecodeAccelerator::GetCapabilities( | 1545 AndroidVideoDecodeAccelerator::GetCapabilities( |
| 1704 const gpu::GpuPreferences& gpu_preferences) { | 1546 const gpu::GpuPreferences& gpu_preferences) { |
| 1705 Capabilities capabilities; | 1547 Capabilities capabilities; |
| 1706 SupportedProfiles& profiles = capabilities.supported_profiles; | 1548 SupportedProfiles& profiles = capabilities.supported_profiles; |
| 1707 | 1549 |
| 1708 // Only support VP8 on Android versions where we don't have to synchronously | 1550 // Only support VP8 on Android versions where we don't have to synchronously |
| 1709 // tear down the MediaCodec on surface destruction because VP8 requires | 1551 // tear down the MediaCodec on surface destruction because VP8 requires |
| 1710 // us to completely drain the decoder before releasing it, which is difficult | 1552 // us to completely drain the decoder before releasing it, which is difficult |
| 1711 // and time consuming to do while the surface is being destroyed. | 1553 // and time consuming to do while the surface is being destroyed. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1752 profile.min_resolution.SetSize(0, 0); | 1594 profile.min_resolution.SetSize(0, 0); |
| 1753 // Advertise support for 4k and let the MediaCodec fail when decoding if it | 1595 // Advertise support for 4k and let the MediaCodec fail when decoding if it |
| 1754 // doesn't support the resolution. It's assumed that consumers won't have | 1596 // doesn't support the resolution. It's assumed that consumers won't have |
| 1755 // software fallback for H264 on Android anyway. | 1597 // software fallback for H264 on Android anyway. |
| 1756 profile.max_resolution.SetSize(3840, 2160); | 1598 profile.max_resolution.SetSize(3840, 2160); |
| 1757 profiles.push_back(profile); | 1599 profiles.push_back(profile); |
| 1758 } | 1600 } |
| 1759 | 1601 |
| 1760 capabilities.flags = | 1602 capabilities.flags = |
| 1761 VideoDecodeAccelerator::Capabilities::SUPPORTS_DEFERRED_INITIALIZATION; | 1603 VideoDecodeAccelerator::Capabilities::SUPPORTS_DEFERRED_INITIALIZATION; |
| 1762 if (UseDeferredRenderingStrategy(gpu_preferences)) { | 1604 capabilities.flags |= |
| 1763 capabilities.flags |= VideoDecodeAccelerator::Capabilities:: | 1605 VideoDecodeAccelerator::Capabilities::NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; |
| 1764 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; | |
| 1765 | 1606 |
| 1766 // If we're using threaded texture mailboxes the COPY_REQUIRED flag must be | 1607 // If we're using threaded texture mailboxes the COPY_REQUIRED flag must be |
| 1767 // set on deferred strategy frames (http://crbug.com/582170), and | 1608 // set on the video frames (http://crbug.com/582170), and SurfaceView output |
| 1768 // SurfaceView output is disabled (http://crbug.com/582170). | 1609 // is disabled (http://crbug.com/582170). |
| 1769 if (gpu_preferences.enable_threaded_texture_mailboxes) { | 1610 if (gpu_preferences.enable_threaded_texture_mailboxes) { |
| 1770 capabilities.flags |= | 1611 capabilities.flags |= |
| 1771 media::VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY; | 1612 media::VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY; |
| 1772 } else if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { | 1613 } else if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { |
| 1773 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: | 1614 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: |
| 1774 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1615 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| 1775 } | |
| 1776 } | 1616 } |
| 1777 | 1617 |
| 1778 return capabilities; | 1618 return capabilities; |
| 1779 } | 1619 } |
| 1780 | 1620 |
| 1781 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1621 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
| 1782 const { | 1622 const { |
| 1783 // Prevent MediaCodec from using its internal software decoders when we have | 1623 // Prevent MediaCodec from using its internal software decoders when we have |
| 1784 // more secure and up to date versions in the renderer process. | 1624 // more secure and up to date versions in the renderer process. |
| 1785 return !config_.is_encrypted && (codec_config_->codec_ == media::kCodecVP8 || | 1625 return !config_.is_encrypted && (codec_config_->codec_ == media::kCodecVP8 || |
| 1786 codec_config_->codec_ == media::kCodecVP9); | 1626 codec_config_->codec_ == media::kCodecVP9); |
| 1787 } | 1627 } |
| 1788 | 1628 |
| 1789 } // namespace media | 1629 } // namespace media |
| OLD | NEW |