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

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: Notifications are now set with BindToCurrentLoop() 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
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/trace_event/trace_event.h" 22 #include "base/trace_event/trace_event.h"
22 #include "content/common/gpu/media/android_copying_backing_strategy.h" 23 #include "content/common/gpu/media/android_copying_backing_strategy.h"
23 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h " 24 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h "
24 #include "content/common/gpu/media/avda_return_on_failure.h" 25 #include "content/common/gpu/media/avda_return_on_failure.h"
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 288
288 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 289 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
289 const MakeGLContextCurrentCallback& make_context_current_cb, 290 const MakeGLContextCurrentCallback& make_context_current_cb,
290 const GetGLES2DecoderCallback& get_gles2_decoder_cb) 291 const GetGLES2DecoderCallback& get_gles2_decoder_cb)
291 : client_(NULL), 292 : client_(NULL),
292 make_context_current_cb_(make_context_current_cb), 293 make_context_current_cb_(make_context_current_cb),
293 get_gles2_decoder_cb_(get_gles2_decoder_cb), 294 get_gles2_decoder_cb_(get_gles2_decoder_cb),
294 is_encrypted_(false), 295 is_encrypted_(false),
295 state_(NO_ERROR), 296 state_(NO_ERROR),
296 picturebuffers_requested_(false), 297 picturebuffers_requested_(false),
298 drain_type_(DRAIN_TYPE_NONE),
297 media_drm_bridge_cdm_context_(nullptr), 299 media_drm_bridge_cdm_context_(nullptr),
298 cdm_registration_id_(0), 300 cdm_registration_id_(0),
299 pending_input_buf_index_(-1), 301 pending_input_buf_index_(-1),
300 error_sequence_token_(0), 302 error_sequence_token_(0),
301 defer_errors_(false), 303 defer_errors_(false),
302 deferred_initialization_pending_(false), 304 deferred_initialization_pending_(false),
303 weak_this_factory_(this) {} 305 weak_this_factory_(this) {}
304 306
305 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 307 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
306 DCHECK(thread_checker_.CalledOnValidThread()); 308 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 530
529 DCHECK_NE(input_buf_index, -1); 531 DCHECK_NE(input_buf_index, -1);
530 532
531 media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front(); 533 media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front();
532 534
533 if (bitstream_buffer.id() == -1) { 535 if (bitstream_buffer.id() == -1) {
534 pending_bitstream_buffers_.pop(); 536 pending_bitstream_buffers_.pop();
535 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 537 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
536 pending_bitstream_buffers_.size()); 538 pending_bitstream_buffers_.size());
537 539
538 DCHECK_NE(state_, ERROR);
539 state_ = WAITING_FOR_EOS;
540 media_codec_->QueueEOS(input_buf_index); 540 media_codec_->QueueEOS(input_buf_index);
541 return true; 541 return true;
542 } 542 }
543 543
544 std::unique_ptr<SharedMemoryRegion> shm; 544 std::unique_ptr<SharedMemoryRegion> shm;
545 545
546 if (pending_input_buf_index_ == -1) { 546 if (pending_input_buf_index_ == -1) {
547 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued 547 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued
548 // from MediaCodec, filled with data and bitstream_buffer.handle() is 548 // from MediaCodec, filled with data and bitstream_buffer.handle() is
549 // closed. 549 // closed.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); 648 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput");
649 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 649 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
650 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp, 650 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp,
651 &eos, NULL); 651 &eos, NULL);
652 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status, 652 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status,
653 "presentation_timestamp (ms)", 653 "presentation_timestamp (ms)",
654 presentation_timestamp.InMilliseconds()); 654 presentation_timestamp.InMilliseconds());
655 655
656 switch (status) { 656 switch (status) {
657 case media::MEDIA_CODEC_ERROR: 657 case media::MEDIA_CODEC_ERROR:
658 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); 658 // Do not post an error if we are draining for reset and destroy.
659 // Instead, run the drain completion task.
660 if (IsDrainingForResetOrDestroy()) {
661 DVLOG(1) << __FUNCTION__ << ": error while codec draining";
662 state_ = ERROR;
663 OnDrainCompleted();
664 } else {
665 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
666 }
659 return false; 667 return false;
660 668
661 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 669 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
662 return false; 670 return false;
663 671
664 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 672 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
673 if (IsDrainingForResetOrDestroy())
674 return true; // ignore
675
665 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) { 676 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) {
666 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed."); 677 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed.");
667 return false; 678 return false;
668 } 679 }
680
669 DVLOG(3) << __FUNCTION__ 681 DVLOG(3) << __FUNCTION__
670 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); 682 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
671 683
672 // Don't request picture buffers if we already have some. This avoids 684 // Don't request picture buffers if we already have some. This avoids
673 // having to dismiss the existing buffers which may actively reference 685 // having to dismiss the existing buffers which may actively reference
674 // decoded images. Breaking their connection to the decoded image will 686 // decoded images. Breaking their connection to the decoded image will
675 // cause rendering of black frames. Instead, we let the existing 687 // cause rendering of black frames. Instead, we let the existing
676 // PictureBuffers live on and we simply update their size the next time 688 // PictureBuffers live on and we simply update their size the next time
677 // they're attachted to an image of the new resolution. See the 689 // they're attachted to an image of the new resolution. See the
678 // size update in |SendDecodedFrameToClient| and https://crbug/587994. 690 // size update in |SendDecodedFrameToClient| and https://crbug/587994.
(...skipping 19 matching lines...) Expand all
698 << " size:" << size << " eos:" << eos; 710 << " size:" << size << " eos:" << eos;
699 break; 711 break;
700 712
701 default: 713 default:
702 NOTREACHED(); 714 NOTREACHED();
703 break; 715 break;
704 } 716 }
705 } while (buf_index < 0); 717 } while (buf_index < 0);
706 718
707 if (eos) { 719 if (eos) {
708 DVLOG(3) << __FUNCTION__ << ": Resetting codec state after EOS"; 720 OnDrainCompleted();
721 return false;
722 }
709 723
710 // If we were waiting for an EOS, clear the state and reset the MediaCodec 724 if (IsDrainingForResetOrDestroy()) {
711 // as normal. Otherwise, enter the ERROR state which will force destruction 725 media_codec_->ReleaseOutputBuffer(buf_index, false);
712 // of MediaCodec during ResetCodecState(). 726 return true;
713 //
714 // Some Android platforms seem to send an EOS buffer even when we're not
715 // expecting it. In this case, destroy and reset the codec but don't notify
716 // flush done since it violates the state machine. http://crbug.com/585959.
717 const bool was_waiting_for_eos = state_ == WAITING_FOR_EOS;
718 state_ = was_waiting_for_eos ? NO_ERROR : ERROR;
719
720 ResetCodecState();
721 // |media_codec_| might still be null.
722 if (was_waiting_for_eos) {
723 base::MessageLoop::current()->PostTask(
724 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
725 weak_this_factory_.GetWeakPtr()));
726 }
727 return false;
728 } 727 }
729 728
730 if (!picturebuffers_requested_) { 729 if (!picturebuffers_requested_) {
731 // If, somehow, we get a decoded frame back before a FORMAT_CHANGED 730 // If, somehow, we get a decoded frame back before a FORMAT_CHANGED
732 // message, then we might not have any picture buffers to use. This 731 // message, then we might not have any picture buffers to use. This
733 // isn't supposed to happen (see EncodeDecodeTest.java#617). 732 // isn't supposed to happen (see EncodeDecodeTest.java#617).
734 // Log a metric to see how common this is. 733 // Log a metric to see how common this is.
735 RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged); 734 RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged);
736 media_codec_->ReleaseOutputBuffer(buf_index, false); 735 media_codec_->ReleaseOutputBuffer(buf_index, false);
737 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED."); 736 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED.");
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 void AndroidVideoDecodeAccelerator::DecodeBuffer( 847 void AndroidVideoDecodeAccelerator::DecodeBuffer(
849 const media::BitstreamBuffer& bitstream_buffer) { 848 const media::BitstreamBuffer& bitstream_buffer) {
850 pending_bitstream_buffers_.push(bitstream_buffer); 849 pending_bitstream_buffers_.push(bitstream_buffer);
851 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 850 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
852 pending_bitstream_buffers_.size()); 851 pending_bitstream_buffers_.size());
853 852
854 DoIOTask(true); 853 DoIOTask(true);
855 } 854 }
856 855
857 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 856 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
858 client_->ProvidePictureBuffers(kNumPictureBuffers, 1, 857 if (client_) {
DaleCurtis 2016/04/21 00:16:07 Why this?
Tima Vaisburd 2016/04/21 00:28:45 See below.
859 strategy_->GetPictureBufferSize(), 858 client_->ProvidePictureBuffers(kNumPictureBuffers, 1,
860 strategy_->GetTextureTarget()); 859 strategy_->GetPictureBufferSize(),
860 strategy_->GetTextureTarget());
861 }
861 } 862 }
862 863
863 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 864 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
864 const std::vector<media::PictureBuffer>& buffers) { 865 const std::vector<media::PictureBuffer>& buffers) {
865 DCHECK(thread_checker_.CalledOnValidThread()); 866 DCHECK(thread_checker_.CalledOnValidThread());
866 DCHECK(output_picture_buffers_.empty()); 867 DCHECK(output_picture_buffers_.empty());
867 DCHECK(free_picture_ids_.empty()); 868 DCHECK(free_picture_ids_.empty());
868 869
869 if (buffers.size() < kNumPictureBuffers) { 870 if (buffers.size() < kNumPictureBuffers) {
870 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 871 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id " 907 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id "
907 << picture_buffer_id); 908 << picture_buffer_id);
908 return; 909 return;
909 } 910 }
910 911
911 strategy_->ReuseOnePictureBuffer(i->second); 912 strategy_->ReuseOnePictureBuffer(i->second);
912 DoIOTask(true); 913 DoIOTask(true);
913 } 914 }
914 915
915 void AndroidVideoDecodeAccelerator::Flush() { 916 void AndroidVideoDecodeAccelerator::Flush() {
917 DVLOG(1) << __FUNCTION__;
916 DCHECK(thread_checker_.CalledOnValidThread()); 918 DCHECK(thread_checker_.CalledOnValidThread());
917 919
918 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); 920 StartCodecDrain(DRAIN_FOR_FLUSH);
919 } 921 }
920 922
921 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { 923 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
922 DCHECK(thread_checker_.CalledOnValidThread()); 924 DCHECK(thread_checker_.CalledOnValidThread());
923 925
924 // It's probably okay just to return here, since the codec will be configured 926 // It's probably okay just to return here, since the codec will be configured
925 // asynchronously. It's unclear that any state for the new request could 927 // asynchronously. It's unclear that any state for the new request could
926 // be different, unless somebody modifies |codec_config_| while we're already 928 // be different, unless somebody modifies |codec_config_| while we're already
927 // waiting for a codec. One shouldn't do that for thread safety. 929 // waiting for a codec. One shouldn't do that for thread safety.
928 DCHECK_NE(state_, WAITING_FOR_CODEC); 930 DCHECK_NE(state_, WAITING_FOR_CODEC);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 if (!media_codec_) { 998 if (!media_codec_) {
997 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); 999 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
998 return; 1000 return;
999 } 1001 }
1000 1002
1001 state_ = NO_ERROR; 1003 state_ = NO_ERROR;
1002 1004
1003 ManageTimer(true); 1005 ManageTimer(true);
1004 } 1006 }
1005 1007
1006 void AndroidVideoDecodeAccelerator::ResetCodecState() { 1008 void AndroidVideoDecodeAccelerator::StartCodecDrain(DrainType drain_type) {
1009 DVLOG(2) << __FUNCTION__ << " drain_type:" << drain_type;
1010 DCHECK(thread_checker_.CalledOnValidThread());
1011
1012 // We assume that DRAIN_FOR_FLUSH and DRAIN_FOR_RESET cannot come while
1013 // another drain request is present, but DRAIN_FOR_DESTROY can.
1014 DCHECK(drain_type != DRAIN_TYPE_NONE);
DaleCurtis 2016/04/21 00:16:07 DCHECK_NE
Tima Vaisburd 2016/04/21 21:38:22 Done.
1015 DCHECK(drain_type_ == DRAIN_TYPE_NONE || drain_type == DRAIN_FOR_DESTROY);
DaleCurtis 2016/04/21 00:16:07 add << drain_type_ print so this DCHECK will print
Tima Vaisburd 2016/04/21 21:38:22 Done.
1016
1017 const bool enqueue_eos = (drain_type_ == DRAIN_TYPE_NONE);
DaleCurtis 2016/04/21 00:16:07 No unnecessary parens.
Tima Vaisburd 2016/04/21 21:38:21 Done.
1018 drain_type_ = drain_type;
1019
1020 if (enqueue_eos)
1021 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
1022 }
1023
1024 bool AndroidVideoDecodeAccelerator::IsDrainingForResetOrDestroy() const {
1025 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY;
1026 }
1027
1028 void AndroidVideoDecodeAccelerator::OnDrainCompleted() {
1029 DVLOG(2) << __FUNCTION__;
1030 DCHECK(thread_checker_.CalledOnValidThread());
1031
1032 // If we were waiting for an EOS, clear the state and reset the MediaCodec
1033 // as normal. Otherwise, enter the ERROR state which will force destruction
1034 // of MediaCodec during ResetCodecState().
1035 //
1036 // Some Android platforms seem to send an EOS buffer even when we're not
1037 // expecting it. In this case, destroy and reset the codec but don't notify
1038 // flush done since it violates the state machine. http://crbug.com/585959.
1039
1040 switch (drain_type_) {
1041 case DRAIN_TYPE_NONE:
1042 // Unexpected EOS.
1043 state_ = ERROR;
1044 ResetCodecState(base::Closure());
1045 break;
1046 case DRAIN_FOR_FLUSH:
1047 ResetCodecState(media::BindToCurrentLoop(
1048 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
1049 weak_this_factory_.GetWeakPtr())));
1050 break;
1051 case DRAIN_FOR_RESET:
1052 ResetCodecState(media::BindToCurrentLoop(
1053 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1054 weak_this_factory_.GetWeakPtr())));
1055 break;
1056 case DRAIN_FOR_DESTROY:
1057 base::MessageLoop::current()->PostTask(
1058 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::ActualDestroy,
1059 weak_this_factory_.GetWeakPtr()));
1060 break;
1061 }
1062 drain_type_ = DRAIN_TYPE_NONE;
1063 }
1064
1065 void AndroidVideoDecodeAccelerator::ResetCodecState(base::Closure done_cb) {
1007 DCHECK(thread_checker_.CalledOnValidThread()); 1066 DCHECK(thread_checker_.CalledOnValidThread());
1008 1067
1009 // If there is already a reset in flight, then that counts. This can really 1068 // If there is already a reset in flight, then that counts. This can really
1010 // only happen if somebody calls Reset. 1069 // only happen if somebody calls Reset.
1011 if (state_ == WAITING_FOR_CODEC) 1070 if (state_ == WAITING_FOR_CODEC) {
1071 if (!done_cb.is_null())
1072 done_cb.Run();
1012 return; 1073 return;
1074 }
1013 1075
1014 bitstream_buffers_in_decoder_.clear(); 1076 bitstream_buffers_in_decoder_.clear();
1015 1077
1016 if (pending_input_buf_index_ != -1) { 1078 if (pending_input_buf_index_ != -1) {
1017 // The data for that index exists in the input buffer, but corresponding 1079 // The data for that index exists in the input buffer, but corresponding
1018 // shm block been deleted. Check that it is safe to flush the coec, i.e. 1080 // shm block been deleted. Check that it is safe to flush the coec, i.e.
1019 // |pending_bitstream_buffers_| is empty. 1081 // |pending_bitstream_buffers_| is empty.
1020 // TODO(timav): keep shm block for that buffer and remove this restriction. 1082 // TODO(timav): keep shm block for that buffer and remove this restriction.
1021 DCHECK(pending_bitstream_buffers_.empty()); 1083 DCHECK(pending_bitstream_buffers_.empty());
1022 pending_input_buf_index_ = -1; 1084 pending_input_buf_index_ = -1;
1023 } 1085 }
1024 1086
1025 if (state_ == WAITING_FOR_KEY) 1087 const bool did_codec_error_happen = (state_ == ERROR);
DaleCurtis 2016/04/21 00:16:07 No unnecessary parens.
Tima Vaisburd 2016/04/21 21:38:22 Done.
1026 state_ = NO_ERROR; 1088 state_ = NO_ERROR;
1027 1089
1028 // We might increment error_sequence_token here to cancel any delayed errors, 1090 // We might increment error_sequence_token here to cancel any delayed errors,
1029 // but right now it's unclear that it's safe to do so. If we are in an error 1091 // but right now it's unclear that it's safe to do so. If we are in an error
1030 // state because of a codec error, then it would be okay. Otherwise, it's 1092 // state because of a codec error, then it would be okay. Otherwise, it's
1031 // less obvious that we are exiting the error state. Since deferred errors 1093 // less obvious that we are exiting the error state. Since deferred errors
1032 // are only intended for fullscreen transitions right now, we take the more 1094 // are only intended for fullscreen transitions right now, we take the more
1033 // conservative approach and let the errors post. 1095 // conservative approach and let the errors post.
1034 // TODO(liberato): revisit this once we sort out the error state a bit more. 1096 // TODO(liberato): revisit this once we sort out the error state a bit more.
1035 1097
1036 // When codec is not in error state we can quickly reset (internally calls 1098 // When codec is not in error state we can quickly reset (internally calls
1037 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs 1099 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs
1038 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new 1100 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new
1039 // one. The full reconfigure is much slower and may cause visible freezing if 1101 // one. The full reconfigure is much slower and may cause visible freezing if
1040 // done mid-stream. 1102 // done mid-stream.
1041 if (state_ == NO_ERROR && 1103 if (!did_codec_error_happen &&
1042 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { 1104 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
1043 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; 1105 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush).";
1044 media_codec_->Reset(); 1106 media_codec_->Reset();
1045 // Since we just flushed all the output buffers, make sure that nothing is 1107 // Since we just flushed all the output buffers, make sure that nothing is
1046 // using them. 1108 // using them.
1047 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); 1109 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
1048 } else { 1110 } else {
1049 DVLOG(3) << __FUNCTION__ 1111 DVLOG(3) << __FUNCTION__
1050 << " Deleting the MediaCodec and creating a new one."; 1112 << " Deleting the MediaCodec and creating a new one.";
1051 g_avda_timer.Pointer()->StopTimer(this); 1113 g_avda_timer.Pointer()->StopTimer(this);
1052 // Changing the codec will also notify the strategy to forget about any 1114 // Changing the codec will also notify the strategy to forget about any
1053 // output buffers it has currently. 1115 // output buffers it has currently.
1054 state_ = NO_ERROR;
1055 ConfigureMediaCodecAsynchronously(); 1116 ConfigureMediaCodecAsynchronously();
1056 } 1117 }
1118
1119 if (!done_cb.is_null())
1120 done_cb.Run();
1057 } 1121 }
1058 1122
1059 void AndroidVideoDecodeAccelerator::Reset() { 1123 void AndroidVideoDecodeAccelerator::Reset() {
1124 DVLOG(1) << __FUNCTION__;
1060 DCHECK(thread_checker_.CalledOnValidThread()); 1125 DCHECK(thread_checker_.CalledOnValidThread());
1061 TRACE_EVENT0("media", "AVDA::Reset"); 1126 TRACE_EVENT0("media", "AVDA::Reset");
1062 1127
1063 while (!pending_bitstream_buffers_.empty()) { 1128 while (!pending_bitstream_buffers_.empty()) {
1064 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id(); 1129 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id();
1065 pending_bitstream_buffers_.pop(); 1130 pending_bitstream_buffers_.pop();
1066 1131
1067 if (bitstream_buffer_id != -1) { 1132 if (bitstream_buffer_id != -1) {
1068 base::MessageLoop::current()->PostTask( 1133 base::MessageLoop::current()->PostTask(
1069 FROM_HERE, 1134 FROM_HERE,
1070 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 1135 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
1071 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); 1136 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
1072 } 1137 }
1073 } 1138 }
1074 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); 1139 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
1075 bitstreams_notified_in_advance_.clear(); 1140 bitstreams_notified_in_advance_.clear();
1076 1141
1077 // Any error that is waiting to post can be ignored. 1142 // Any error that is waiting to post can be ignored.
1078 error_sequence_token_++; 1143 error_sequence_token_++;
1079 1144
1080 ResetCodecState(); 1145 DCHECK(strategy_);
DaleCurtis 2016/04/21 00:16:07 Don't think this can every be null?
Tima Vaisburd 2016/04/21 21:38:22 As far as I understand |strategy_| can be null onl
1146 strategy_->ReleaseCodecBuffers(output_picture_buffers_);
DaleCurtis 2016/04/21 00:16:07 Did we decide to do this for all codecs and not ju
Tima Vaisburd 2016/04/21 00:28:45 No, we have not, but I went ahead myself because I
1081 1147
1082 // Note that |media_codec_| might not yet be ready, but we can still post 1148 // Some VP8 files require complete MediaCodec drain before we can call
1083 // this anyway. 1149 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1084 base::MessageLoop::current()->PostTask( 1150 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1085 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 1151 // Postpone ResetCodecState() after the drain.
1086 weak_this_factory_.GetWeakPtr())); 1152 StartCodecDrain(DRAIN_FOR_RESET);
1153 } else {
1154 ResetCodecState(media::BindToCurrentLoop(
1155 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1156 weak_this_factory_.GetWeakPtr())));
1157 }
1087 } 1158 }
1088 1159
1089 void AndroidVideoDecodeAccelerator::Destroy() { 1160 void AndroidVideoDecodeAccelerator::Destroy() {
1161 DVLOG(1) << __FUNCTION__;
1090 DCHECK(thread_checker_.CalledOnValidThread()); 1162 DCHECK(thread_checker_.CalledOnValidThread());
1091 1163
1092 bool have_context = make_context_current_cb_.Run(); 1164 bool have_context = make_context_current_cb_.Run();
1093 if (!have_context) 1165 if (!have_context)
1094 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 1166 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
1095 1167
1096 if (strategy_) 1168 if (strategy_)
1097 strategy_->Cleanup(have_context, output_picture_buffers_); 1169 strategy_->Cleanup(have_context, output_picture_buffers_);
1098 1170
1099 // If we have an OnFrameAvailable handler, tell it that we're going away. 1171 // If we have an OnFrameAvailable handler, tell it that we're going away.
1100 if (on_frame_available_handler_) { 1172 if (on_frame_available_handler_) {
1101 on_frame_available_handler_->ClearOwner(); 1173 on_frame_available_handler_->ClearOwner();
1102 on_frame_available_handler_ = nullptr; 1174 on_frame_available_handler_ = nullptr;
1103 } 1175 }
1104 1176
1177 client_ = nullptr;
DaleCurtis 2016/04/21 00:16:07 Despite clearing this, none of the nullptr checks
Tima Vaisburd 2016/04/21 00:28:45 Yes, I think I did. Before this change I observed
DaleCurtis 2016/04/21 00:32:36 I see. It's risky to invalidate the weakptrs and c
1178
1179 // Some VP8 files require complete MediaCodec drain before we can call
1180 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1181 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1182 // Clear pending_bitstream_buffers_.
1183 while (!pending_bitstream_buffers_.empty())
1184 pending_bitstream_buffers_.pop();
1185
1186 // Postpone ActualDestroy after the drain.
1187 StartCodecDrain(DRAIN_FOR_DESTROY);
1188 } else {
1189 ActualDestroy();
1190 }
1191 }
1192
1193 void AndroidVideoDecodeAccelerator::ActualDestroy() {
1194 DVLOG(1) << __FUNCTION__;
1195 DCHECK(thread_checker_.CalledOnValidThread());
1196
1105 // Note that async codec construction might still be in progress. In that 1197 // Note that async codec construction might still be in progress. In that
1106 // case, the codec will be deleted when it completes once we invalidate all 1198 // case, the codec will be deleted when it completes once we invalidate all
1107 // our weak refs. 1199 // our weak refs.
1108 weak_this_factory_.InvalidateWeakPtrs(); 1200 weak_this_factory_.InvalidateWeakPtrs();
1109 if (media_codec_) { 1201 if (media_codec_) {
1110 g_avda_timer.Pointer()->StopTimer(this); 1202 g_avda_timer.Pointer()->StopTimer(this);
1111 media_codec_.reset(); 1203 media_codec_.reset();
1112 } 1204 }
1113 delete this; 1205 delete this;
1114 } 1206 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 void AndroidVideoDecodeAccelerator::OnKeyAdded() { 1293 void AndroidVideoDecodeAccelerator::OnKeyAdded() {
1202 DVLOG(1) << __FUNCTION__; 1294 DVLOG(1) << __FUNCTION__;
1203 1295
1204 if (state_ == WAITING_FOR_KEY) 1296 if (state_ == WAITING_FOR_KEY)
1205 state_ = NO_ERROR; 1297 state_ = NO_ERROR;
1206 1298
1207 DoIOTask(true); 1299 DoIOTask(true);
1208 } 1300 }
1209 1301
1210 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) { 1302 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) {
1211 client_->NotifyInitializationComplete(success); 1303 if (client_)
1304 client_->NotifyInitializationComplete(success);
1212 } 1305 }
1213 1306
1214 void AndroidVideoDecodeAccelerator::NotifyPictureReady( 1307 void AndroidVideoDecodeAccelerator::NotifyPictureReady(
1215 const media::Picture& picture) { 1308 const media::Picture& picture) {
1216 client_->PictureReady(picture); 1309 if (client_)
1310 client_->PictureReady(picture);
1217 } 1311 }
1218 1312
1219 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( 1313 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
1220 int input_buffer_id) { 1314 int input_buffer_id) {
1221 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 1315 if (client_)
1316 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
1222 } 1317 }
1223 1318
1224 void AndroidVideoDecodeAccelerator::NotifyFlushDone() { 1319 void AndroidVideoDecodeAccelerator::NotifyFlushDone() {
1225 client_->NotifyFlushDone(); 1320 if (client_)
1321 client_->NotifyFlushDone();
1226 } 1322 }
1227 1323
1228 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 1324 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
1229 client_->NotifyResetDone(); 1325 if (client_)
1326 client_->NotifyResetDone();
1230 } 1327 }
1231 1328
1232 void AndroidVideoDecodeAccelerator::NotifyError( 1329 void AndroidVideoDecodeAccelerator::NotifyError(
1233 media::VideoDecodeAccelerator::Error error, 1330 media::VideoDecodeAccelerator::Error error,
1234 int token) { 1331 int token) {
1235 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token 1332 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token
1236 << " current: " << error_sequence_token_; 1333 << " current: " << error_sequence_token_;
1237 if (token != error_sequence_token_) 1334 if (token != error_sequence_token_)
1238 return; 1335 return;
1239 1336
1240 client_->NotifyError(error); 1337 if (client_)
1338 client_->NotifyError(error);
1241 } 1339 }
1242 1340
1243 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) { 1341 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) {
1244 bool should_be_running = true; 1342 bool should_be_running = true;
1245 1343
1246 base::TimeTicks now = base::TimeTicks::Now(); 1344 base::TimeTicks now = base::TimeTicks::Now();
1247 if (!did_work && !most_recent_work_.is_null()) { 1345 if (!did_work && !most_recent_work_.is_null()) {
1248 // Make sure that we have done work recently enough, else stop the timer. 1346 // Make sure that we have done work recently enough, else stop the timer.
1249 if (now - most_recent_work_ > IdleTimerTimeOut()) { 1347 if (now - most_recent_work_ > IdleTimerTimeOut()) {
1250 most_recent_work_ = base::TimeTicks(); 1348 most_recent_work_ = base::TimeTicks();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { 1428 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) {
1331 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: 1429 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
1332 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1430 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1333 } 1431 }
1334 } 1432 }
1335 1433
1336 return capabilities; 1434 return capabilities;
1337 } 1435 }
1338 1436
1339 } // namespace content 1437 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698