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

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

Issue 1862303002: Delay actual flush and reset in AVDA (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Kept OUTPUT_FORMAT_CHANGED processing while draining, rebased Created 4 years, 8 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
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <memory> 9 #include <memory>
10 10
11 #include "base/android/build_info.h" 11 #include "base/android/build_info.h"
12 #include "base/auto_reset.h" 12 #include "base/auto_reset.h"
13 #include "base/bind.h" 13 #include "base/bind.h"
14 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
15 #include "base/callback_helpers.h"
15 #include "base/command_line.h" 16 #include "base/command_line.h"
16 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
17 #include "base/logging.h" 18 #include "base/logging.h"
18 #include "base/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
19 #include "base/metrics/histogram.h" 20 #include "base/metrics/histogram.h"
20 #include "base/task_runner_util.h" 21 #include "base/task_runner_util.h"
21 #include "base/threading/thread_checker.h" 22 #include "base/threading/thread_checker.h"
22 #include "base/trace_event/trace_event.h" 23 #include "base/trace_event/trace_event.h"
23 #include "content/common/gpu/media/android_copying_backing_strategy.h" 24 #include "content/common/gpu/media/android_copying_backing_strategy.h"
24 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h " 25 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h "
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 305
305 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 306 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
306 const MakeGLContextCurrentCallback& make_context_current_cb, 307 const MakeGLContextCurrentCallback& make_context_current_cb,
307 const GetGLES2DecoderCallback& get_gles2_decoder_cb) 308 const GetGLES2DecoderCallback& get_gles2_decoder_cb)
308 : client_(NULL), 309 : client_(NULL),
309 make_context_current_cb_(make_context_current_cb), 310 make_context_current_cb_(make_context_current_cb),
310 get_gles2_decoder_cb_(get_gles2_decoder_cb), 311 get_gles2_decoder_cb_(get_gles2_decoder_cb),
311 is_encrypted_(false), 312 is_encrypted_(false),
312 state_(NO_ERROR), 313 state_(NO_ERROR),
313 picturebuffers_requested_(false), 314 picturebuffers_requested_(false),
315 drain_type_(DRAIN_TYPE_NONE),
314 media_drm_bridge_cdm_context_(nullptr), 316 media_drm_bridge_cdm_context_(nullptr),
315 cdm_registration_id_(0), 317 cdm_registration_id_(0),
316 pending_input_buf_index_(-1), 318 pending_input_buf_index_(-1),
317 error_sequence_token_(0), 319 error_sequence_token_(0),
318 defer_errors_(false), 320 defer_errors_(false),
319 deferred_initialization_pending_(false), 321 deferred_initialization_pending_(false),
320 weak_this_factory_(this) {} 322 weak_this_factory_(this) {}
321 323
322 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 324 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
323 DCHECK(thread_checker_.CalledOnValidThread()); 325 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 550
549 DCHECK_NE(input_buf_index, -1); 551 DCHECK_NE(input_buf_index, -1);
550 552
551 media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front(); 553 media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front();
552 554
553 if (bitstream_buffer.id() == -1) { 555 if (bitstream_buffer.id() == -1) {
554 pending_bitstream_buffers_.pop(); 556 pending_bitstream_buffers_.pop();
555 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 557 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
556 pending_bitstream_buffers_.size()); 558 pending_bitstream_buffers_.size());
557 559
558 DCHECK_NE(state_, ERROR);
559 state_ = WAITING_FOR_EOS;
560 media_codec_->QueueEOS(input_buf_index); 560 media_codec_->QueueEOS(input_buf_index);
561 return true; 561 return true;
562 } 562 }
563 563
564 std::unique_ptr<SharedMemoryRegion> shm; 564 std::unique_ptr<SharedMemoryRegion> shm;
565 565
566 if (pending_input_buf_index_ == -1) { 566 if (pending_input_buf_index_ == -1) {
567 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued 567 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued
568 // from MediaCodec, filled with data and bitstream_buffer.handle() is 568 // from MediaCodec, filled with data and bitstream_buffer.handle() is
569 // closed. 569 // closed.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); 668 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput");
669 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 669 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
670 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp, 670 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp,
671 &eos, NULL); 671 &eos, NULL);
672 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status, 672 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status,
673 "presentation_timestamp (ms)", 673 "presentation_timestamp (ms)",
674 presentation_timestamp.InMilliseconds()); 674 presentation_timestamp.InMilliseconds());
675 675
676 switch (status) { 676 switch (status) {
677 case media::MEDIA_CODEC_ERROR: 677 case media::MEDIA_CODEC_ERROR:
678 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); 678 // Do not post an error if we are draining for reset and destroy.
679 // Instead, run the drain completion task.
680 if (IsDrainingForResetOrDestroy()) {
681 DVLOG(1) << __FUNCTION__ << ": error while codec draining";
682 state_ = ERROR;
683 OnDrainCompleted();
684 } else {
685 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
686 }
679 return false; 687 return false;
680 688
681 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 689 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
682 return false; 690 return false;
683 691
684 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 692 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
693 // An OUTPUT_FORMAT_CHANGED is not reported after flush() if the frame
694 // size does not change. Therefore we have to keep track on the format
695 // even if draining, unless we are draining for destroy.
696 if (drain_type_ == DRAIN_FOR_DESTROY)
697 return true; // ignore
698
685 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) { 699 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) {
686 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed."); 700 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed.");
687 return false; 701 return false;
688 } 702 }
703
689 DVLOG(3) << __FUNCTION__ 704 DVLOG(3) << __FUNCTION__
690 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); 705 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
691 706
692 // Don't request picture buffers if we already have some. This avoids 707 // Don't request picture buffers if we already have some. This avoids
693 // having to dismiss the existing buffers which may actively reference 708 // having to dismiss the existing buffers which may actively reference
694 // decoded images. Breaking their connection to the decoded image will 709 // decoded images. Breaking their connection to the decoded image will
695 // cause rendering of black frames. Instead, we let the existing 710 // cause rendering of black frames. Instead, we let the existing
696 // PictureBuffers live on and we simply update their size the next time 711 // PictureBuffers live on and we simply update their size the next time
697 // they're attachted to an image of the new resolution. See the 712 // they're attachted to an image of the new resolution. See the
698 // size update in |SendDecodedFrameToClient| and https://crbug/587994. 713 // size update in |SendDecodedFrameToClient| and https://crbug/587994.
(...skipping 19 matching lines...) Expand all
718 << " size:" << size << " eos:" << eos; 733 << " size:" << size << " eos:" << eos;
719 break; 734 break;
720 735
721 default: 736 default:
722 NOTREACHED(); 737 NOTREACHED();
723 break; 738 break;
724 } 739 }
725 } while (buf_index < 0); 740 } while (buf_index < 0);
726 741
727 if (eos) { 742 if (eos) {
728 DVLOG(3) << __FUNCTION__ << ": Resetting codec state after EOS"; 743 OnDrainCompleted();
744 return false;
745 }
729 746
730 // If we were waiting for an EOS, clear the state and reset the MediaCodec 747 if (IsDrainingForResetOrDestroy()) {
731 // as normal. Otherwise, enter the ERROR state which will force destruction 748 media_codec_->ReleaseOutputBuffer(buf_index, false);
732 // of MediaCodec during ResetCodecState(). 749 return true;
733 //
734 // Some Android platforms seem to send an EOS buffer even when we're not
735 // expecting it. In this case, destroy and reset the codec but don't notify
736 // flush done since it violates the state machine. http://crbug.com/585959.
737 const bool was_waiting_for_eos = state_ == WAITING_FOR_EOS;
738 state_ = was_waiting_for_eos ? NO_ERROR : ERROR;
739
740 ResetCodecState();
741 // |media_codec_| might still be null.
742 if (was_waiting_for_eos) {
743 base::MessageLoop::current()->PostTask(
744 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
745 weak_this_factory_.GetWeakPtr()));
746 }
747 return false;
748 } 750 }
749 751
750 if (!picturebuffers_requested_) { 752 if (!picturebuffers_requested_) {
751 // If, somehow, we get a decoded frame back before a FORMAT_CHANGED 753 // If, somehow, we get a decoded frame back before a FORMAT_CHANGED
752 // message, then we might not have any picture buffers to use. This 754 // message, then we might not have any picture buffers to use. This
753 // isn't supposed to happen (see EncodeDecodeTest.java#617). 755 // isn't supposed to happen (see EncodeDecodeTest.java#617).
754 // Log a metric to see how common this is. 756 // Log a metric to see how common this is.
755 RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged); 757 RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged);
756 media_codec_->ReleaseOutputBuffer(buf_index, false); 758 media_codec_->ReleaseOutputBuffer(buf_index, false);
757 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED."); 759 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED.");
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 void AndroidVideoDecodeAccelerator::DecodeBuffer( 870 void AndroidVideoDecodeAccelerator::DecodeBuffer(
869 const media::BitstreamBuffer& bitstream_buffer) { 871 const media::BitstreamBuffer& bitstream_buffer) {
870 pending_bitstream_buffers_.push(bitstream_buffer); 872 pending_bitstream_buffers_.push(bitstream_buffer);
871 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 873 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
872 pending_bitstream_buffers_.size()); 874 pending_bitstream_buffers_.size());
873 875
874 DoIOTask(true); 876 DoIOTask(true);
875 } 877 }
876 878
877 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 879 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
878 client_->ProvidePictureBuffers(kNumPictureBuffers, 1, 880 if (client_) {
879 strategy_->GetPictureBufferSize(), 881 client_->ProvidePictureBuffers(kNumPictureBuffers, 1,
880 strategy_->GetTextureTarget()); 882 strategy_->GetPictureBufferSize(),
883 strategy_->GetTextureTarget());
884 }
881 } 885 }
882 886
883 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 887 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
884 const std::vector<media::PictureBuffer>& buffers) { 888 const std::vector<media::PictureBuffer>& buffers) {
885 DCHECK(thread_checker_.CalledOnValidThread()); 889 DCHECK(thread_checker_.CalledOnValidThread());
886 DCHECK(output_picture_buffers_.empty()); 890 DCHECK(output_picture_buffers_.empty());
887 DCHECK(free_picture_ids_.empty()); 891 DCHECK(free_picture_ids_.empty());
888 892
889 if (buffers.size() < kNumPictureBuffers) { 893 if (buffers.size() < kNumPictureBuffers) {
890 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 894 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " 930 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id "
927 << picture_buffer_id); 931 << picture_buffer_id);
928 return; 932 return;
929 } 933 }
930 934
931 strategy_->ReuseOnePictureBuffer(i->second); 935 strategy_->ReuseOnePictureBuffer(i->second);
932 DoIOTask(true); 936 DoIOTask(true);
933 } 937 }
934 938
935 void AndroidVideoDecodeAccelerator::Flush() { 939 void AndroidVideoDecodeAccelerator::Flush() {
940 DVLOG(1) << __FUNCTION__;
936 DCHECK(thread_checker_.CalledOnValidThread()); 941 DCHECK(thread_checker_.CalledOnValidThread());
937 942
938 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); 943 StartCodecDrain(DRAIN_FOR_FLUSH);
939 } 944 }
940 945
941 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { 946 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
942 DCHECK(thread_checker_.CalledOnValidThread()); 947 DCHECK(thread_checker_.CalledOnValidThread());
943 948
944 // It's probably okay just to return here, since the codec will be configured 949 // It's probably okay just to return here, since the codec will be configured
945 // asynchronously. It's unclear that any state for the new request could 950 // asynchronously. It's unclear that any state for the new request could
946 // be different, unless somebody modifies |codec_config_| while we're already 951 // be different, unless somebody modifies |codec_config_| while we're already
947 // waiting for a codec. One shouldn't do that for thread safety. 952 // waiting for a codec. One shouldn't do that for thread safety.
948 DCHECK_NE(state_, WAITING_FOR_CODEC); 953 DCHECK_NE(state_, WAITING_FOR_CODEC);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 if (!media_codec_) { 1025 if (!media_codec_) {
1021 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); 1026 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
1022 return; 1027 return;
1023 } 1028 }
1024 1029
1025 state_ = NO_ERROR; 1030 state_ = NO_ERROR;
1026 1031
1027 ManageTimer(true); 1032 ManageTimer(true);
1028 } 1033 }
1029 1034
1030 void AndroidVideoDecodeAccelerator::ResetCodecState() { 1035 void AndroidVideoDecodeAccelerator::StartCodecDrain(DrainType drain_type) {
1036 DVLOG(2) << __FUNCTION__ << " drain_type:" << drain_type;
1037 DCHECK(thread_checker_.CalledOnValidThread());
1038
1039 // We assume that DRAIN_FOR_FLUSH and DRAIN_FOR_RESET cannot come while
1040 // another drain request is present, but DRAIN_FOR_DESTROY can.
1041 DCHECK_NE(drain_type, DRAIN_TYPE_NONE);
1042 DCHECK(drain_type_ == DRAIN_TYPE_NONE || drain_type == DRAIN_FOR_DESTROY)
1043 << "Unexpected StartCodecDrain() with drain type " << drain_type
1044 << " while already draining with drain type " << drain_type_;
1045
1046 const bool enqueue_eos = drain_type_ == DRAIN_TYPE_NONE;
1047 drain_type_ = drain_type;
1048
1049 if (enqueue_eos)
1050 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
1051 }
1052
1053 bool AndroidVideoDecodeAccelerator::IsDrainingForResetOrDestroy() const {
1054 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY;
1055 }
1056
1057 void AndroidVideoDecodeAccelerator::OnDrainCompleted() {
1058 DVLOG(2) << __FUNCTION__;
1059 DCHECK(thread_checker_.CalledOnValidThread());
1060
1061 // If we were waiting for an EOS, clear the state and reset the MediaCodec
1062 // as normal. Otherwise, enter the ERROR state which will force destruction
1063 // of MediaCodec during ResetCodecState().
1064 //
1065 // Some Android platforms seem to send an EOS buffer even when we're not
1066 // expecting it. In this case, destroy and reset the codec but don't notify
1067 // flush done since it violates the state machine. http://crbug.com/585959.
1068
1069 switch (drain_type_) {
1070 case DRAIN_TYPE_NONE:
1071 // Unexpected EOS.
1072 state_ = ERROR;
1073 ResetCodecState(base::Closure());
1074 break;
1075 case DRAIN_FOR_FLUSH:
1076 ResetCodecState(media::BindToCurrentLoop(
1077 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
1078 weak_this_factory_.GetWeakPtr())));
1079 break;
1080 case DRAIN_FOR_RESET:
1081 ResetCodecState(media::BindToCurrentLoop(
1082 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1083 weak_this_factory_.GetWeakPtr())));
1084 break;
1085 case DRAIN_FOR_DESTROY:
1086 base::MessageLoop::current()->PostTask(
1087 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::ActualDestroy,
1088 weak_this_factory_.GetWeakPtr()));
1089 break;
1090 }
1091 drain_type_ = DRAIN_TYPE_NONE;
1092 }
1093
1094 void AndroidVideoDecodeAccelerator::ResetCodecState(
1095 const base::Closure& done_cb) {
1031 DCHECK(thread_checker_.CalledOnValidThread()); 1096 DCHECK(thread_checker_.CalledOnValidThread());
1032 1097
1033 // If there is already a reset in flight, then that counts. This can really 1098 // If there is already a reset in flight, then that counts. This can really
1034 // only happen if somebody calls Reset. 1099 // only happen if somebody calls Reset.
1035 if (state_ == WAITING_FOR_CODEC) 1100 if (state_ == WAITING_FOR_CODEC) {
1101 if (!done_cb.is_null())
1102 done_cb.Run();
1036 return; 1103 return;
1104 }
1037 1105
1038 bitstream_buffers_in_decoder_.clear(); 1106 bitstream_buffers_in_decoder_.clear();
1039 1107
1040 if (pending_input_buf_index_ != -1) { 1108 if (pending_input_buf_index_ != -1) {
1041 // The data for that index exists in the input buffer, but corresponding 1109 // The data for that index exists in the input buffer, but corresponding
1042 // shm block been deleted. Check that it is safe to flush the coec, i.e. 1110 // shm block been deleted. Check that it is safe to flush the coec, i.e.
1043 // |pending_bitstream_buffers_| is empty. 1111 // |pending_bitstream_buffers_| is empty.
1044 // TODO(timav): keep shm block for that buffer and remove this restriction. 1112 // TODO(timav): keep shm block for that buffer and remove this restriction.
1045 DCHECK(pending_bitstream_buffers_.empty()); 1113 DCHECK(pending_bitstream_buffers_.empty());
1046 pending_input_buf_index_ = -1; 1114 pending_input_buf_index_ = -1;
1047 } 1115 }
1048 1116
1049 if (state_ == WAITING_FOR_KEY) 1117 const bool did_codec_error_happen = state_ == ERROR;
1050 state_ = NO_ERROR; 1118 state_ = NO_ERROR;
1051 1119
1052 // We might increment error_sequence_token here to cancel any delayed errors, 1120 // We might increment error_sequence_token here to cancel any delayed errors,
1053 // but right now it's unclear that it's safe to do so. If we are in an error 1121 // but right now it's unclear that it's safe to do so. If we are in an error
1054 // state because of a codec error, then it would be okay. Otherwise, it's 1122 // state because of a codec error, then it would be okay. Otherwise, it's
1055 // less obvious that we are exiting the error state. Since deferred errors 1123 // less obvious that we are exiting the error state. Since deferred errors
1056 // are only intended for fullscreen transitions right now, we take the more 1124 // are only intended for fullscreen transitions right now, we take the more
1057 // conservative approach and let the errors post. 1125 // conservative approach and let the errors post.
1058 // TODO(liberato): revisit this once we sort out the error state a bit more. 1126 // TODO(liberato): revisit this once we sort out the error state a bit more.
1059 1127
1060 // When codec is not in error state we can quickly reset (internally calls 1128 // When codec is not in error state we can quickly reset (internally calls
1061 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs 1129 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs
1062 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new 1130 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new
1063 // one. The full reconfigure is much slower and may cause visible freezing if 1131 // one. The full reconfigure is much slower and may cause visible freezing if
1064 // done mid-stream. 1132 // done mid-stream.
1065 if (state_ == NO_ERROR && 1133 if (!did_codec_error_happen &&
1066 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { 1134 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
1067 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; 1135 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush).";
1068 media_codec_->Reset(); 1136 media_codec_->Reset();
1069 // Since we just flushed all the output buffers, make sure that nothing is 1137 // Since we just flushed all the output buffers, make sure that nothing is
1070 // using them. 1138 // using them.
1071 strategy_->CodecChanged(media_codec_.get()); 1139 strategy_->CodecChanged(media_codec_.get());
1072 } else { 1140 } else {
1073 DVLOG(3) << __FUNCTION__ 1141 DVLOG(3) << __FUNCTION__
1074 << " Deleting the MediaCodec and creating a new one."; 1142 << " Deleting the MediaCodec and creating a new one.";
1075 g_avda_timer.Pointer()->StopTimer(this); 1143 g_avda_timer.Pointer()->StopTimer(this);
1076 // Changing the codec will also notify the strategy to forget about any 1144 // Changing the codec will also notify the strategy to forget about any
1077 // output buffers it has currently. 1145 // output buffers it has currently.
1078 state_ = NO_ERROR;
1079 ConfigureMediaCodecAsynchronously(); 1146 ConfigureMediaCodecAsynchronously();
1080 } 1147 }
1148
1149 if (!done_cb.is_null())
1150 done_cb.Run();
1081 } 1151 }
1082 1152
1083 void AndroidVideoDecodeAccelerator::Reset() { 1153 void AndroidVideoDecodeAccelerator::Reset() {
1154 DVLOG(1) << __FUNCTION__;
1084 DCHECK(thread_checker_.CalledOnValidThread()); 1155 DCHECK(thread_checker_.CalledOnValidThread());
1085 TRACE_EVENT0("media", "AVDA::Reset"); 1156 TRACE_EVENT0("media", "AVDA::Reset");
1086 1157
1087 while (!pending_bitstream_buffers_.empty()) { 1158 while (!pending_bitstream_buffers_.empty()) {
1088 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id(); 1159 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id();
1089 pending_bitstream_buffers_.pop(); 1160 pending_bitstream_buffers_.pop();
1090 1161
1091 if (bitstream_buffer_id != -1) { 1162 if (bitstream_buffer_id != -1) {
1092 base::MessageLoop::current()->PostTask( 1163 base::MessageLoop::current()->PostTask(
1093 FROM_HERE, 1164 FROM_HERE,
1094 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 1165 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
1095 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); 1166 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
1096 } 1167 }
1097 } 1168 }
1098 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); 1169 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
1099 bitstreams_notified_in_advance_.clear(); 1170 bitstreams_notified_in_advance_.clear();
1100 1171
1101 // Any error that is waiting to post can be ignored. 1172 // Any error that is waiting to post can be ignored.
1102 error_sequence_token_++; 1173 error_sequence_token_++;
1103 1174
1104 ResetCodecState(); 1175 DCHECK(strategy_);
1176 strategy_->ReleaseCodecBuffers(output_picture_buffers_);
1105 1177
1106 // Note that |media_codec_| might not yet be ready, but we can still post 1178 // Some VP8 files require complete MediaCodec drain before we can call
1107 // this anyway. 1179 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1108 base::MessageLoop::current()->PostTask( 1180 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1109 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 1181 // Postpone ResetCodecState() after the drain.
1110 weak_this_factory_.GetWeakPtr())); 1182 StartCodecDrain(DRAIN_FOR_RESET);
1183 } else {
1184 ResetCodecState(media::BindToCurrentLoop(
1185 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1186 weak_this_factory_.GetWeakPtr())));
1187 }
1111 } 1188 }
1112 1189
1113 void AndroidVideoDecodeAccelerator::Destroy() { 1190 void AndroidVideoDecodeAccelerator::Destroy() {
1191 DVLOG(1) << __FUNCTION__;
1114 DCHECK(thread_checker_.CalledOnValidThread()); 1192 DCHECK(thread_checker_.CalledOnValidThread());
1115 1193
1116 bool have_context = make_context_current_cb_.Run(); 1194 bool have_context = make_context_current_cb_.Run();
1117 if (!have_context) 1195 if (!have_context)
1118 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 1196 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
1119 1197
1120 if (strategy_) 1198 if (strategy_)
1121 strategy_->Cleanup(have_context, output_picture_buffers_); 1199 strategy_->Cleanup(have_context, output_picture_buffers_);
1122 1200
1123 // If we have an OnFrameAvailable handler, tell it that we're going away. 1201 // If we have an OnFrameAvailable handler, tell it that we're going away.
1124 if (on_frame_available_handler_) { 1202 if (on_frame_available_handler_) {
1125 on_frame_available_handler_->ClearOwner(); 1203 on_frame_available_handler_->ClearOwner();
1126 on_frame_available_handler_ = nullptr; 1204 on_frame_available_handler_ = nullptr;
1127 } 1205 }
1128 1206
1207 client_ = nullptr;
1208
1209 // Some VP8 files require complete MediaCodec drain before we can call
1210 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1211 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1212 // Clear pending_bitstream_buffers_.
1213 while (!pending_bitstream_buffers_.empty())
1214 pending_bitstream_buffers_.pop();
1215
1216 // Postpone ActualDestroy after the drain.
1217 StartCodecDrain(DRAIN_FOR_DESTROY);
1218 } else {
1219 ActualDestroy();
1220 }
1221 }
1222
1223 void AndroidVideoDecodeAccelerator::ActualDestroy() {
1224 DVLOG(1) << __FUNCTION__;
1225 DCHECK(thread_checker_.CalledOnValidThread());
1226
1129 // Note that async codec construction might still be in progress. In that 1227 // Note that async codec construction might still be in progress. In that
1130 // case, the codec will be deleted when it completes once we invalidate all 1228 // case, the codec will be deleted when it completes once we invalidate all
1131 // our weak refs. 1229 // our weak refs.
1132 weak_this_factory_.InvalidateWeakPtrs(); 1230 weak_this_factory_.InvalidateWeakPtrs();
1133 if (media_codec_) { 1231 if (media_codec_) {
1134 g_avda_timer.Pointer()->StopTimer(this); 1232 g_avda_timer.Pointer()->StopTimer(this);
1135 media_codec_.reset(); 1233 media_codec_.reset();
1136 } 1234 }
1137 delete this; 1235 delete this;
1138 } 1236 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 void AndroidVideoDecodeAccelerator::OnKeyAdded() { 1323 void AndroidVideoDecodeAccelerator::OnKeyAdded() {
1226 DVLOG(1) << __FUNCTION__; 1324 DVLOG(1) << __FUNCTION__;
1227 1325
1228 if (state_ == WAITING_FOR_KEY) 1326 if (state_ == WAITING_FOR_KEY)
1229 state_ = NO_ERROR; 1327 state_ = NO_ERROR;
1230 1328
1231 DoIOTask(true); 1329 DoIOTask(true);
1232 } 1330 }
1233 1331
1234 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) { 1332 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) {
1235 client_->NotifyInitializationComplete(success); 1333 if (client_)
1334 client_->NotifyInitializationComplete(success);
1236 } 1335 }
1237 1336
1238 void AndroidVideoDecodeAccelerator::NotifyPictureReady( 1337 void AndroidVideoDecodeAccelerator::NotifyPictureReady(
1239 const media::Picture& picture) { 1338 const media::Picture& picture) {
1240 client_->PictureReady(picture); 1339 if (client_)
1340 client_->PictureReady(picture);
1241 } 1341 }
1242 1342
1243 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( 1343 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
1244 int input_buffer_id) { 1344 int input_buffer_id) {
1245 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 1345 if (client_)
1346 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
1246 } 1347 }
1247 1348
1248 void AndroidVideoDecodeAccelerator::NotifyFlushDone() { 1349 void AndroidVideoDecodeAccelerator::NotifyFlushDone() {
1249 client_->NotifyFlushDone(); 1350 if (client_)
1351 client_->NotifyFlushDone();
1250 } 1352 }
1251 1353
1252 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 1354 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
1253 client_->NotifyResetDone(); 1355 if (client_)
1356 client_->NotifyResetDone();
1254 } 1357 }
1255 1358
1256 void AndroidVideoDecodeAccelerator::NotifyError( 1359 void AndroidVideoDecodeAccelerator::NotifyError(
1257 media::VideoDecodeAccelerator::Error error, 1360 media::VideoDecodeAccelerator::Error error,
1258 int token) { 1361 int token) {
1259 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token 1362 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token
1260 << " current: " << error_sequence_token_; 1363 << " current: " << error_sequence_token_;
1261 if (token != error_sequence_token_) 1364 if (token != error_sequence_token_)
1262 return; 1365 return;
1263 1366
1264 client_->NotifyError(error); 1367 if (client_)
1368 client_->NotifyError(error);
1265 } 1369 }
1266 1370
1267 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) { 1371 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) {
1268 bool should_be_running = true; 1372 bool should_be_running = true;
1269 1373
1270 base::TimeTicks now = base::TimeTicks::Now(); 1374 base::TimeTicks now = base::TimeTicks::Now();
1271 if (!did_work && !most_recent_work_.is_null()) { 1375 if (!did_work && !most_recent_work_.is_null()) {
1272 // Make sure that we have done work recently enough, else stop the timer. 1376 // Make sure that we have done work recently enough, else stop the timer.
1273 if (now - most_recent_work_ > IdleTimerTimeOut()) { 1377 if (now - most_recent_work_ > IdleTimerTimeOut()) {
1274 most_recent_work_ = base::TimeTicks(); 1378 most_recent_work_ = base::TimeTicks();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1354 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { 1458 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) {
1355 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: 1459 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
1356 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1460 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1357 } 1461 }
1358 } 1462 }
1359 1463
1360 return capabilities; 1464 return capabilities;
1361 } 1465 }
1362 1466
1363 } // namespace content 1467 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698