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

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: Uses drain with EOS instead of abitrary delay 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 "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/trace_event/trace_event.h" 20 #include "base/trace_event/trace_event.h"
20 #include "content/common/gpu/media/android_copying_backing_strategy.h" 21 #include "content/common/gpu/media/android_copying_backing_strategy.h"
21 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h " 22 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h "
22 #include "content/common/gpu/media/avda_return_on_failure.h" 23 #include "content/common/gpu/media/avda_return_on_failure.h"
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 286
286 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator( 287 AndroidVideoDecodeAccelerator::AndroidVideoDecodeAccelerator(
287 const MakeGLContextCurrentCallback& make_context_current_cb, 288 const MakeGLContextCurrentCallback& make_context_current_cb,
288 const GetGLES2DecoderCallback& get_gles2_decoder_cb) 289 const GetGLES2DecoderCallback& get_gles2_decoder_cb)
289 : client_(NULL), 290 : client_(NULL),
290 make_context_current_cb_(make_context_current_cb), 291 make_context_current_cb_(make_context_current_cb),
291 get_gles2_decoder_cb_(get_gles2_decoder_cb), 292 get_gles2_decoder_cb_(get_gles2_decoder_cb),
292 is_encrypted_(false), 293 is_encrypted_(false),
293 state_(NO_ERROR), 294 state_(NO_ERROR),
294 picturebuffers_requested_(false), 295 picturebuffers_requested_(false),
296 drain_type_(DRAIN_TYPE_NONE),
295 media_drm_bridge_cdm_context_(nullptr), 297 media_drm_bridge_cdm_context_(nullptr),
296 cdm_registration_id_(0), 298 cdm_registration_id_(0),
297 pending_input_buf_index_(-1), 299 pending_input_buf_index_(-1),
298 error_sequence_token_(0), 300 error_sequence_token_(0),
299 defer_errors_(false), 301 defer_errors_(false),
300 deferred_initialization_pending_(false), 302 deferred_initialization_pending_(false),
301 weak_this_factory_(this) {} 303 weak_this_factory_(this) {}
302 304
303 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 305 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
304 DCHECK(thread_checker_.CalledOnValidThread()); 306 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
521 523
522 DCHECK_NE(input_buf_index, -1); 524 DCHECK_NE(input_buf_index, -1);
523 525
524 media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front(); 526 media::BitstreamBuffer bitstream_buffer = pending_bitstream_buffers_.front();
525 527
526 if (bitstream_buffer.id() == -1) { 528 if (bitstream_buffer.id() == -1) {
527 pending_bitstream_buffers_.pop(); 529 pending_bitstream_buffers_.pop();
528 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 530 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
529 pending_bitstream_buffers_.size()); 531 pending_bitstream_buffers_.size());
530 532
531 DCHECK_NE(state_, ERROR);
532 state_ = WAITING_FOR_EOS;
533 media_codec_->QueueEOS(input_buf_index); 533 media_codec_->QueueEOS(input_buf_index);
534 return true; 534 return true;
535 } 535 }
536 536
537 std::unique_ptr<SharedMemoryRegion> shm; 537 std::unique_ptr<SharedMemoryRegion> shm;
538 538
539 if (pending_input_buf_index_ == -1) { 539 if (pending_input_buf_index_ == -1) {
540 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued 540 // When |pending_input_buf_index_| is not -1, the buffer is already dequeued
541 // from MediaCodec, filled with data and bitstream_buffer.handle() is 541 // from MediaCodec, filled with data and bitstream_buffer.handle() is
542 // closed. 542 // closed.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput"); 641 TRACE_EVENT_BEGIN0("media", "AVDA::DequeueOutput");
642 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer( 642 media::MediaCodecStatus status = media_codec_->DequeueOutputBuffer(
643 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp, 643 NoWaitTimeOut(), &buf_index, &offset, &size, &presentation_timestamp,
644 &eos, NULL); 644 &eos, NULL);
645 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status, 645 TRACE_EVENT_END2("media", "AVDA::DequeueOutput", "status", status,
646 "presentation_timestamp (ms)", 646 "presentation_timestamp (ms)",
647 presentation_timestamp.InMilliseconds()); 647 presentation_timestamp.InMilliseconds());
648 648
649 switch (status) { 649 switch (status) {
650 case media::MEDIA_CODEC_ERROR: 650 case media::MEDIA_CODEC_ERROR:
651 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed."); 651 // Do not post an error if we are draining for reset. Instead, try
watk 2016/04/18 21:12:18 Remove "try" since we are unconditionally running
Tima Vaisburd 2016/04/20 01:54:19 Done.
652 // to run the drain completion callback.
653 if (IsDrainingForReset()) {
654 state_ = ERROR;
655 DCHECK(!drain_completed_cb_.is_null());
656 base::ResetAndReturn(&drain_completed_cb_).Run();
657 } else {
658 POST_ERROR(PLATFORM_FAILURE, "DequeueOutputBuffer failed.");
659 }
652 return false; 660 return false;
653 661
654 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER: 662 case media::MEDIA_CODEC_DEQUEUE_OUTPUT_AGAIN_LATER:
655 return false; 663 return false;
656 664
657 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: { 665 case media::MEDIA_CODEC_OUTPUT_FORMAT_CHANGED: {
666 if (IsDrainingForReset())
667 return true;
668
658 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) { 669 if (media_codec_->GetOutputSize(&size_) != media::MEDIA_CODEC_OK) {
659 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed."); 670 POST_ERROR(PLATFORM_FAILURE, "GetOutputSize failed.");
660 return false; 671 return false;
661 } 672 }
673
662 DVLOG(3) << __FUNCTION__ 674 DVLOG(3) << __FUNCTION__
663 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString(); 675 << " OUTPUT_FORMAT_CHANGED, new size: " << size_.ToString();
664 676
665 // Don't request picture buffers if we already have some. This avoids 677 // Don't request picture buffers if we already have some. This avoids
666 // having to dismiss the existing buffers which may actively reference 678 // having to dismiss the existing buffers which may actively reference
667 // decoded images. Breaking their connection to the decoded image will 679 // decoded images. Breaking their connection to the decoded image will
668 // cause rendering of black frames. Instead, we let the existing 680 // cause rendering of black frames. Instead, we let the existing
669 // PictureBuffers live on and we simply update their size the next time 681 // PictureBuffers live on and we simply update their size the next time
670 // they're attachted to an image of the new resolution. See the 682 // they're attachted to an image of the new resolution. See the
671 // size update in |SendDecodedFrameToClient| and https://crbug/587994. 683 // size update in |SendDecodedFrameToClient| and https://crbug/587994.
(...skipping 28 matching lines...) Expand all
700 if (eos) { 712 if (eos) {
701 DVLOG(3) << __FUNCTION__ << ": Resetting codec state after EOS"; 713 DVLOG(3) << __FUNCTION__ << ": Resetting codec state after EOS";
702 714
703 // If we were waiting for an EOS, clear the state and reset the MediaCodec 715 // If we were waiting for an EOS, clear the state and reset the MediaCodec
704 // as normal. Otherwise, enter the ERROR state which will force destruction 716 // as normal. Otherwise, enter the ERROR state which will force destruction
705 // of MediaCodec during ResetCodecState(). 717 // of MediaCodec during ResetCodecState().
706 // 718 //
707 // Some Android platforms seem to send an EOS buffer even when we're not 719 // Some Android platforms seem to send an EOS buffer even when we're not
708 // expecting it. In this case, destroy and reset the codec but don't notify 720 // expecting it. In this case, destroy and reset the codec but don't notify
709 // flush done since it violates the state machine. http://crbug.com/585959. 721 // flush done since it violates the state machine. http://crbug.com/585959.
710 const bool was_waiting_for_eos = state_ == WAITING_FOR_EOS; 722 if (drain_completed_cb_.is_null()) {
711 state_ = was_waiting_for_eos ? NO_ERROR : ERROR; 723 // Unexpected EOS.
712 724 state_ = ERROR;
713 ResetCodecState(); 725 ResetCodecState(base::Closure());
714 // |media_codec_| might still be null. 726 } else {
715 if (was_waiting_for_eos) { 727 base::ResetAndReturn(&drain_completed_cb_).Run();
716 base::MessageLoop::current()->PostTask(
717 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
718 weak_this_factory_.GetWeakPtr()));
719 } 728 }
720 return false; 729 return false;
721 } 730 }
722 731
732 if (IsDrainingForReset()) {
733 media_codec_->ReleaseOutputBuffer(buf_index, false);
734 return true;
735 }
736
723 if (!picturebuffers_requested_) { 737 if (!picturebuffers_requested_) {
724 // If, somehow, we get a decoded frame back before a FORMAT_CHANGED 738 // If, somehow, we get a decoded frame back before a FORMAT_CHANGED
725 // message, then we might not have any picture buffers to use. This 739 // message, then we might not have any picture buffers to use. This
726 // isn't supposed to happen (see EncodeDecodeTest.java#617). 740 // isn't supposed to happen (see EncodeDecodeTest.java#617).
727 // Log a metric to see how common this is. 741 // Log a metric to see how common this is.
728 RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged); 742 RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged);
729 media_codec_->ReleaseOutputBuffer(buf_index, false); 743 media_codec_->ReleaseOutputBuffer(buf_index, false);
730 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED."); 744 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED.");
731 return false; 745 return false;
732 } 746 }
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 void AndroidVideoDecodeAccelerator::DecodeBuffer( 855 void AndroidVideoDecodeAccelerator::DecodeBuffer(
842 const media::BitstreamBuffer& bitstream_buffer) { 856 const media::BitstreamBuffer& bitstream_buffer) {
843 pending_bitstream_buffers_.push(bitstream_buffer); 857 pending_bitstream_buffers_.push(bitstream_buffer);
844 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 858 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount",
845 pending_bitstream_buffers_.size()); 859 pending_bitstream_buffers_.size());
846 860
847 DoIOTask(true); 861 DoIOTask(true);
848 } 862 }
849 863
850 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { 864 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() {
851 client_->ProvidePictureBuffers(kNumPictureBuffers, 1, 865 if (client_)
852 strategy_->GetPictureBufferSize(), 866 client_->ProvidePictureBuffers(kNumPictureBuffers, 1,
853 strategy_->GetTextureTarget()); 867 strategy_->GetPictureBufferSize(),
868 strategy_->GetTextureTarget());
854 } 869 }
855 870
856 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 871 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
857 const std::vector<media::PictureBuffer>& buffers) { 872 const std::vector<media::PictureBuffer>& buffers) {
858 DCHECK(thread_checker_.CalledOnValidThread()); 873 DCHECK(thread_checker_.CalledOnValidThread());
859 DCHECK(output_picture_buffers_.empty()); 874 DCHECK(output_picture_buffers_.empty());
860 DCHECK(free_picture_ids_.empty()); 875 DCHECK(free_picture_ids_.empty());
861 876
862 if (buffers.size() < kNumPictureBuffers) { 877 if (buffers.size() < kNumPictureBuffers) {
863 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 878 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned.");
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 return; 916 return;
902 } 917 }
903 918
904 strategy_->ReuseOnePictureBuffer(i->second); 919 strategy_->ReuseOnePictureBuffer(i->second);
905 DoIOTask(true); 920 DoIOTask(true);
906 } 921 }
907 922
908 void AndroidVideoDecodeAccelerator::Flush() { 923 void AndroidVideoDecodeAccelerator::Flush() {
909 DCHECK(thread_checker_.CalledOnValidThread()); 924 DCHECK(thread_checker_.CalledOnValidThread());
910 925
911 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); 926 base::Closure notification_cb = media::BindToCurrentLoop(
927 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
928 weak_this_factory_.GetWeakPtr()));
929
930 RequestDrain(DRAIN_FOR_FLUSH,
931 base::Bind(&AndroidVideoDecodeAccelerator::ResetCodecState,
932 weak_this_factory_.GetWeakPtr(), notification_cb));
912 } 933 }
913 934
914 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { 935 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
915 DCHECK(thread_checker_.CalledOnValidThread()); 936 DCHECK(thread_checker_.CalledOnValidThread());
916 937
917 // It's probably okay just to return here, since the codec will be configured 938 // It's probably okay just to return here, since the codec will be configured
918 // asynchronously. It's unclear that any state for the new request could 939 // asynchronously. It's unclear that any state for the new request could
919 // be different, unless somebody modifies |codec_config_| while we're already 940 // be different, unless somebody modifies |codec_config_| while we're already
920 // waiting for a codec. One shouldn't do that for thread safety. 941 // waiting for a codec. One shouldn't do that for thread safety.
921 DCHECK_NE(state_, WAITING_FOR_CODEC); 942 DCHECK_NE(state_, WAITING_FOR_CODEC);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 if (!media_codec_) { 1010 if (!media_codec_) {
990 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); 1011 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
991 return; 1012 return;
992 } 1013 }
993 1014
994 state_ = NO_ERROR; 1015 state_ = NO_ERROR;
995 1016
996 ManageTimer(true); 1017 ManageTimer(true);
997 } 1018 }
998 1019
999 void AndroidVideoDecodeAccelerator::ResetCodecState() { 1020 void AndroidVideoDecodeAccelerator::RequestDrain(
watk 2016/04/18 21:12:18 IMO RequestDrain makes it sound like there's a cha
Tima Vaisburd 2016/04/20 01:54:19 Renamed to StartCodecDrain(). I have to strong pre
1021 DrainType drain_type,
1022 base::Closure drain_completed_cb) {
watk 2016/04/18 21:12:18 I'm wondering if it would be clearer to structure
Tima Vaisburd 2016/04/20 01:54:19 Yes, thank you! I tried now, and I think this way
1023 DVLOG(2) << __FUNCTION__ << " drain_type:" << drain_type;
1024
1025 // We assume that DRAIN_FOR_FLUSH and DRAIN_FOR_RESET cannot come while
1026 // another drain request is present, but DRAIN_FOR_DESTROY can.
1027 DCHECK(drain_completed_cb_.is_null() || drain_type == DRAIN_FOR_DESTROY);
1028
1029 drain_completed_cb_ = drain_completed_cb;
1030 drain_type_ = drain_type;
1031 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
watk 2016/04/18 21:12:18 If there's an EOS already queued for a DRAIN_FOR_F
Tima Vaisburd 2016/04/20 01:54:19 Done.
1032 }
1033
1034 bool AndroidVideoDecodeAccelerator::IsDrainingForReset() const {
1035 return !drain_completed_cb_.is_null() &&
1036 (drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY);
1037 }
1038
1039 void AndroidVideoDecodeAccelerator::ResetCodecState(
1040 base::Closure notification_cb) {
watk 2016/04/18 21:12:18 I would be inclined to name this consistently with
Tima Vaisburd 2016/04/20 01:54:19 Done.
1000 DCHECK(thread_checker_.CalledOnValidThread()); 1041 DCHECK(thread_checker_.CalledOnValidThread());
1001 1042
1002 // If there is already a reset in flight, then that counts. This can really 1043 // If there is already a reset in flight, then that counts. This can really
1003 // only happen if somebody calls Reset. 1044 // only happen if somebody calls Reset.
1004 if (state_ == WAITING_FOR_CODEC) 1045 if (state_ == WAITING_FOR_CODEC) {
1046 if (!notification_cb.is_null())
1047 notification_cb.Run();
1005 return; 1048 return;
1049 }
1006 1050
1007 bitstream_buffers_in_decoder_.clear(); 1051 bitstream_buffers_in_decoder_.clear();
1008 1052
1009 if (pending_input_buf_index_ != -1) { 1053 if (pending_input_buf_index_ != -1) {
1010 // The data for that index exists in the input buffer, but corresponding 1054 // The data for that index exists in the input buffer, but corresponding
1011 // shm block been deleted. Check that it is safe to flush the coec, i.e. 1055 // shm block been deleted. Check that it is safe to flush the coec, i.e.
1012 // |pending_bitstream_buffers_| is empty. 1056 // |pending_bitstream_buffers_| is empty.
1013 // TODO(timav): keep shm block for that buffer and remove this restriction. 1057 // TODO(timav): keep shm block for that buffer and remove this restriction.
1014 DCHECK(pending_bitstream_buffers_.empty()); 1058 DCHECK(pending_bitstream_buffers_.empty());
1015 pending_input_buf_index_ = -1; 1059 pending_input_buf_index_ = -1;
1016 } 1060 }
1017 1061
1018 if (state_ == WAITING_FOR_KEY) 1062 const bool did_codec_error_happen = (state_ == ERROR);
1019 state_ = NO_ERROR; 1063 state_ = NO_ERROR;
1020 1064
1021 // We might increment error_sequence_token here to cancel any delayed errors, 1065 // We might increment error_sequence_token here to cancel any delayed errors,
1022 // but right now it's unclear that it's safe to do so. If we are in an error 1066 // but right now it's unclear that it's safe to do so. If we are in an error
1023 // state because of a codec error, then it would be okay. Otherwise, it's 1067 // state because of a codec error, then it would be okay. Otherwise, it's
1024 // less obvious that we are exiting the error state. Since deferred errors 1068 // less obvious that we are exiting the error state. Since deferred errors
1025 // are only intended for fullscreen transitions right now, we take the more 1069 // are only intended for fullscreen transitions right now, we take the more
1026 // conservative approach and let the errors post. 1070 // conservative approach and let the errors post.
1027 // TODO(liberato): revisit this once we sort out the error state a bit more. 1071 // TODO(liberato): revisit this once we sort out the error state a bit more.
1028 1072
1029 // When codec is not in error state we can quickly reset (internally calls 1073 // When codec is not in error state we can quickly reset (internally calls
1030 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs 1074 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs
1031 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new 1075 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new
1032 // one. The full reconfigure is much slower and may cause visible freezing if 1076 // one. The full reconfigure is much slower and may cause visible freezing if
1033 // done mid-stream. 1077 // done mid-stream.
1034 if (state_ == NO_ERROR && 1078 if (!did_codec_error_happen &&
1035 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { 1079 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
1036 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; 1080 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush).";
1037 media_codec_->Reset(); 1081 media_codec_->Reset();
1038 // Since we just flushed all the output buffers, make sure that nothing is 1082 // Since we just flushed all the output buffers, make sure that nothing is
1039 // using them. 1083 // using them.
1040 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); 1084 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
1041 } else { 1085 } else {
1042 DVLOG(3) << __FUNCTION__ 1086 DVLOG(3) << __FUNCTION__
1043 << " Deleting the MediaCodec and creating a new one."; 1087 << " Deleting the MediaCodec and creating a new one.";
1044 g_avda_timer.Pointer()->StopTimer(this); 1088 g_avda_timer.Pointer()->StopTimer(this);
1045 // Changing the codec will also notify the strategy to forget about any 1089 // Changing the codec will also notify the strategy to forget about any
1046 // output buffers it has currently. 1090 // output buffers it has currently.
1047 state_ = NO_ERROR;
1048 ConfigureMediaCodecAsynchronously(); 1091 ConfigureMediaCodecAsynchronously();
1049 } 1092 }
1093
1094 if (!notification_cb.is_null())
1095 notification_cb.Run();
1050 } 1096 }
1051 1097
1052 void AndroidVideoDecodeAccelerator::Reset() { 1098 void AndroidVideoDecodeAccelerator::Reset() {
1099 DVLOG(1) << __FUNCTION__;
1100
1053 DCHECK(thread_checker_.CalledOnValidThread()); 1101 DCHECK(thread_checker_.CalledOnValidThread());
1054 TRACE_EVENT0("media", "AVDA::Reset"); 1102 TRACE_EVENT0("media", "AVDA::Reset");
1055 1103
1056 while (!pending_bitstream_buffers_.empty()) { 1104 while (!pending_bitstream_buffers_.empty()) {
1057 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id(); 1105 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id();
1058 pending_bitstream_buffers_.pop(); 1106 pending_bitstream_buffers_.pop();
1059 1107
1060 if (bitstream_buffer_id != -1) { 1108 if (bitstream_buffer_id != -1) {
1061 base::MessageLoop::current()->PostTask( 1109 base::MessageLoop::current()->PostTask(
1062 FROM_HERE, 1110 FROM_HERE,
1063 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 1111 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
1064 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); 1112 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
1065 } 1113 }
1066 } 1114 }
1067 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); 1115 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
1068 bitstreams_notified_in_advance_.clear(); 1116 bitstreams_notified_in_advance_.clear();
1069 1117
1070 // Any error that is waiting to post can be ignored. 1118 // Any error that is waiting to post can be ignored.
1071 error_sequence_token_++; 1119 error_sequence_token_++;
1072 1120
1073 ResetCodecState(); 1121 DCHECK(strategy_);
1122 strategy_->ReleaseCodecBuffers(output_picture_buffers_);
1074 1123
1075 // Note that |media_codec_| might not yet be ready, but we can still post 1124 base::Closure notification_cb = media::BindToCurrentLoop(
watk 2016/04/18 21:12:18 I don't think you need BindToCurrentLoop because t
Tima Vaisburd 2016/04/20 01:54:19 Removed BindToCurrentLoop. The original code alway
1076 // this anyway. 1125 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1077 base::MessageLoop::current()->PostTask( 1126 weak_this_factory_.GetWeakPtr()));
1078 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 1127
1079 weak_this_factory_.GetWeakPtr())); 1128 // Some VP8 files require complete MediaCodec drain before we can call
1129 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1130 if (codec_config_->codec_ == media::kCodecVP8) {
1131 // Postpone ResetCodecState() after the drain.
1132 RequestDrain(DRAIN_FOR_RESET,
1133 base::Bind(&AndroidVideoDecodeAccelerator::ResetCodecState,
1134 weak_this_factory_.GetWeakPtr(), notification_cb));
1135 } else {
1136 ResetCodecState(notification_cb);
1137 }
1080 } 1138 }
1081 1139
1082 void AndroidVideoDecodeAccelerator::Destroy() { 1140 void AndroidVideoDecodeAccelerator::Destroy() {
1141 DVLOG(1) << __FUNCTION__;
1142
watk 2016/04/18 21:12:18 nit: Remove empty line to keep the LOG and thread
Tima Vaisburd 2016/04/20 01:54:19 Done.
1083 DCHECK(thread_checker_.CalledOnValidThread()); 1143 DCHECK(thread_checker_.CalledOnValidThread());
1084 1144
1085 bool have_context = make_context_current_cb_.Run(); 1145 bool have_context = make_context_current_cb_.Run();
1086 if (!have_context) 1146 if (!have_context)
1087 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 1147 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
1088 1148
1089 if (strategy_) 1149 if (strategy_)
1090 strategy_->Cleanup(have_context, output_picture_buffers_); 1150 strategy_->Cleanup(have_context, output_picture_buffers_);
1091 1151
1092 // If we have an OnFrameAvailable handler, tell it that we're going away. 1152 // If we have an OnFrameAvailable handler, tell it that we're going away.
1093 if (on_frame_available_handler_) { 1153 if (on_frame_available_handler_) {
1094 on_frame_available_handler_->ClearOwner(); 1154 on_frame_available_handler_->ClearOwner();
1095 on_frame_available_handler_ = nullptr; 1155 on_frame_available_handler_ = nullptr;
1096 } 1156 }
1097 1157
1158 client_ = nullptr;
1159
1160 // Some VP8 files require complete MediaCodec drain before we can call
1161 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1162 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1163 // Clear pending_bitstream_buffers_.
1164 while (!pending_bitstream_buffers_.empty())
1165 pending_bitstream_buffers_.pop();
1166
1167 // Postpone ActualDestroy after the drain.
1168 RequestDrain(DRAIN_FOR_DESTROY,
1169 media::BindToCurrentLoop(
1170 base::Bind(&AndroidVideoDecodeAccelerator::ActualDestroy,
1171 weak_this_factory_.GetWeakPtr())));
1172 } else {
1173 ActualDestroy();
1174 }
1175 }
1176
1177 void AndroidVideoDecodeAccelerator::ActualDestroy() {
1178 DVLOG(1) << __FUNCTION__;
1098 // Note that async codec construction might still be in progress. In that 1179 // Note that async codec construction might still be in progress. In that
1099 // case, the codec will be deleted when it completes once we invalidate all 1180 // case, the codec will be deleted when it completes once we invalidate all
1100 // our weak refs. 1181 // our weak refs.
1101 weak_this_factory_.InvalidateWeakPtrs(); 1182 weak_this_factory_.InvalidateWeakPtrs();
1102 if (media_codec_) { 1183 if (media_codec_) {
1103 g_avda_timer.Pointer()->StopTimer(this); 1184 g_avda_timer.Pointer()->StopTimer(this);
1104 media_codec_.reset(); 1185 media_codec_.reset();
1105 } 1186 }
1106 delete this; 1187 delete this;
1107 } 1188 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 void AndroidVideoDecodeAccelerator::OnKeyAdded() { 1275 void AndroidVideoDecodeAccelerator::OnKeyAdded() {
1195 DVLOG(1) << __FUNCTION__; 1276 DVLOG(1) << __FUNCTION__;
1196 1277
1197 if (state_ == WAITING_FOR_KEY) 1278 if (state_ == WAITING_FOR_KEY)
1198 state_ = NO_ERROR; 1279 state_ = NO_ERROR;
1199 1280
1200 DoIOTask(true); 1281 DoIOTask(true);
1201 } 1282 }
1202 1283
1203 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) { 1284 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) {
1204 client_->NotifyInitializationComplete(success); 1285 if (client_)
1286 client_->NotifyInitializationComplete(success);
1205 } 1287 }
1206 1288
1207 void AndroidVideoDecodeAccelerator::NotifyPictureReady( 1289 void AndroidVideoDecodeAccelerator::NotifyPictureReady(
1208 const media::Picture& picture) { 1290 const media::Picture& picture) {
1209 client_->PictureReady(picture); 1291 if (client_)
1292 client_->PictureReady(picture);
1210 } 1293 }
1211 1294
1212 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( 1295 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
1213 int input_buffer_id) { 1296 int input_buffer_id) {
1214 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 1297 if (client_)
1298 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
1215 } 1299 }
1216 1300
1217 void AndroidVideoDecodeAccelerator::NotifyFlushDone() { 1301 void AndroidVideoDecodeAccelerator::NotifyFlushDone() {
1218 client_->NotifyFlushDone(); 1302 if (client_)
1303 client_->NotifyFlushDone();
1219 } 1304 }
1220 1305
1221 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 1306 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
1222 client_->NotifyResetDone(); 1307 if (client_)
1308 client_->NotifyResetDone();
1223 } 1309 }
1224 1310
1225 void AndroidVideoDecodeAccelerator::NotifyError( 1311 void AndroidVideoDecodeAccelerator::NotifyError(
1226 media::VideoDecodeAccelerator::Error error, 1312 media::VideoDecodeAccelerator::Error error,
1227 int token) { 1313 int token) {
1228 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token 1314 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token
1229 << " current: " << error_sequence_token_; 1315 << " current: " << error_sequence_token_;
1230 if (token != error_sequence_token_) 1316 if (token != error_sequence_token_)
1231 return; 1317 return;
1232 1318
1233 client_->NotifyError(error); 1319 if (client_)
1320 client_->NotifyError(error);
1234 } 1321 }
1235 1322
1236 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) { 1323 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) {
1237 bool should_be_running = true; 1324 bool should_be_running = true;
1238 1325
1239 base::TimeTicks now = base::TimeTicks::Now(); 1326 base::TimeTicks now = base::TimeTicks::Now();
1240 if (!did_work && !most_recent_work_.is_null()) { 1327 if (!did_work && !most_recent_work_.is_null()) {
1241 // Make sure that we have done work recently enough, else stop the timer. 1328 // Make sure that we have done work recently enough, else stop the timer.
1242 if (now - most_recent_work_ > IdleTimerTimeOut()) { 1329 if (now - most_recent_work_ > IdleTimerTimeOut()) {
1243 most_recent_work_ = base::TimeTicks(); 1330 most_recent_work_ = base::TimeTicks();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 media::VideoDecodeAccelerator::Capabilities:: 1408 media::VideoDecodeAccelerator::Capabilities::
1322 SUPPORTS_EXTERNAL_OUTPUT_SURFACE | 1409 SUPPORTS_EXTERNAL_OUTPUT_SURFACE |
1323 media::VideoDecodeAccelerator::Capabilities:: 1410 media::VideoDecodeAccelerator::Capabilities::
1324 SUPPORTS_DEFERRED_INITIALIZATION; 1411 SUPPORTS_DEFERRED_INITIALIZATION;
1325 } 1412 }
1326 1413
1327 return capabilities; 1414 return capabilities;
1328 } 1415 }
1329 1416
1330 } // namespace content 1417 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698