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

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: Feedback: Adding UpdatePictureBufferSize to strategy 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_util.h" 27 #include "media/base/android/media_codec_util.h"
27 #include "media/base/bind_to_current_loop.h" 28 #include "media/base/bind_to_current_loop.h"
28 #include "media/base/bitstream_buffer.h" 29 #include "media/base/bitstream_buffer.h"
29 #include "media/base/limits.h" 30 #include "media/base/limits.h"
30 #include "media/base/media.h" 31 #include "media/base/media.h"
31 #include "media/base/media_switches.h" 32 #include "media/base/media_switches.h"
32 #include "media/base/timestamp_constants.h" 33 #include "media/base/timestamp_constants.h"
33 #include "media/base/video_decoder_config.h" 34 #include "media/base/video_decoder_config.h"
34 #include "media/video/picture.h" 35 #include "media/video/picture.h"
35 #include "ui/gl/android/scoped_java_surface.h" 36 #include "ui/gl/android/scoped_java_surface.h"
36 #include "ui/gl/android/surface_texture.h" 37 #include "ui/gl/android/surface_texture.h"
37 #include "ui/gl/gl_bindings.h" 38 #include "ui/gl/gl_bindings.h"
38 39
39 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 40 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
40 #include "media/base/media_keys.h" 41 #include "media/base/media_keys.h"
41 #include "media/mojo/services/mojo_cdm_service.h" 42 #include "media/mojo/services/mojo_cdm_service.h"
42 #endif 43 #endif
43 44
44 #define POST_ERROR(error_code, error_message) \ 45 #define POST_ERROR(error_code, error_message) \
45 do { \ 46 do { \
46 DLOG(ERROR) << error_message; \ 47 DLOG(ERROR) << error_message; \
47 PostError(FROM_HERE, media::VideoDecodeAccelerator::error_code); \ 48 PostError(FROM_HERE, media::VideoDecodeAccelerator::error_code); \
48 } while (0) 49 } while (0)
49 50
51 // Override definition from avda_return_on_failure.h to s/state_provider_/this/.
52 #undef RETURN_NULL_IF_NULL
53 #define RETURN_NULL_IF_NULL(ptr, ...) \
54 RETURN_ON_FAILURE(this, ptr, "Got null for " << #ptr, ILLEGAL_STATE, nullptr);
55
50 namespace content { 56 namespace content {
51 57
52 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 }; 58 enum { kNumPictureBuffers = media::limits::kMaxVideoFrames + 1 };
53 59
54 // Max number of bitstreams notified to the client with 60 // Max number of bitstreams notified to the client with
55 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream. 61 // NotifyEndOfBitstreamBuffer() before getting output from the bitstream.
56 enum { kMaxBitstreamsNotifiedInAdvance = 32 }; 62 enum { kMaxBitstreamsNotifiedInAdvance = 32 };
57 63
58 // MediaCodec is only guaranteed to support baseline, but some devices may 64 // MediaCodec is only guaranteed to support baseline, but some devices may
59 // support others. Advertise support for all H264 profiles and let the 65 // support others. Advertise support for all H264 profiles and let the
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 is_encrypted_(false), 243 is_encrypted_(false),
238 needs_protected_surface_(false), 244 needs_protected_surface_(false),
239 state_(NO_ERROR), 245 state_(NO_ERROR),
240 picturebuffers_requested_(false), 246 picturebuffers_requested_(false),
241 gl_decoder_(decoder), 247 gl_decoder_(decoder),
242 cdm_registration_id_(0), 248 cdm_registration_id_(0),
243 pending_input_buf_index_(-1), 249 pending_input_buf_index_(-1),
244 error_sequence_token_(0), 250 error_sequence_token_(0),
245 defer_errors_(false), 251 defer_errors_(false),
246 weak_this_factory_(this) { 252 weak_this_factory_(this) {
247 if (UseDeferredRenderingStrategy()) { 253 // if (UseDeferredRenderingStrategy()) {
248 // TODO(liberato, watk): Figure out what we want to do about zero copy for 254 // // TODO(liberato, watk): Figure out what we want to do about zero copy
249 // fullscreen external SurfaceView in WebView. http://crbug.com/582170. 255 // for
250 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync()); 256 // // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
251 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; 257 // DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync());
252 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this)); 258 // DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy.";
253 } else { 259 // strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
254 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; 260 // } else {
255 strategy_.reset(new AndroidCopyingBackingStrategy(this)); 261 DVLOG(1) << __FUNCTION__ << ", using copy back strategy.";
256 } 262 strategy_.reset(new AndroidCopyingBackingStrategy(this));
263 // }
257 } 264 }
258 265
259 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 266 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
260 DCHECK(thread_checker_.CalledOnValidThread()); 267 DCHECK(thread_checker_.CalledOnValidThread());
261 g_avda_timer.Pointer()->StopTimer(this); 268 g_avda_timer.Pointer()->StopTimer(this);
262 269
263 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 270 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
264 if (cdm_) { 271 if (cdm_) {
265 DCHECK(cdm_registration_id_); 272 DCHECK(cdm_registration_id_);
266 static_cast<media::MediaDrmBridge*>(cdm_.get()) 273 static_cast<media::MediaDrmBridge*>(cdm_.get())
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 574
568 switch (status) { 575 switch (status) {
569 case media::MEDIA_CODEC_ERROR: 576 case media::MEDIA_CODEC_ERROR:
570 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); 577 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
571 return false; 578 return false;
572 579
573 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 580 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
574 return false; 581 return false;
575 582
576 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 583 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
577 if (!output_picture_buffers_.empty()) {
578 // TODO(chcunningham): This will likely dismiss a handful of decoded
579 // frames that have not yet been drawn and returned to us for re-use.
580 // Consider a more complicated design that would wait for them to be
581 // drawn before dismissing.
582 DismissPictureBuffers();
583 }
584
585 picturebuffers_requested_ = true;
586 int32_t width, height; 584 int32_t width, height;
587 media_codec_->GetOutputFormat(&width, &height); 585 media_codec_->GetOutputFormat(&width, &height);
588 size_ = gfx::Size(width, height); 586 size_ = gfx::Size(width, height);
589 base::MessageLoop::current()->PostTask( 587 DVLOG(4) << __FUNCTION__
590 FROM_HERE, 588 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
591 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers, 589
592 weak_this_factory_.GetWeakPtr())); 590 // Don't request picture buffers if we already have some. This avoids
593 return false; 591 // having to dismiss the existing buffers which may actively reference
592 // decoded images. Breaking their connection to the decoded image will
593 // cause rendering of black frames. Instead, we let the existing
594 // PictureBuffers live on and we simply update their size the next time
595 // they're attachted to an image of the new resolution. See the
596 // size update in |SendDecodedFrameToClient| and https://crbug/587994.
597 if (output_picture_buffers_.empty()) {
598 picturebuffers_requested_ = true;
599 base::MessageLoop::current()->PostTask(
600 FROM_HERE,
601 base::Bind(&AndroidVideoDecodeAccelerator::RequestPictureBuffers,
602 weak_this_factory_.GetWeakPtr()));
603 return false;
604 }
605
606 return true;
594 } 607 }
595 608
596 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED: 609 case media::MEDIA_CODEC_OUTPUT_BUFFERS_CHANGED:
597 break; 610 break;
598 611
599 case media::MEDIA_CODEC_OK: 612 case media::MEDIA_CODEC_OK:
600 DCHECK_GE(buf_index, 0); 613 DCHECK_GE(buf_index, 0);
601 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp 614 DVLOG(3) << __FUNCTION__ << ": pts:" << presentation_timestamp
602 << " buf_index:" << buf_index << " offset:" << offset 615 << " buf_index:" << buf_index << " offset:" << offset
603 << " size:" << size << " eos:" << eos; 616 << " size:" << size << " eos:" << eos;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 691
679 if (!make_context_current_.Run()) { 692 if (!make_context_current_.Run()) {
680 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current."); 693 POST_ERROR(PLATFORM_FAILURE, "Failed to make the GL context current.");
681 return; 694 return;
682 } 695 }
683 696
684 int32_t picture_buffer_id = free_picture_ids_.front(); 697 int32_t picture_buffer_id = free_picture_ids_.front();
685 free_picture_ids_.pop(); 698 free_picture_ids_.pop();
686 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size()); 699 TRACE_COUNTER1("media", "AVDA::FreePictureIds", free_picture_ids_.size());
687 700
688 OutputBufferMap::const_iterator i = 701 OutputBufferMap::iterator i = output_picture_buffers_.find(picture_buffer_id);
689 output_picture_buffers_.find(picture_buffer_id);
690 if (i == output_picture_buffers_.end()) { 702 if (i == output_picture_buffers_.end()) {
691 POST_ERROR(PLATFORM_FAILURE, 703 POST_ERROR(PLATFORM_FAILURE,
692 "Can't find PictureBuffer id: " << picture_buffer_id); 704 "Can't find PictureBuffer id: " << picture_buffer_id);
693 return; 705 return;
694 } 706 }
695 707
708 if (i->second.size() != size_) {
709 // Size may have changed due to resolution change since the last time this
710 // PictureBuffer was used.
711 strategy_->UpdatePictureBufferSize(&i->second, size_);
712 }
713
696 // Connect the PictureBuffer to the decoded frame, via whatever 714 // Connect the PictureBuffer to the decoded frame, via whatever
697 // mechanism the strategy likes. 715 // mechanism the strategy likes.
698 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second); 716 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second);
699 717
700 const bool allow_overlay = strategy_->ArePicturesOverlayable(); 718 const bool allow_overlay = strategy_->ArePicturesOverlayable();
701 base::MessageLoop::current()->PostTask( 719 base::MessageLoop::current()->PostTask(
702 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, 720 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady,
703 weak_this_factory_.GetWeakPtr(), 721 weak_this_factory_.GetWeakPtr(),
704 media::Picture(picture_buffer_id, bitstream_id, 722 media::Picture(picture_buffer_id, bitstream_id,
705 gfx::Rect(size_), allow_overlay))); 723 gfx::Rect(size_), allow_overlay)));
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker() 985 const base::ThreadChecker& AndroidVideoDecodeAccelerator::ThreadChecker()
968 const { 986 const {
969 return thread_checker_; 987 return thread_checker_;
970 } 988 }
971 989
972 base::WeakPtr<gpu::gles2::GLES2Decoder> 990 base::WeakPtr<gpu::gles2::GLES2Decoder>
973 AndroidVideoDecodeAccelerator::GetGlDecoder() const { 991 AndroidVideoDecodeAccelerator::GetGlDecoder() const {
974 return gl_decoder_; 992 return gl_decoder_;
975 } 993 }
976 994
995 gpu::gles2::TextureRef* const
996 AndroidVideoDecodeAccelerator::GetTextureForPicture(
997 const media::PictureBuffer& picture_buffer) {
998 RETURN_NULL_IF_NULL(GetGlDecoder());
999 RETURN_NULL_IF_NULL(GetGlDecoder()->GetContextGroup());
1000 gpu::gles2::TextureManager* texture_manager =
1001 GetGlDecoder()->GetContextGroup()->texture_manager();
1002 RETURN_NULL_IF_NULL(texture_manager);
1003 gpu::gles2::TextureRef* texture_ref =
1004 texture_manager->GetTexture(picture_buffer.internal_texture_id());
1005 RETURN_NULL_IF_NULL(texture_ref);
1006
1007 return texture_ref;
1008 }
1009
977 void AndroidVideoDecodeAccelerator::OnFrameAvailable() { 1010 void AndroidVideoDecodeAccelerator::OnFrameAvailable() {
978 // Remember: this may be on any thread. 1011 // Remember: this may be on any thread.
979 DCHECK(strategy_); 1012 DCHECK(strategy_);
980 strategy_->OnFrameAvailable(); 1013 strategy_->OnFrameAvailable();
981 } 1014 }
982 1015
983 void AndroidVideoDecodeAccelerator::PostError( 1016 void AndroidVideoDecodeAccelerator::PostError(
984 const ::tracked_objects::Location& from_here, 1017 const ::tracked_objects::Location& from_here,
985 media::VideoDecodeAccelerator::Error error) { 1018 media::VideoDecodeAccelerator::Error error) {
986 base::MessageLoop::current()->PostDelayedTask( 1019 base::MessageLoop::current()->PostDelayedTask(
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1154 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1122 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1155 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1123 media::VideoDecodeAccelerator::Capabilities:: 1156 media::VideoDecodeAccelerator::Capabilities::
1124 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1157 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1125 } 1158 }
1126 1159
1127 return capabilities; 1160 return capabilities;
1128 } 1161 }
1129 1162
1130 } // namespace content 1163 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698