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

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

Issue 1963773003: Merge to M51: Various fixes to prevent playback hang on MotoX. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2704
Patch Set: Created 4 years, 7 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/callback_helpers.h"
13 #include "base/command_line.h" 14 #include "base/command_line.h"
14 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
15 #include "base/logging.h" 16 #include "base/logging.h"
16 #include "base/message_loop/message_loop.h" 17 #include "base/message_loop/message_loop.h"
17 #include "base/metrics/histogram.h" 18 #include "base/metrics/histogram.h"
18 #include "base/task_runner_util.h" 19 #include "base/task_runner_util.h"
19 #include "base/threading/thread_checker.h" 20 #include "base/threading/thread_checker.h"
20 #include "base/trace_event/trace_event.h" 21 #include "base/trace_event/trace_event.h"
21 #include "content/common/gpu/media/android_copying_backing_strategy.h" 22 #include "content/common/gpu/media/android_copying_backing_strategy.h"
22 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h " 23 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h "
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 303
303 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 304 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
304 const MakeGLContextCurrentCallback& make_context_current_cb, 305 const MakeGLContextCurrentCallback& make_context_current_cb,
305 const GetGLES2DecoderCallback& get_gles2_decoder_cb) 306 const GetGLES2DecoderCallback& get_gles2_decoder_cb)
306 : client_(NULL), 307 : client_(NULL),
307 make_context_current_cb_(make_context_current_cb), 308 make_context_current_cb_(make_context_current_cb),
308 get_gles2_decoder_cb_(get_gles2_decoder_cb), 309 get_gles2_decoder_cb_(get_gles2_decoder_cb),
309 is_encrypted_(false), 310 is_encrypted_(false),
310 state_(NO_ERROR), 311 state_(NO_ERROR),
311 picturebuffers_requested_(false), 312 picturebuffers_requested_(false),
313 drain_type_(DRAIN_TYPE_NONE),
312 media_drm_bridge_cdm_context_(nullptr), 314 media_drm_bridge_cdm_context_(nullptr),
313 cdm_registration_id_(0), 315 cdm_registration_id_(0),
314 pending_input_buf_index_(-1), 316 pending_input_buf_index_(-1),
315 error_sequence_token_(0), 317 error_sequence_token_(0),
316 defer_errors_(false), 318 defer_errors_(false),
317 deferred_initialization_pending_(false), 319 deferred_initialization_pending_(false),
318 weak_this_factory_(this) {} 320 weak_this_factory_(this) {}
319 321
320 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 322 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
321 DCHECK(thread_checker_.CalledOnValidThread()); 323 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 490
489 NOTIMPLEMENTED(); 491 NOTIMPLEMENTED();
490 NotifyInitializationComplete(false); 492 NotifyInitializationComplete(false);
491 493
492 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) 494 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
493 } 495 }
494 496
495 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { 497 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) {
496 DCHECK(thread_checker_.CalledOnValidThread()); 498 DCHECK(thread_checker_.CalledOnValidThread());
497 TRACE_EVENT0("media", "AVDA::DoIOTask"); 499 TRACE_EVENT0("media", "AVDA::DoIOTask");
498 if (state_ == ERROR || state_ == WAITING_FOR_CODEC) { 500 if (state_ == ERROR || state_ == WAITING_FOR_CODEC)
499 return; 501 return;
500 }
501 502
502 bool did_work = QueueInput(); 503 strategy_->MaybeRenderEarly();
503 while (DequeueOutput()) 504 bool did_work = false, did_input = false, did_output = false;
504 did_work = true; 505 do {
506 did_input = QueueInput();
507 did_output = DequeueOutput();
508 if (did_input || did_output)
509 did_work = true;
510 } while (did_input || did_output);
505 511
506 ManageTimer(did_work || start_timer); 512 ManageTimer(did_work || start_timer);
507 } 513 }
508 514
509 bool AndroidVideoDecodeAccelerator::QueueInput() { 515 bool AndroidVideoDecodeAccelerator::QueueInput() {
510 DCHECK(thread_checker_.CalledOnValidThread()); 516 DCHECK(thread_checker_.CalledOnValidThread());
511 TRACE_EVENT0("media", "AVDA::QueueInput"); 517 TRACE_EVENT0("media", "AVDA::QueueInput");
512 base::AutoReset<bool> auto_reset(&defer_errors_, true); 518 base::AutoReset<bool> auto_reset(&defer_errors_, true);
513 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance) 519 if (bitstreams_notified_in_advance_.size() > kMaxBitstreamsNotifiedInAdvance)
514 return false; 520 return false;
(...skipping 26 matching lines...) Expand all
541 547
542 DCHECK_NE(input_buf_index, -1); 548 DCHECK_NE(input_buf_index, -1);
543 549
544 media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front(); 550 media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front();
545 551
546 if (bitstream_buffer.id() == -1) { 552 if (bitstream_buffer.id() == -1) {
547 pending_bitstream_buffers_.pop(); 553 pending_bitstream_buffers_.pop();
548 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 554 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
549 pending_bitstream_buffers_.size()); 555 pending_bitstream_buffers_.size());
550 556
551 DCHECK_NE(state_, ERROR);
552 state_ = WAITING_FOR_EOS;
553 media_codec_->QueueEOS(input_buf_index); 557 media_codec_->QueueEOS(input_buf_index);
554 return true; 558 return true;
555 } 559 }
556 560
557 scoped_ptr<SharedMemoryRegion> shm; 561 scoped_ptr<SharedMemoryRegion> shm;
558 562
559 if (pending_input_buf_index_ == -1) { 563 if (pending_input_buf_index_ == -1) {
560 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued 564 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued
561 // from MediaCodec, filled with data and bitstream_buffer.handle() is 565 // from MediaCodec, filled with data and bitstream_buffer.handle() is
562 // closed. 566 // closed.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); 665 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput");
662 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 666 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
663 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp, 667 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp,
664 &eos, NULL); 668 &eos, NULL);
665 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status, 669 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status,
666 "presentation_timestamp (ms)", 670 "presentation_timestamp (ms)",
667 presentation_timestamp.InMilliseconds()); 671 presentation_timestamp.InMilliseconds());
668 672
669 switch (status) { 673 switch (status) {
670 case media::MEDIA_CODEC_ERROR: 674 case media::MEDIA_CODEC_ERROR:
671 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); 675 // Do not post an error if we are draining for reset and destroy.
676 // Instead, run the drain completion task.
677 if (IsDrainingForResetOrDestroy()) {
678 DVLOG(1) << __FUNCTION__ << ": error while codec draining";
679 state_ = ERROR;
680 OnDrainCompleted();
681 } else {
682 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
683 }
672 return false; 684 return false;
673 685
674 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 686 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
675 return false; 687 return false;
676 688
677 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 689 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
690 // An OUTPUT_FORMAT_CHANGED is not reported after flush() if the frame
691 // size does not change. Therefore we have to keep track on the format
692 // even if draining, unless we are draining for destroy.
693 if (drain_type_ == DRAIN_FOR_DESTROY)
694 return true; // ignore
695
678 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) { 696 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) {
679 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed."); 697 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed.");
680 return false; 698 return false;
681 } 699 }
700
682 DVLOG(3) << __FUNCTION__ 701 DVLOG(3) << __FUNCTION__
683 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); 702 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
684 703
685 // Don't request picture buffers if we already have some. This avoids 704 // Don't request picture buffers if we already have some. This avoids
686 // having to dismiss the existing buffers which may actively reference 705 // having to dismiss the existing buffers which may actively reference
687 // decoded images. Breaking their connection to the decoded image will 706 // decoded images. Breaking their connection to the decoded image will
688 // cause rendering of black frames. Instead, we let the existing 707 // cause rendering of black frames. Instead, we let the existing
689 // PictureBuffers live on and we simply update their size the next time 708 // PictureBuffers live on and we simply update their size the next time
690 // they're attachted to an image of the new resolution. See the 709 // they're attachted to an image of the new resolution. See the
691 // size update in |SendDecodedFrameToClient| and https://crbug/587994. 710 // size update in |SendDecodedFrameToClient| and https://crbug/587994.
(...skipping 19 matching lines...) Expand all
711 << " size:" << size << " eos:" << eos; 730 << " size:" << size << " eos:" << eos;
712 break; 731 break;
713 732
714 default: 733 default:
715 NOTREACHED(); 734 NOTREACHED();
716 break; 735 break;
717 } 736 }
718 } while (buf_index < 0); 737 } while (buf_index < 0);
719 738
720 if (eos) { 739 if (eos) {
721 DVLOG(3) << __FUNCTION__ << ": Resetting codec state after EOS"; 740 OnDrainCompleted();
741 return false;
742 }
722 743
723 // If we were waiting for an EOS, clear the state and reset the MediaCodec 744 if (IsDrainingForResetOrDestroy()) {
724 // as normal. Otherwise, enter the ERROR state which will force destruction 745 media_codec_->ReleaseOutputBuffer(buf_index, false);
725 // of MediaCodec during ResetCodecState(). 746 return true;
726 //
727 // Some Android platforms seem to send an EOS buffer even when we're not
728 // expecting it. In this case, destroy and reset the codec but don't notify
729 // flush done since it violates the state machine. http://crbug.com/585959.
730 const bool was_waiting_for_eos = state_ == WAITING_FOR_EOS;
731 state_ = was_waiting_for_eos ? NO_ERROR : ERROR;
732
733 ResetCodecState();
734 // |media_codec_| might still be null.
735 if (was_waiting_for_eos) {
736 base::MessageLoop::current()->PostTask(
737 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
738 weak_this_factory_.GetWeakPtr()));
739 }
740 return false;
741 } 747 }
742 748
743 if (!picturebuffers_requested_) { 749 if (!picturebuffers_requested_) {
744 // If, somehow, we get a decoded frame back before a FORMAT_CHANGED 750 // If, somehow, we get a decoded frame back before a FORMAT_CHANGED
745 // message, then we might not have any picture buffers to use. This 751 // message, then we might not have any picture buffers to use. This
746 // isn't supposed to happen (see EncodeDecodeTest.java#617). 752 // isn't supposed to happen (see EncodeDecodeTest.java#617).
747 // Log a metric to see how common this is. 753 // Log a metric to see how common this is.
748 RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged); 754 RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged);
749 media_codec_->ReleaseOutputBuffer(buf_index, false); 755 media_codec_->ReleaseOutputBuffer(buf_index, false);
750 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED."); 756 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED.");
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 } 819 }
814 820
815 bool size_changed = false; 821 bool size_changed = false;
816 if (i->second.size() != size_) { 822 if (i->second.size() != size_) {
817 // Size may have changed due to resolution change since the last time this 823 // Size may have changed due to resolution change since the last time this
818 // PictureBuffer was used. 824 // PictureBuffer was used.
819 strategy_->UpdatePictureBufferSize(&i->second, size_); 825 strategy_->UpdatePictureBufferSize(&i->second, size_);
820 size_changed = true; 826 size_changed = true;
821 } 827 }
822 828
823 // Connect the PictureBuffer to the decoded frame, via whatever
824 // mechanism the strategy likes.
825 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second);
826
827 const bool allow_overlay = strategy_->ArePicturesOverlayable(); 829 const bool allow_overlay = strategy_->ArePicturesOverlayable();
828
829 media::Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_), 830 media::Picture picture(picture_buffer_id, bitstream_id, gfx::Rect(size_),
830 allow_overlay); 831 allow_overlay);
831 picture.set_size_changed(size_changed); 832 picture.set_size_changed(size_changed);
832 833
833 base::MessageLoop::current()->PostTask( 834 // Notify picture ready before calling UseCodecBufferForPictureBuffer() since
834 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyPictureReady, 835 // that process may be slow and shouldn't delay delivery of the frame to the
835 weak_this_factory_.GetWeakPtr(), picture)); 836 // renderer. The picture is only used on the same thread as this method is
837 // called, so it is safe to do this.
838 NotifyPictureReady(picture);
839
840 // Connect the PictureBuffer to the decoded frame, via whatever mechanism the
841 // strategy likes.
842 strategy_->UseCodecBufferForPictureBuffer(codec_buffer_index, i->second);
836 } 843 }
837 844
838 void AndroidVideoDecodeAccelerator::Decode( 845 void AndroidVideoDecodeAccelerator::Decode(
839 const media::BitstreamBuffer& bitstream_buffer) { 846 const media::BitstreamBuffer& bitstream_buffer) {
840 DCHECK(thread_checker_.CalledOnValidThread()); 847 DCHECK(thread_checker_.CalledOnValidThread());
841 848
842 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) { 849 if (bitstream_buffer.id() >= 0 && bitstream_buffer.size() > 0) {
843 DecodeBuffer(bitstream_buffer); 850 DecodeBuffer(bitstream_buffer);
844 return; 851 return;
845 } 852 }
(...skipping 15 matching lines...) Expand all
861 void AndroidVideoDecodeAccelerator::DecodeBuffer( 868 void AndroidVideoDecodeAccelerator::DecodeBuffer(
862 const media::BitstreamBuffer& bitstream_buffer) { 869 const media::BitstreamBuffer& bitstream_buffer) {
863 pending_bitstream_buffers_.push(bitstream_buffer); 870 pending_bitstream_buffers_.push(bitstream_buffer);
864 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 871 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
865 pending_bitstream_buffers_.size()); 872 pending_bitstream_buffers_.size());
866 873
867 DoIOTask(true); 874 DoIOTask(true);
868 } 875 }
869 876
870 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 877 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
871 client_->ProvidePictureBuffers(kNumPictureBuffers, 1, 878 if (client_) {
872 strategy_->GetPictureBufferSize(), 879 client_->ProvidePictureBuffers(kNumPictureBuffers, 1,
873 strategy_->GetTextureTarget()); 880 strategy_->GetPictureBufferSize(),
881 strategy_->GetTextureTarget());
882 }
874 } 883 }
875 884
876 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 885 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
877 const std::vector<media::PictureBuffer>& buffers) { 886 const std::vector<media::PictureBuffer>& buffers) {
878 DCHECK(thread_checker_.CalledOnValidThread()); 887 DCHECK(thread_checker_.CalledOnValidThread());
879 DCHECK(output_picture_buffers_.empty()); 888 DCHECK(output_picture_buffers_.empty());
880 DCHECK(free_picture_ids_.empty()); 889 DCHECK(free_picture_ids_.empty());
881 890
882 if (buffers.size() < kNumPictureBuffers) { 891 if (buffers.size() < kNumPictureBuffers) {
883 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 892 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " 928 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id "
920 << picture_buffer_id); 929 << picture_buffer_id);
921 return; 930 return;
922 } 931 }
923 932
924 strategy_->ReuseOnePictureBuffer(i->second); 933 strategy_->ReuseOnePictureBuffer(i->second);
925 DoIOTask(true); 934 DoIOTask(true);
926 } 935 }
927 936
928 void AndroidVideoDecodeAccelerator::Flush() { 937 void AndroidVideoDecodeAccelerator::Flush() {
938 DVLOG(1) << __FUNCTION__;
929 DCHECK(thread_checker_.CalledOnValidThread()); 939 DCHECK(thread_checker_.CalledOnValidThread());
930 940
931 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); 941 StartCodecDrain(DRAIN_FOR_FLUSH);
932 } 942 }
933 943
934 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { 944 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
935 DCHECK(thread_checker_.CalledOnValidThread()); 945 DCHECK(thread_checker_.CalledOnValidThread());
936 946
937 // It's probably okay just to return here, since the codec will be configured 947 // It's probably okay just to return here, since the codec will be configured
938 // asynchronously. It's unclear that any state for the new request could 948 // asynchronously. It's unclear that any state for the new request could
939 // be different, unless somebody modifies |codec_config_| while we're already 949 // be different, unless somebody modifies |codec_config_| while we're already
940 // waiting for a codec. One shouldn't do that for thread safety. 950 // waiting for a codec. One shouldn't do that for thread safety.
941 DCHECK_NE(state_, WAITING_FOR_CODEC); 951 DCHECK_NE(state_, WAITING_FOR_CODEC);
942 952
943 state_ = WAITING_FOR_CODEC; 953 state_ = WAITING_FOR_CODEC;
944 954
945 // Tell the strategy that we're changing codecs. The codec itself could be 955 // Tell the strategy that we're changing codecs. The codec itself could be
946 // used normally, since we don't replace it until we're back on the main 956 // used normally, since we don't replace it until we're back on the main
947 // thread. However, if we're using an output surface, then the incoming codec 957 // thread. However, if we're using an output surface, then the incoming codec
948 // might access that surface while the main thread is drawing. Telling the 958 // might access that surface while the main thread is drawing. Telling the
949 // strategy to forget the codec avoids this. 959 // strategy to forget the codec avoids this.
950 if (media_codec_) { 960 if (media_codec_) {
951 media_codec_.reset(); 961 media_codec_.reset();
952 strategy_->CodecChanged(nullptr, output_picture_buffers_); 962 strategy_->CodecChanged(nullptr);
953 } 963 }
954 964
955 scoped_refptr<base::SingleThreadTaskRunner> task_runner = 965 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
956 g_avda_timer.Pointer()->ConstructionTaskRunner(); 966 g_avda_timer.Pointer()->ConstructionTaskRunner();
957 CHECK(task_runner); 967 CHECK(task_runner);
958 968
959 base::PostTaskAndReplyWithResult( 969 base::PostTaskAndReplyWithResult(
960 task_runner.get(), FROM_HERE, 970 task_runner.get(), FROM_HERE,
961 base::Bind(&AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread, 971 base::Bind(&AndroidVideoDecodeAccelerator::ConfigureMediaCodecOnAnyThread,
962 codec_config_), 972 codec_config_),
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 void AndroidVideoDecodeAccelerator::OnCodecConfigured( 1004 void AndroidVideoDecodeAccelerator::OnCodecConfigured(
995 scoped_ptr<media::VideoCodecBridge> media_codec) { 1005 scoped_ptr<media::VideoCodecBridge> media_codec) {
996 DCHECK(thread_checker_.CalledOnValidThread()); 1006 DCHECK(thread_checker_.CalledOnValidThread());
997 DCHECK_EQ(state_, WAITING_FOR_CODEC); 1007 DCHECK_EQ(state_, WAITING_FOR_CODEC);
998 1008
999 media_codec_ = std::move(media_codec); 1009 media_codec_ = std::move(media_codec);
1000 1010
1001 // Record one instance of the codec being initialized. 1011 // Record one instance of the codec being initialized.
1002 RecordFormatChangedMetric(FormatChangedValue::CodecInitialized); 1012 RecordFormatChangedMetric(FormatChangedValue::CodecInitialized);
1003 1013
1004 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); 1014 strategy_->CodecChanged(media_codec_.get());
1005 1015
1006 // If we are supposed to notify that initialization is complete, then do so 1016 // If we are supposed to notify that initialization is complete, then do so
1007 // now. Otherwise, this is a reconfiguration. 1017 // now. Otherwise, this is a reconfiguration.
1008 if (deferred_initialization_pending_) { 1018 if (deferred_initialization_pending_) {
1009 NotifyInitializationComplete(!!media_codec_); 1019 NotifyInitializationComplete(!!media_codec_);
1010 deferred_initialization_pending_ = false; 1020 deferred_initialization_pending_ = false;
1011 } 1021 }
1012 1022
1013 if (!media_codec_) { 1023 if (!media_codec_) {
1014 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); 1024 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
1015 return; 1025 return;
1016 } 1026 }
1017 1027
1018 state_ = NO_ERROR; 1028 state_ = NO_ERROR;
1019 1029
1020 ManageTimer(true); 1030 ManageTimer(true);
1021 } 1031 }
1022 1032
1023 void AndroidVideoDecodeAccelerator::ResetCodecState() { 1033 void AndroidVideoDecodeAccelerator::StartCodecDrain(DrainType drain_type) {
1034 DVLOG(2) << __FUNCTION__ << " drain_type:" << drain_type;
1035 DCHECK(thread_checker_.CalledOnValidThread());
1036
1037 // We assume that DRAIN_FOR_FLUSH and DRAIN_FOR_RESET cannot come while
1038 // another drain request is present, but DRAIN_FOR_DESTROY can.
1039 DCHECK_NE(drain_type, DRAIN_TYPE_NONE);
1040 DCHECK(drain_type_ == DRAIN_TYPE_NONE || drain_type == DRAIN_FOR_DESTROY)
1041 << "Unexpected StartCodecDrain() with drain type " << drain_type
1042 << " while already draining with drain type " << drain_type_;
1043
1044 const bool enqueue_eos = drain_type_ == DRAIN_TYPE_NONE;
1045 drain_type_ = drain_type;
1046
1047 if (enqueue_eos)
1048 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
1049 }
1050
1051 bool AndroidVideoDecodeAccelerator::IsDrainingForResetOrDestroy() const {
1052 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY;
1053 }
1054
1055 void AndroidVideoDecodeAccelerator::OnDrainCompleted() {
1056 DVLOG(2) << __FUNCTION__;
1057 DCHECK(thread_checker_.CalledOnValidThread());
1058
1059 // If we were waiting for an EOS, clear the state and reset the MediaCodec
1060 // as normal. Otherwise, enter the ERROR state which will force destruction
1061 // of MediaCodec during ResetCodecState().
1062 //
1063 // Some Android platforms seem to send an EOS buffer even when we're not
1064 // expecting it. In this case, destroy and reset the codec but don't notify
1065 // flush done since it violates the state machine. http://crbug.com/585959.
1066
1067 switch (drain_type_) {
1068 case DRAIN_TYPE_NONE:
1069 // Unexpected EOS.
1070 state_ = ERROR;
1071 ResetCodecState(base::Closure());
1072 break;
1073 case DRAIN_FOR_FLUSH:
1074 ResetCodecState(media::BindToCurrentLoop(
1075 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
1076 weak_this_factory_.GetWeakPtr())));
1077 break;
1078 case DRAIN_FOR_RESET:
1079 ResetCodecState(media::BindToCurrentLoop(
1080 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1081 weak_this_factory_.GetWeakPtr())));
1082 break;
1083 case DRAIN_FOR_DESTROY:
1084 base::MessageLoop::current()->PostTask(
1085 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::ActualDestroy,
1086 weak_this_factory_.GetWeakPtr()));
1087 break;
1088 }
1089 drain_type_ = DRAIN_TYPE_NONE;
1090 }
1091
1092 void AndroidVideoDecodeAccelerator::ResetCodecState(
1093 const base::Closure& done_cb) {
1024 DCHECK(thread_checker_.CalledOnValidThread()); 1094 DCHECK(thread_checker_.CalledOnValidThread());
1025 1095
1026 // If there is already a reset in flight, then that counts. This can really 1096 // If there is already a reset in flight, then that counts. This can really
1027 // only happen if somebody calls Reset. 1097 // only happen if somebody calls Reset.
1028 if (state_ == WAITING_FOR_CODEC) 1098 if (state_ == WAITING_FOR_CODEC) {
1099 if (!done_cb.is_null())
1100 done_cb.Run();
1029 return; 1101 return;
1102 }
1030 1103
1031 bitstream_buffers_in_decoder_.clear(); 1104 bitstream_buffers_in_decoder_.clear();
1032 1105
1033 if (pending_input_buf_index_ != -1) { 1106 if (pending_input_buf_index_ != -1) {
1034 // The data for that index exists in the input buffer, but corresponding 1107 // The data for that index exists in the input buffer, but corresponding
1035 // shm block been deleted. Check that it is safe to flush the coec, i.e. 1108 // shm block been deleted. Check that it is safe to flush the coec, i.e.
1036 // |pending_bitstream_buffers_| is empty. 1109 // |pending_bitstream_buffers_| is empty.
1037 // TODO(timav): keep shm block for that buffer and remove this restriction. 1110 // TODO(timav): keep shm block for that buffer and remove this restriction.
1038 DCHECK(pending_bitstream_buffers_.empty()); 1111 DCHECK(pending_bitstream_buffers_.empty());
1039 pending_input_buf_index_ = -1; 1112 pending_input_buf_index_ = -1;
1040 } 1113 }
1041 1114
1042 if (state_ == WAITING_FOR_KEY) 1115 const bool did_codec_error_happen = state_ == ERROR;
1043 state_ = NO_ERROR; 1116 state_ = NO_ERROR;
1044 1117
1045 // We might increment error_sequence_token here to cancel any delayed errors, 1118 // We might increment error_sequence_token here to cancel any delayed errors,
1046 // but right now it's unclear that it's safe to do so. If we are in an error 1119 // but right now it's unclear that it's safe to do so. If we are in an error
1047 // state because of a codec error, then it would be okay. Otherwise, it's 1120 // state because of a codec error, then it would be okay. Otherwise, it's
1048 // less obvious that we are exiting the error state. Since deferred errors 1121 // less obvious that we are exiting the error state. Since deferred errors
1049 // are only intended for fullscreen transitions right now, we take the more 1122 // are only intended for fullscreen transitions right now, we take the more
1050 // conservative approach and let the errors post. 1123 // conservative approach and let the errors post.
1051 // TODO(liberato): revisit this once we sort out the error state a bit more. 1124 // TODO(liberato): revisit this once we sort out the error state a bit more.
1052 1125
1053 // When codec is not in error state we can quickly reset (internally calls 1126 // When codec is not in error state we can quickly reset (internally calls
1054 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs 1127 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs
1055 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new 1128 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new
1056 // one. The full reconfigure is much slower and may cause visible freezing if 1129 // one. The full reconfigure is much slower and may cause visible freezing if
1057 // done mid-stream. 1130 // done mid-stream.
1058 if (state_ == NO_ERROR && 1131 if (!did_codec_error_happen &&
1059 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { 1132 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
1060 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; 1133 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush).";
1061 media_codec_->Reset(); 1134 media_codec_->Reset();
1062 // Since we just flushed all the output buffers, make sure that nothing is 1135 // Since we just flushed all the output buffers, make sure that nothing is
1063 // using them. 1136 // using them.
1064 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); 1137 strategy_->CodecChanged(media_codec_.get());
1065 } else { 1138 } else {
1066 DVLOG(3) << __FUNCTION__ 1139 DVLOG(3) << __FUNCTION__
1067 << " Deleting the MediaCodec and creating a new one."; 1140 << " Deleting the MediaCodec and creating a new one.";
1068 g_avda_timer.Pointer()->StopTimer(this); 1141 g_avda_timer.Pointer()->StopTimer(this);
1069 // Changing the codec will also notify the strategy to forget about any 1142 // Changing the codec will also notify the strategy to forget about any
1070 // output buffers it has currently. 1143 // output buffers it has currently.
1071 state_ = NO_ERROR;
1072 ConfigureMediaCodecAsynchronously(); 1144 ConfigureMediaCodecAsynchronously();
1073 } 1145 }
1146
1147 if (!done_cb.is_null())
1148 done_cb.Run();
1074 } 1149 }
1075 1150
1076 void AndroidVideoDecodeAccelerator::Reset() { 1151 void AndroidVideoDecodeAccelerator::Reset() {
1152 DVLOG(1) << __FUNCTION__;
1077 DCHECK(thread_checker_.CalledOnValidThread()); 1153 DCHECK(thread_checker_.CalledOnValidThread());
1078 TRACE_EVENT0("media", "AVDA::Reset"); 1154 TRACE_EVENT0("media", "AVDA::Reset");
1079 1155
1080 while (!pending_bitstream_buffers_.empty()) { 1156 while (!pending_bitstream_buffers_.empty()) {
1081 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id(); 1157 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id();
1082 pending_bitstream_buffers_.pop(); 1158 pending_bitstream_buffers_.pop();
1083 1159
1084 if (bitstream_buffer_id != -1) { 1160 if (bitstream_buffer_id != -1) {
1085 base::MessageLoop::current()->PostTask( 1161 base::MessageLoop::current()->PostTask(
1086 FROM_HERE, 1162 FROM_HERE,
1087 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 1163 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
1088 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); 1164 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
1089 } 1165 }
1090 } 1166 }
1091 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); 1167 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
1092 bitstreams_notified_in_advance_.clear(); 1168 bitstreams_notified_in_advance_.clear();
1093 1169
1094 // Any error that is waiting to post can be ignored. 1170 // Any error that is waiting to post can be ignored.
1095 error_sequence_token_++; 1171 error_sequence_token_++;
1096 1172
1097 ResetCodecState(); 1173 DCHECK(strategy_);
1174 strategy_->ReleaseCodecBuffers(output_picture_buffers_);
1098 1175
1099 // Note that |media_codec_| might not yet be ready, but we can still post 1176 // Some VP8 files require complete MediaCodec drain before we can call
1100 // this anyway. 1177 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1101 base::MessageLoop::current()->PostTask( 1178 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1102 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 1179 // Postpone ResetCodecState() after the drain.
1103 weak_this_factory_.GetWeakPtr())); 1180 StartCodecDrain(DRAIN_FOR_RESET);
1181 } else {
1182 ResetCodecState(media::BindToCurrentLoop(
1183 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1184 weak_this_factory_.GetWeakPtr())));
1185 }
1104 } 1186 }
1105 1187
1106 void AndroidVideoDecodeAccelerator::Destroy() { 1188 void AndroidVideoDecodeAccelerator::Destroy() {
1189 DVLOG(1) << __FUNCTION__;
1107 DCHECK(thread_checker_.CalledOnValidThread()); 1190 DCHECK(thread_checker_.CalledOnValidThread());
1108 1191
1109 bool have_context = make_context_current_cb_.Run(); 1192 bool have_context = make_context_current_cb_.Run();
1110 if (!have_context) 1193 if (!have_context)
1111 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 1194 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
1112 1195
1113 if (strategy_) 1196 if (strategy_)
1114 strategy_->Cleanup(have_context, output_picture_buffers_); 1197 strategy_->Cleanup(have_context, output_picture_buffers_);
1115 1198
1116 // If we have an OnFrameAvailable handler, tell it that we're going away. 1199 // If we have an OnFrameAvailable handler, tell it that we're going away.
1117 if (on_frame_available_handler_) { 1200 if (on_frame_available_handler_) {
1118 on_frame_available_handler_->ClearOwner(); 1201 on_frame_available_handler_->ClearOwner();
1119 on_frame_available_handler_ = nullptr; 1202 on_frame_available_handler_ = nullptr;
1120 } 1203 }
1121 1204
1205 client_ = nullptr;
1206
1207 // Some VP8 files require complete MediaCodec drain before we can call
1208 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1209 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1210 // Clear pending_bitstream_buffers_.
1211 while (!pending_bitstream_buffers_.empty())
1212 pending_bitstream_buffers_.pop();
1213
1214 // Postpone ActualDestroy after the drain.
1215 StartCodecDrain(DRAIN_FOR_DESTROY);
1216 } else {
1217 ActualDestroy();
1218 }
1219 }
1220
1221 void AndroidVideoDecodeAccelerator::ActualDestroy() {
1222 DVLOG(1) << __FUNCTION__;
1223 DCHECK(thread_checker_.CalledOnValidThread());
1224
1122 // Note that async codec construction might still be in progress. In that 1225 // Note that async codec construction might still be in progress. In that
1123 // case, the codec will be deleted when it completes once we invalidate all 1226 // case, the codec will be deleted when it completes once we invalidate all
1124 // our weak refs. 1227 // our weak refs.
1125 weak_this_factory_.InvalidateWeakPtrs(); 1228 weak_this_factory_.InvalidateWeakPtrs();
1126 if (media_codec_) { 1229 if (media_codec_) {
1127 g_avda_timer.Pointer()->StopTimer(this); 1230 g_avda_timer.Pointer()->StopTimer(this);
1128 media_codec_.reset(); 1231 media_codec_.reset();
1129 } 1232 }
1130 delete this; 1233 delete this;
1131 } 1234 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 void AndroidVideoDecodeAccelerator::OnKeyAdded() { 1321 void AndroidVideoDecodeAccelerator::OnKeyAdded() {
1219 DVLOG(1) << __FUNCTION__; 1322 DVLOG(1) << __FUNCTION__;
1220 1323
1221 if (state_ == WAITING_FOR_KEY) 1324 if (state_ == WAITING_FOR_KEY)
1222 state_ = NO_ERROR; 1325 state_ = NO_ERROR;
1223 1326
1224 DoIOTask(true); 1327 DoIOTask(true);
1225 } 1328 }
1226 1329
1227 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) { 1330 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) {
1228 client_->NotifyInitializationComplete(success); 1331 if (client_)
1332 client_->NotifyInitializationComplete(success);
1229 } 1333 }
1230 1334
1231 void AndroidVideoDecodeAccelerator::NotifyPictureReady( 1335 void AndroidVideoDecodeAccelerator::NotifyPictureReady(
1232 const media::Picture& picture) { 1336 const media::Picture& picture) {
1233 client_->PictureReady(picture); 1337 if (client_)
1338 client_->PictureReady(picture);
1234 } 1339 }
1235 1340
1236 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( 1341 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
1237 int input_buffer_id) { 1342 int input_buffer_id) {
1238 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 1343 if (client_)
1344 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
1239 } 1345 }
1240 1346
1241 void AndroidVideoDecodeAccelerator::NotifyFlushDone() { 1347 void AndroidVideoDecodeAccelerator::NotifyFlushDone() {
1242 client_->NotifyFlushDone(); 1348 if (client_)
1349 client_->NotifyFlushDone();
1243 } 1350 }
1244 1351
1245 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 1352 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
1246 client_->NotifyResetDone(); 1353 if (client_)
1354 client_->NotifyResetDone();
1247 } 1355 }
1248 1356
1249 void AndroidVideoDecodeAccelerator::NotifyError( 1357 void AndroidVideoDecodeAccelerator::NotifyError(
1250 media::VideoDecodeAccelerator::Error error, 1358 media::VideoDecodeAccelerator::Error error,
1251 int token) { 1359 int token) {
1252 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token 1360 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token
1253 << " current: " << error_sequence_token_; 1361 << " current: " << error_sequence_token_;
1254 if (token != error_sequence_token_) 1362 if (token != error_sequence_token_)
1255 return; 1363 return;
1256 1364
1257 client_->NotifyError(error); 1365 if (client_)
1366 client_->NotifyError(error);
1258 } 1367 }
1259 1368
1260 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) { 1369 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) {
1261 bool should_be_running = true; 1370 bool should_be_running = true;
1262 1371
1263 base::TimeTicks now = base::TimeTicks::Now(); 1372 base::TimeTicks now = base::TimeTicks::Now();
1264 if (!did_work && !most_recent_work_.is_null()) { 1373 if (!did_work && !most_recent_work_.is_null()) {
1265 // Make sure that we have done work recently enough, else stop the timer. 1374 // Make sure that we have done work recently enough, else stop the timer.
1266 if (now - most_recent_work_ > IdleTimerTimeOut()) { 1375 if (now - most_recent_work_ > IdleTimerTimeOut()) {
1267 most_recent_work_ = base::TimeTicks(); 1376 most_recent_work_ = base::TimeTicks();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1347 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { 1456 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) {
1348 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: 1457 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
1349 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1458 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1350 } 1459 }
1351 } 1460 }
1352 1461
1353 return capabilities; 1462 return capabilities;
1354 } 1463 }
1355 1464
1356 } // namespace content 1465 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | content/common/gpu/media/avda_codec_image.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698