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

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: Address the easy feedback, awaiting high level design sign off 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/public/common/content_switches.h" 23 #include "content/public/common/content_switches.h"
23 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 24 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
24 #include "gpu/command_buffer/service/gpu_switches.h" 25 #include "gpu/command_buffer/service/gpu_switches.h"
25 #include "gpu/command_buffer/service/mailbox_manager.h" 26 #include "gpu/command_buffer/service/mailbox_manager.h"
26 #include "media/base/android/media_codec_bridge.h" 27 #include "media/base/android/media_codec_bridge.h"
27 #include "media/base/android/media_codec_util.h" 28 #include "media/base/android/media_codec_util.h"
28 #include "media/base/bind_to_current_loop.h" 29 #include "media/base/bind_to_current_loop.h"
29 #include "media/base/bitstream_buffer.h" 30 #include "media/base/bitstream_buffer.h"
30 #include "media/base/limits.h" 31 #include "media/base/limits.h"
31 #include "media/base/media.h" 32 #include "media/base/media.h"
32 #include "media/base/media_switches.h" 33 #include "media/base/media_switches.h"
33 #include "media/base/timestamp_constants.h" 34 #include "media/base/timestamp_constants.h"
34 #include "media/base/video_decoder_config.h" 35 #include "media/base/video_decoder_config.h"
35 #include "media/video/picture.h" 36 #include "media/video/picture.h"
36 #include "ui/gl/android/scoped_java_surface.h" 37 #include "ui/gl/android/scoped_java_surface.h"
37 #include "ui/gl/android/surface_texture.h" 38 #include "ui/gl/android/surface_texture.h"
38 #include "ui/gl/gl_bindings.h" 39 #include "ui/gl/gl_bindings.h"
39 40
40 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 41 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
41 #include "media/base/media_keys.h" 42 #include "media/base/media_keys.h"
42 #include "media/mojo/services/mojo_cdm_service.h" 43 #include "media/mojo/services/mojo_cdm_service.h"
43 #endif 44 #endif
44 45
45 #define POST_ERROR(error_code, error_message) \ 46 #define POST_ERROR(error_code, error_message) \
46 do { \ 47 do { \
47 DLOG(ERROR) << error_message; \ 48 DLOG(ERROR) << error_message; \
48 PostError(FROM_HERE, media::VideoDecodeAccelerator::error_code); \ 49 PostError(FROM_HERE, media::VideoDecodeAccelerator::error_code); \
49 } while (0) 50 } while (0)
50 51
52 // Override definition from avda_return_on_failure.h to s/state_provider_/this/.
DaleCurtis 2016/03/08 18:29:03 Just use RETURN_ON_FAILURE directly instead of red
chcunningham 2016/03/08 22:19:13 Done.
53 #undef RETURN_NULL_IF_NULL
54 #define RETURN_NULL_IF_NULL(ptr, ...) \
55 RETURN_ON_FAILURE(this, ptr, "Got null for " << #ptr, ILLEGAL_STATE, nullptr);
56
51 namespace content { 57 namespace content {
52 58
53 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 }; 59 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 };
54 60
55 // Max number of bitstreams notified to the client with 61 // Max number of bitstreams notified to the client with
56 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. 62 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
57 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; 63 enum { kMaxBitstreamsNotifiedInAdvance = 32 };
58 64
59 // MediaCodec is only guaranteed to support baseline, but some devices may 65 // MediaCodec is only guaranteed to support baseline, but some devices may
60 // support others. Advertise support for all H264 profiles and let the 66 // support others. Advertise support for all H264 profiles and let the
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 584
579 switch (status) { 585 switch (status) {
580 case media::MEDIA_CODEC_ERROR: 586 case media::MEDIA_CODEC_ERROR:
581 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); 587 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
582 return false; 588 return false;
583 589
584 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 590 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
585 return false; 591 return false;
586 592
587 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 593 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
588 if (!output_picture_buffers_.empty()) {
589 // TODO(chcunningham): This will likely dismiss a handful of decoded
590 // frames that have not yet been drawn and returned to us for re-use.
591 // Consider a more complicated design that would wait for them to be
592 // drawn before dismissing.
593 DismissPictureBuffers();
594 }
595
596 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) { 594 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) {
597 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed."); 595 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed.");
598 return false; 596 return false;
599 } 597 }
598 DVLOG(3) << __FUNCTION__
599 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
600 600
601 picturebuffers_requested_ = true; 601 // Don't request picture buffers if we already have some. This avoids
602 base::MessageLoop::current()->PostTask( 602 // having to dismiss the existing buffers which may actively reference
603 FROM_HERE, 603 // decoded images. Breaking their connection to the decoded image will
604 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, 604 // cause rendering of black frames. Instead, we let the existing
605 weak_this_factory_.GetWeakPtr())); 605 // PictureBuffers live on and we simply update their size the next time
606 return false; 606 // they're attachted to an image of the new resolution. See the
607 // size update in |SendDecodedFrameToClient| and https://crbug/587994.
608 if (output_picture_buffers_.empty()) {
609 picturebuffers_requested_ = true;
DaleCurtis 2016/03/08 18:29:03 Should this value be double checked to prevent mul
chcunningham 2016/03/08 22:19:13 Done.
610 base::MessageLoop::current()->PostTask(
611 FROM_HERE,
612 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
613 weak_this_factory_.GetWeakPtr()));
614 return false;
615 }
616
617 return true;
607 } 618 }
608 619
609 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: 620 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
610 break; 621 break;
611 622
612 case media::MEDIA_CODEC_OK: 623 case media::MEDIA_CODEC_OK:
613 DCHECK_GE(buf_index, 0); 624 DCHECK_GE(buf_index, 0);
614 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp 625 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp
615 << " buf_index:" << buf_index << " offset:" << offset 626 << " buf_index:" << buf_index << " offset:" << offset
616 << " size:" << size << " eos:" << eos; 627 << " size:" << size << " eos:" << eos;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 713
703 if (!make_context_current_.Run()) { 714 if (!make_context_current_.Run()) {
704 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 715 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
705 return; 716 return;
706 } 717 }
707 718
708 int32_t picture_buffer_id = free_picture_ids_.front(); 719 int32_t picture_buffer_id = free_picture_ids_.front();
709 free_picture_ids_.pop(); 720 free_picture_ids_.pop();
710 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 721 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
711 722
712 OutputBufferMap::const_iterator i = 723 OutputBufferMap::iterator i = output_picture_buffers_.find(picture_buffer_id);
DaleCurtis 2016/03/08 18:29:03 This is a fine place for auto if you like.
chcunningham 2016/03/08 22:19:13 Done.
713 output_picture_buffers_.find(picture_buffer_id);
714 if (i == output_picture_buffers_.end()) { 724 if (i == output_picture_buffers_.end()) {
715 POST_ERROR(PLATFORM_FAILURE, 725 POST_ERROR(PLATFORM_FAILURE,
716 "Can't find PictureBuffer id: " << picture_buffer_id); 726 "Can't find PictureBuffer id: " << picture_buffer_id);
717 return; 727 return;
718 } 728 }
719 729
730 bool size_changed = false;
731 if (i->second.size() != size_) {
732 // Size may have changed due to resolution change since the last time this
733 // PictureBuffer was used.
734 strategy_->UpdatePictureBufferSize(&i->second, size_);
735 size_changed = true;
736 }
737
720 // Connect the PictureBuffer to the decoded frame, via whatever 738 // Connect the PictureBuffer to the decoded frame, via whatever
721 // mechanism the strategy likes. 739 // mechanism the strategy likes.
722 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); 740 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second);
723 741
724 const bool allow_overlay = strategy_->ArePicturesOverlayable(); 742 const bool allow_overlay = strategy_->ArePicturesOverlayable();
725 base::MessageLoop::current()->PostTask( 743 base::MessageLoop::current()->PostTask(
726 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, 744 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
727 weak_this_factory_.GetWeakPtr(), 745 weak_this_factory_.GetWeakPtr(),
728 media::Picture(picture_buffer_id, bitstream_id, 746 media::Picture(picture_buffer_id, bitstream_id,
729 gfx::Rect(size_), allow_overlay))); 747 gfx::Rect(size_), allow_overlay,
748 size_changed)));
730 } 749 }
731 750
732 void AndroidVideoDecodeAccelerator::Decode( 751 void AndroidVideoDecodeAccelerator::Decode(
733 const media::BitstreamBuffer& bitstream_buffer) { 752 const media::BitstreamBuffer& bitstream_buffer) {
734 DCHECK(thread_checker_.CalledOnValidThread()); 753 DCHECK(thread_checker_.CalledOnValidThread());
735 754
736 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { 755 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) {
737 DecodeBuffer(bitstream_buffer); 756 DecodeBuffer(bitstream_buffer);
738 return; 757 return;
739 } 758 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() 1013 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
995 const { 1014 const {
996 return thread_checker_; 1015 return thread_checker_;
997 } 1016 }
998 1017
999 base::WeakPtr<gpu::gles2::GLES2Decoder> 1018 base::WeakPtr<gpu::gles2::GLES2Decoder>
1000 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 1019 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
1001 return gl_decoder_; 1020 return gl_decoder_;
1002 } 1021 }
1003 1022
1023 gpu::gles2::TextureRef* AndroidVideoDecodeAccelerator::GetTextureForPicture(
1024 const media::PictureBuffer& picture_buffer) {
1025 RETURN_NULL_IF_NULL(GetGlDecoder());
1026 RETURN_NULL_IF_NULL(GetGlDecoder()->GetContextGroup());
1027 gpu::gles2::TextureManager* texture_manager =
1028 GetGlDecoder()->GetContextGroup()->texture_manager();
1029 RETURN_NULL_IF_NULL(texture_manager);
1030 gpu::gles2::TextureRef* texture_ref =
1031 texture_manager->GetTexture(picture_buffer.internal_texture_id());
1032 RETURN_NULL_IF_NULL(texture_ref);
1033
1034 return texture_ref;
1035 }
1036
1004 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { 1037 void AndroidVideoDecodeAccelerator::OnFrameAvailable() {
1005 // Remember: this may be on any thread. 1038 // Remember: this may be on any thread.
1006 DCHECK(strategy_); 1039 DCHECK(strategy_);
1007 strategy_->OnFrameAvailable(); 1040 strategy_->OnFrameAvailable();
1008 } 1041 }
1009 1042
1010 void AndroidVideoDecodeAccelerator::PostError( 1043 void AndroidVideoDecodeAccelerator::PostError(
1011 const ::tracked_objects::Location& from_here, 1044 const ::tracked_objects::Location& from_here,
1012 media::VideoDecodeAccelerator::Error error) { 1045 media::VideoDecodeAccelerator::Error error) {
1013 base::MessageLoop::current()->PostDelayedTask( 1046 base::MessageLoop::current()->PostDelayedTask(
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1181 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1149 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1182 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1150 media::VideoDecodeAccelerator::Capabilities:: 1183 media::VideoDecodeAccelerator::Capabilities::
1151 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1184 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1152 } 1185 }
1153 1186
1154 return capabilities; 1187 return capabilities;
1155 } 1188 }
1156 1189
1157 } // namespace content 1190 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698