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

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

Issue 1750213002: Fix Android black frames from MSE config changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/media/android_video_decode_accelerator.h" 5 #include "content/common/gpu/media/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/android/build_info.h" 9 #include "base/android/build_info.h"
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/lazy_instance.h" 14 #include "base/lazy_instance.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/trace_event/trace_event.h" 18 #include "base/trace_event/trace_event.h"
19 #include "content/common/gpu/gpu_channel.h" 19 #include "content/common/gpu/gpu_channel.h"
20 #include "content/common/gpu/media/android_copying_backing_strategy.h" 20 #include "content/common/gpu/media/android_copying_backing_strategy.h"
21 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h " 21 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h "
22 #include "content/common/gpu/media/avda_return_on_failure.h"
22 #include "content/common/gpu/media/shared_memory_region.h" 23 #include "content/common/gpu/media/shared_memory_region.h"
23 #include "content/public/common/content_switches.h" 24 #include "content/public/common/content_switches.h"
24 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 25 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
25 #include "gpu/command_buffer/service/gpu_switches.h" 26 #include "gpu/command_buffer/service/gpu_switches.h"
26 #include "gpu/command_buffer/service/mailbox_manager.h" 27 #include "gpu/command_buffer/service/mailbox_manager.h"
27 #include "media/base/android/media_codec_bridge.h" 28 #include "media/base/android/media_codec_bridge.h"
28 #include "media/base/android/media_codec_util.h" 29 #include "media/base/android/media_codec_util.h"
29 #include "media/base/bind_to_current_loop.h" 30 #include "media/base/bind_to_current_loop.h"
30 #include "media/base/bitstream_buffer.h" 31 #include "media/base/bitstream_buffer.h"
31 #include "media/base/limits.h" 32 #include "media/base/limits.h"
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 593
593 switch (status) { 594 switch (status) {
594 case media::MEDIA_CODEC_ERROR: 595 case media::MEDIA_CODEC_ERROR:
595 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); 596 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
596 return false; 597 return false;
597 598
598 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 599 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
599 return false; 600 return false;
600 601
601 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 602 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
602 if (!output_picture_buffers_.empty()) {
603 // TODO(chcunningham): This will likely dismiss a handful of decoded
604 // frames that have not yet been drawn and returned to us for re-use.
605 // Consider a more complicated design that would wait for them to be
606 // drawn before dismissing.
607 DismissPictureBuffers();
608 }
609
610 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) { 603 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) {
611 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed."); 604 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed.");
612 return false; 605 return false;
613 } 606 }
607 DVLOG(3) << __FUNCTION__
608 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
614 609
615 picturebuffers_requested_ = true; 610 // Don't request picture buffers if we already have some. This avoids
616 base::MessageLoop::current()->PostTask( 611 // having to dismiss the existing buffers which may actively reference
617 FROM_HERE, 612 // decoded images. Breaking their connection to the decoded image will
618 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, 613 // cause rendering of black frames. Instead, we let the existing
619 weak_this_factory_.GetWeakPtr())); 614 // PictureBuffers live on and we simply update their size the next time
620 return false; 615 // they're attachted to an image of the new resolution. See the
616 // size update in |SendDecodedFrameToClient| and https://crbug/587994.
617 if (output_picture_buffers_.empty() && !picturebuffers_requested_) {
618 picturebuffers_requested_ = true;
619 base::MessageLoop::current()->PostTask(
620 FROM_HERE,
621 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
622 weak_this_factory_.GetWeakPtr()));
623 return false;
624 }
625
626 return true;
621 } 627 }
622 628
623 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: 629 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
624 break; 630 break;
625 631
626 case media::MEDIA_CODEC_OK: 632 case media::MEDIA_CODEC_OK:
627 DCHECK_GE(buf_index, 0); 633 DCHECK_GE(buf_index, 0);
628 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp 634 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp
629 << " buf_index:" << buf_index << " offset:" << offset 635 << " buf_index:" << buf_index << " offset:" << offset
630 << " size:" << size << " eos:" << eos; 636 << " size:" << size << " eos:" << eos;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 722
717 if (!make_context_current_.Run()) { 723 if (!make_context_current_.Run()) {
718 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 724 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
719 return; 725 return;
720 } 726 }
721 727
722 int32_t picture_buffer_id = free_picture_ids_.front(); 728 int32_t picture_buffer_id = free_picture_ids_.front();
723 free_picture_ids_.pop(); 729 free_picture_ids_.pop();
724 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 730 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
725 731
726 OutputBufferMap::const_iterator i = 732 const auto& i = output_picture_buffers_.find(picture_buffer_id);
727 output_picture_buffers_.find(picture_buffer_id);
728 if (i == output_picture_buffers_.end()) { 733 if (i == output_picture_buffers_.end()) {
729 POST_ERROR(PLATFORM_FAILURE, 734 POST_ERROR(PLATFORM_FAILURE,
730 "Can't find PictureBuffer id: " << picture_buffer_id); 735 "Can't find PictureBuffer id: " << picture_buffer_id);
731 return; 736 return;
732 } 737 }
733 738
739 bool size_changed = false;
740 if (i->second.size() != size_) {
741 // Size may have changed due to resolution change since the last time this
742 // PictureBuffer was used.
743 strategy_->UpdatePictureBufferSize(&i->second, size_);
744 size_changed = true;
745 }
746
734 // Connect the PictureBuffer to the decoded frame, via whatever 747 // Connect the PictureBuffer to the decoded frame, via whatever
735 // mechanism the strategy likes. 748 // mechanism the strategy likes.
736 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); 749 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second);
737 750
738 const bool allow_overlay = strategy_->ArePicturesOverlayable(); 751 const bool allow_overlay = strategy_->ArePicturesOverlayable();
752
753 media::Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_),
754 allow_overlay);
755 picture.set_size_changed(size_changed);
756
739 base::MessageLoop::current()->PostTask( 757 base::MessageLoop::current()->PostTask(
740 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, 758 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
741 weak_this_factory_.GetWeakPtr(), 759 weak_this_factory_.GetWeakPtr(), picture));
742 media::Picture(picture_buffer_id, bitstream_id,
743 gfx::Rect(size_), allow_overlay)));
744 } 760 }
745 761
746 void AndroidVideoDecodeAccelerator::Decode( 762 void AndroidVideoDecodeAccelerator::Decode(
747 const media::BitstreamBuffer& bitstream_buffer) { 763 const media::BitstreamBuffer& bitstream_buffer) {
748 DCHECK(thread_checker_.CalledOnValidThread()); 764 DCHECK(thread_checker_.CalledOnValidThread());
749 765
750 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { 766 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) {
751 DecodeBuffer(bitstream_buffer); 767 DecodeBuffer(bitstream_buffer);
752 return; 768 return;
753 } 769 }
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() 1029 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
1014 const { 1030 const {
1015 return thread_checker_; 1031 return thread_checker_;
1016 } 1032 }
1017 1033
1018 base::WeakPtr<gpu::gles2::GLES2Decoder> 1034 base::WeakPtr<gpu::gles2::GLES2Decoder>
1019 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 1035 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
1020 return gl_decoder_; 1036 return gl_decoder_;
1021 } 1037 }
1022 1038
1039 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture(
1040 const media::PictureBuffer& picture_buffer) {
1041 RETURN_ON_FAILURE(this, gl_decoder_, "Null gl_decoder_", ILLEGAL_STATE,
1042 nullptr);
1043 RETURN_ON_FAILURE(this, gl_decoder_->GetContextGroup(),
1044 "Null gl_decoder_->GetContextGroup()", ILLEGAL_STATE,
1045 nullptr);
1046 gpu::gles2::TextureManager* texture_manager =
1047 gl_decoder_->GetContextGroup()->texture_manager();
1048 RETURN_ON_FAILURE(this, texture_manager, "Null texture_manager",
1049 ILLEGAL_STATE, nullptr);
1050 gpu::gles2::TextureRef* texture_ref =
1051 texture_manager->GetTexture(picture_buffer.internal_texture_id());
1052 RETURN_ON_FAILURE(this, texture_manager, "Null texture_ref", ILLEGAL_STATE,
1053 nullptr);
1054
1055 return texture_ref;
1056 }
1057
1023 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { 1058 void AndroidVideoDecodeAccelerator::OnFrameAvailable() {
1024 // Remember: this may be on any thread. 1059 // Remember: this may be on any thread.
1025 DCHECK(strategy_); 1060 DCHECK(strategy_);
1026 strategy_->OnFrameAvailable(); 1061 strategy_->OnFrameAvailable();
1027 } 1062 }
1028 1063
1029 void AndroidVideoDecodeAccelerator::PostError( 1064 void AndroidVideoDecodeAccelerator::PostError(
1030 const ::tracked_objects::Location& from_here, 1065 const ::tracked_objects::Location& from_here,
1031 media::VideoDecodeAccelerator::Error error) { 1066 media::VideoDecodeAccelerator::Error error) {
1032 base::MessageLoop::current()->PostDelayedTask( 1067 base::MessageLoop::current()->PostDelayedTask(
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1167 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1202 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1168 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1203 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1169 media::VideoDecodeAccelerator::Capabilities:: 1204 media::VideoDecodeAccelerator::Capabilities::
1170 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1205 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1171 } 1206 }
1172 1207
1173 return capabilities; 1208 return capabilities;
1174 } 1209 }
1175 1210
1176 } // namespace content 1211 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | content/common/gpu/media/avda_state_provider.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698