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

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: Removed an empty line 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/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_)
859 strategy_->GetPictureBufferSize(), 858 client_->ProvidePictureBuffers(kNumPictureBuffers, 1,
860 strategy_->GetTextureTarget()); 859 strategy_->GetPictureBufferSize(),
860 strategy_->GetTextureTarget());
861 } 861 }
862 862
863 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( 863 void AndroidVideoDecodeAccelerator::AssignPictureBuffers(
864 const std::vector<media::PictureBuffer>& buffers) { 864 const std::vector<media::PictureBuffer>& buffers) {
865 DCHECK(thread_checker_.CalledOnValidThread()); 865 DCHECK(thread_checker_.CalledOnValidThread());
866 DCHECK(output_picture_buffers_.empty()); 866 DCHECK(output_picture_buffers_.empty());
867 DCHECK(free_picture_ids_.empty()); 867 DCHECK(free_picture_ids_.empty());
868 868
869 if (buffers.size() < kNumPictureBuffers) { 869 if (buffers.size() < kNumPictureBuffers) {
870 POST_ERROR(INVALID_ARGUMENT, "Not enough picture buffers assigned."); 870 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 " 906 POST_ERROR(PLATFORM_FAILURE, "Can't find PictureBuffer id "
907 << picture_buffer_id); 907 << picture_buffer_id);
908 return; 908 return;
909 } 909 }
910 910
911 strategy_->ReuseOnePictureBuffer(i->second); 911 strategy_->ReuseOnePictureBuffer(i->second);
912 DoIOTask(true); 912 DoIOTask(true);
913 } 913 }
914 914
915 void AndroidVideoDecodeAccelerator::Flush() { 915 void AndroidVideoDecodeAccelerator::Flush() {
916 DVLOG(1) << __FUNCTION__;
916 DCHECK(thread_checker_.CalledOnValidThread()); 917 DCHECK(thread_checker_.CalledOnValidThread());
917 918
918 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0)); 919 StartCodecDrain(DRAIN_FOR_FLUSH);
919 } 920 }
920 921
921 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() { 922 void AndroidVideoDecodeAccelerator::ConfigureMediaCodecAsynchronously() {
922 DCHECK(thread_checker_.CalledOnValidThread()); 923 DCHECK(thread_checker_.CalledOnValidThread());
923 924
924 // It's probably okay just to return here, since the codec will be configured 925 // 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 926 // asynchronously. It's unclear that any state for the new request could
926 // be different, unless somebody modifies |codec_config_| while we're already 927 // be different, unless somebody modifies |codec_config_| while we're already
927 // waiting for a codec. One shouldn't do that for thread safety. 928 // waiting for a codec. One shouldn't do that for thread safety.
928 DCHECK_NE(state_, WAITING_FOR_CODEC); 929 DCHECK_NE(state_, WAITING_FOR_CODEC);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 if (!media_codec_) { 997 if (!media_codec_) {
997 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); 998 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec.");
998 return; 999 return;
999 } 1000 }
1000 1001
1001 state_ = NO_ERROR; 1002 state_ = NO_ERROR;
1002 1003
1003 ManageTimer(true); 1004 ManageTimer(true);
1004 } 1005 }
1005 1006
1006 void AndroidVideoDecodeAccelerator::ResetCodecState() { 1007 void AndroidVideoDecodeAccelerator::StartCodecDrain(DrainType drain_type) {
watk 2016/04/20 18:13:45 Since we have thread checkers everywhere else, you
Tima Vaisburd 2016/04/20 20:07:52 Done.
1008 DVLOG(2) << __FUNCTION__ << " drain_type:" << drain_type;
1009
1010 // We assume that DRAIN_FOR_FLUSH and DRAIN_FOR_RESET cannot come while
1011 // another drain request is present, but DRAIN_FOR_DESTROY can.
1012 DCHECK(drain_type != DRAIN_TYPE_NONE);
1013 DCHECK(drain_type_ == DRAIN_TYPE_NONE || drain_type == DRAIN_FOR_DESTROY);
1014
1015 const bool enqueue_eos = (drain_type_ == DRAIN_TYPE_NONE);
1016 drain_type_ = drain_type;
1017
1018 if (enqueue_eos)
1019 DecodeBuffer(media::BitstreamBuffer(-1, base::SharedMemoryHandle(), 0));
1020 }
1021
1022 bool AndroidVideoDecodeAccelerator::IsDrainingForResetOrDestroy() const {
1023 return drain_type_ == DRAIN_FOR_RESET || drain_type_ == DRAIN_FOR_DESTROY;
1024 }
1025
1026 void AndroidVideoDecodeAccelerator::OnDrainCompleted() {
watk 2016/04/20 18:13:44 I like it! Thread checker here too.
Tima Vaisburd 2016/04/20 20:07:52 Done.
1027 DVLOG(2) << __FUNCTION__;
1028
1029 // If we were waiting for an EOS, clear the state and reset the MediaCodec
1030 // as normal. Otherwise, enter the ERROR state which will force destruction
1031 // of MediaCodec during ResetCodecState().
1032 //
1033 // Some Android platforms seem to send an EOS buffer even when we're not
1034 // expecting it. In this case, destroy and reset the codec but don't notify
1035 // flush done since it violates the state machine. http://crbug.com/585959.
1036
1037 switch (drain_type_) {
1038 case DRAIN_TYPE_NONE:
1039 // Unexpected EOS.
1040 state_ = ERROR;
1041 ResetCodecState(base::Closure());
1042 break;
1043 case DRAIN_FOR_FLUSH:
1044 ResetCodecState(
1045 base::Bind(&AndroidVideoDecodeAccelerator::NotifyFlushDone,
1046 weak_this_factory_.GetWeakPtr()));
1047 break;
1048 case DRAIN_FOR_RESET:
1049 ResetCodecState(
1050 base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1051 weak_this_factory_.GetWeakPtr()));
1052 break;
1053 case DRAIN_FOR_DESTROY:
1054 base::MessageLoop::current()->PostTask(
1055 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::ActualDestroy,
1056 weak_this_factory_.GetWeakPtr()));
1057 break;
1058 }
1059 drain_type_ = DRAIN_TYPE_NONE;
1060 }
1061
1062 void AndroidVideoDecodeAccelerator::ResetCodecState(base::Closure done_cb) {
1007 DCHECK(thread_checker_.CalledOnValidThread()); 1063 DCHECK(thread_checker_.CalledOnValidThread());
1008 1064
1009 // If there is already a reset in flight, then that counts. This can really 1065 // If there is already a reset in flight, then that counts. This can really
1010 // only happen if somebody calls Reset. 1066 // only happen if somebody calls Reset.
1011 if (state_ == WAITING_FOR_CODEC) 1067 if (state_ == WAITING_FOR_CODEC) {
1068 if (!done_cb.is_null())
1069 done_cb.Run();
1012 return; 1070 return;
1071 }
1013 1072
1014 bitstream_buffers_in_decoder_.clear(); 1073 bitstream_buffers_in_decoder_.clear();
1015 1074
1016 if (pending_input_buf_index_ != -1) { 1075 if (pending_input_buf_index_ != -1) {
1017 // The data for that index exists in the input buffer, but corresponding 1076 // 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. 1077 // shm block been deleted. Check that it is safe to flush the coec, i.e.
1019 // |pending_bitstream_buffers_| is empty. 1078 // |pending_bitstream_buffers_| is empty.
1020 // TODO(timav): keep shm block for that buffer and remove this restriction. 1079 // TODO(timav): keep shm block for that buffer and remove this restriction.
1021 DCHECK(pending_bitstream_buffers_.empty()); 1080 DCHECK(pending_bitstream_buffers_.empty());
1022 pending_input_buf_index_ = -1; 1081 pending_input_buf_index_ = -1;
1023 } 1082 }
1024 1083
1025 if (state_ == WAITING_FOR_KEY) 1084 const bool did_codec_error_happen = (state_ == ERROR);
1026 state_ = NO_ERROR; 1085 state_ = NO_ERROR;
1027 1086
1028 // We might increment error_sequence_token here to cancel any delayed errors, 1087 // 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 1088 // 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 1089 // 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 1090 // 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 1091 // are only intended for fullscreen transitions right now, we take the more
1033 // conservative approach and let the errors post. 1092 // conservative approach and let the errors post.
1034 // TODO(liberato): revisit this once we sort out the error state a bit more. 1093 // TODO(liberato): revisit this once we sort out the error state a bit more.
1035 1094
1036 // When codec is not in error state we can quickly reset (internally calls 1095 // 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 1096 // 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 1097 // (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 1098 // one. The full reconfigure is much slower and may cause visible freezing if
1040 // done mid-stream. 1099 // done mid-stream.
1041 if (state_ == NO_ERROR && 1100 if (!did_codec_error_happen &&
1042 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { 1101 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) {
1043 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; 1102 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush).";
1044 media_codec_->Reset(); 1103 media_codec_->Reset();
1045 // Since we just flushed all the output buffers, make sure that nothing is 1104 // Since we just flushed all the output buffers, make sure that nothing is
1046 // using them. 1105 // using them.
1047 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); 1106 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_);
1048 } else { 1107 } else {
1049 DVLOG(3) << __FUNCTION__ 1108 DVLOG(3) << __FUNCTION__
1050 << " Deleting the MediaCodec and creating a new one."; 1109 << " Deleting the MediaCodec and creating a new one.";
1051 g_avda_timer.Pointer()->StopTimer(this); 1110 g_avda_timer.Pointer()->StopTimer(this);
1052 // Changing the codec will also notify the strategy to forget about any 1111 // Changing the codec will also notify the strategy to forget about any
1053 // output buffers it has currently. 1112 // output buffers it has currently.
1054 state_ = NO_ERROR;
1055 ConfigureMediaCodecAsynchronously(); 1113 ConfigureMediaCodecAsynchronously();
1056 } 1114 }
1115
1116 if (!done_cb.is_null())
1117 done_cb.Run();
1057 } 1118 }
1058 1119
1059 void AndroidVideoDecodeAccelerator::Reset() { 1120 void AndroidVideoDecodeAccelerator::Reset() {
1121 DVLOG(1) << __FUNCTION__;
1122
watk 2016/04/20 18:13:45 nit: no blank line
Tima Vaisburd 2016/04/20 20:07:52 Done.
1060 DCHECK(thread_checker_.CalledOnValidThread()); 1123 DCHECK(thread_checker_.CalledOnValidThread());
1061 TRACE_EVENT0("media", "AVDA::Reset"); 1124 TRACE_EVENT0("media", "AVDA::Reset");
1062 1125
1063 while (!pending_bitstream_buffers_.empty()) { 1126 while (!pending_bitstream_buffers_.empty()) {
1064 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id(); 1127 int32_t bitstream_buffer_id = pending_bitstream_buffers_.front().id();
1065 pending_bitstream_buffers_.pop(); 1128 pending_bitstream_buffers_.pop();
1066 1129
1067 if (bitstream_buffer_id != -1) { 1130 if (bitstream_buffer_id != -1) {
1068 base::MessageLoop::current()->PostTask( 1131 base::MessageLoop::current()->PostTask(
1069 FROM_HERE, 1132 FROM_HERE,
1070 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer, 1133 base::Bind(&AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer,
1071 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id)); 1134 weak_this_factory_.GetWeakPtr(), bitstream_buffer_id));
1072 } 1135 }
1073 } 1136 }
1074 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0); 1137 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", 0);
1075 bitstreams_notified_in_advance_.clear(); 1138 bitstreams_notified_in_advance_.clear();
1076 1139
1077 // Any error that is waiting to post can be ignored. 1140 // Any error that is waiting to post can be ignored.
1078 error_sequence_token_++; 1141 error_sequence_token_++;
1079 1142
1080 ResetCodecState(); 1143 DCHECK(strategy_);
1144 strategy_->ReleaseCodecBuffers(output_picture_buffers_);
1081 1145
1082 // Note that |media_codec_| might not yet be ready, but we can still post 1146 // Some VP8 files require complete MediaCodec drain before we can call
1083 // this anyway. 1147 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1084 base::MessageLoop::current()->PostTask( 1148 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1085 FROM_HERE, base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone, 1149 // Postpone ResetCodecState() after the drain.
1086 weak_this_factory_.GetWeakPtr())); 1150 StartCodecDrain(DRAIN_FOR_RESET);
1151 } else {
1152 ResetCodecState(base::Bind(&AndroidVideoDecodeAccelerator::NotifyResetDone,
1153 weak_this_factory_.GetWeakPtr()));
1154 }
1087 } 1155 }
1088 1156
1089 void AndroidVideoDecodeAccelerator::Destroy() { 1157 void AndroidVideoDecodeAccelerator::Destroy() {
1158 DVLOG(1) << __FUNCTION__;
1090 DCHECK(thread_checker_.CalledOnValidThread()); 1159 DCHECK(thread_checker_.CalledOnValidThread());
1091 1160
1092 bool have_context = make_context_current_cb_.Run(); 1161 bool have_context = make_context_current_cb_.Run();
1093 if (!have_context) 1162 if (!have_context)
1094 LOG(WARNING) << "Failed make GL context current for Destroy, continuing."; 1163 LOG(WARNING) << "Failed make GL context current for Destroy, continuing.";
1095 1164
1096 if (strategy_) 1165 if (strategy_)
1097 strategy_->Cleanup(have_context, output_picture_buffers_); 1166 strategy_->Cleanup(have_context, output_picture_buffers_);
1098 1167
1099 // If we have an OnFrameAvailable handler, tell it that we're going away. 1168 // If we have an OnFrameAvailable handler, tell it that we're going away.
1100 if (on_frame_available_handler_) { 1169 if (on_frame_available_handler_) {
1101 on_frame_available_handler_->ClearOwner(); 1170 on_frame_available_handler_->ClearOwner();
1102 on_frame_available_handler_ = nullptr; 1171 on_frame_available_handler_ = nullptr;
1103 } 1172 }
1104 1173
1174 client_ = nullptr;
1175
1176 // Some VP8 files require complete MediaCodec drain before we can call
1177 // MediaCodec.flush() or MediaCodec.reset(). http://crbug.com/598963.
1178 if (media_codec_ && codec_config_->codec_ == media::kCodecVP8) {
1179 // Clear pending_bitstream_buffers_.
1180 while (!pending_bitstream_buffers_.empty())
1181 pending_bitstream_buffers_.pop();
1182
1183 // Postpone ActualDestroy after the drain.
1184 StartCodecDrain(DRAIN_FOR_DESTROY);
1185 } else {
1186 ActualDestroy();
1187 }
1188 }
1189
1190 void AndroidVideoDecodeAccelerator::ActualDestroy() {
1191 DVLOG(1) << __FUNCTION__;
1105 // Note that async codec construction might still be in progress. In that 1192 // 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 1193 // case, the codec will be deleted when it completes once we invalidate all
1107 // our weak refs. 1194 // our weak refs.
1108 weak_this_factory_.InvalidateWeakPtrs(); 1195 weak_this_factory_.InvalidateWeakPtrs();
1109 if (media_codec_) { 1196 if (media_codec_) {
1110 g_avda_timer.Pointer()->StopTimer(this); 1197 g_avda_timer.Pointer()->StopTimer(this);
1111 media_codec_.reset(); 1198 media_codec_.reset();
1112 } 1199 }
1113 delete this; 1200 delete this;
1114 } 1201 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1201 void AndroidVideoDecodeAccelerator::OnKeyAdded() { 1288 void AndroidVideoDecodeAccelerator::OnKeyAdded() {
1202 DVLOG(1) << __FUNCTION__; 1289 DVLOG(1) << __FUNCTION__;
1203 1290
1204 if (state_ == WAITING_FOR_KEY) 1291 if (state_ == WAITING_FOR_KEY)
1205 state_ = NO_ERROR; 1292 state_ = NO_ERROR;
1206 1293
1207 DoIOTask(true); 1294 DoIOTask(true);
1208 } 1295 }
1209 1296
1210 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) { 1297 void AndroidVideoDecodeAccelerator::NotifyInitializationComplete(bool success) {
1211 client_->NotifyInitializationComplete(success); 1298 if (client_)
1299 client_->NotifyInitializationComplete(success);
1212 } 1300 }
1213 1301
1214 void AndroidVideoDecodeAccelerator::NotifyPictureReady( 1302 void AndroidVideoDecodeAccelerator::NotifyPictureReady(
1215 const media::Picture& picture) { 1303 const media::Picture& picture) {
1216 client_->PictureReady(picture); 1304 if (client_)
1305 client_->PictureReady(picture);
1217 } 1306 }
1218 1307
1219 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( 1308 void AndroidVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer(
1220 int input_buffer_id) { 1309 int input_buffer_id) {
1221 client_->NotifyEndOfBitstreamBuffer(input_buffer_id); 1310 if (client_)
1311 client_->NotifyEndOfBitstreamBuffer(input_buffer_id);
1222 } 1312 }
1223 1313
1224 void AndroidVideoDecodeAccelerator::NotifyFlushDone() { 1314 void AndroidVideoDecodeAccelerator::NotifyFlushDone() {
1225 client_->NotifyFlushDone(); 1315 if (client_)
1316 client_->NotifyFlushDone();
1226 } 1317 }
1227 1318
1228 void AndroidVideoDecodeAccelerator::NotifyResetDone() { 1319 void AndroidVideoDecodeAccelerator::NotifyResetDone() {
1229 client_->NotifyResetDone(); 1320 if (client_)
1321 client_->NotifyResetDone();
1230 } 1322 }
1231 1323
1232 void AndroidVideoDecodeAccelerator::NotifyError( 1324 void AndroidVideoDecodeAccelerator::NotifyError(
1233 media::VideoDecodeAccelerator::Error error, 1325 media::VideoDecodeAccelerator::Error error,
1234 int token) { 1326 int token) {
1235 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token 1327 DVLOG(1) << __FUNCTION__ << ": error: " << error << " token: " << token
1236 << " current: " << error_sequence_token_; 1328 << " current: " << error_sequence_token_;
1237 if (token != error_sequence_token_) 1329 if (token != error_sequence_token_)
1238 return; 1330 return;
1239 1331
1240 client_->NotifyError(error); 1332 if (client_)
1333 client_->NotifyError(error);
1241 } 1334 }
1242 1335
1243 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) { 1336 void AndroidVideoDecodeAccelerator::ManageTimer(bool did_work) {
1244 bool should_be_running = true; 1337 bool should_be_running = true;
1245 1338
1246 base::TimeTicks now = base::TimeTicks::Now(); 1339 base::TimeTicks now = base::TimeTicks::Now();
1247 if (!did_work && !most_recent_work_.is_null()) { 1340 if (!did_work && !most_recent_work_.is_null()) {
1248 // Make sure that we have done work recently enough, else stop the timer. 1341 // Make sure that we have done work recently enough, else stop the timer.
1249 if (now - most_recent_work_ > IdleTimerTimeOut()) { 1342 if (now - most_recent_work_ > IdleTimerTimeOut()) {
1250 most_recent_work_ = base::TimeTicks(); 1343 most_recent_work_ = base::TimeTicks();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { 1423 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) {
1331 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: 1424 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::
1332 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1425 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1333 } 1426 }
1334 } 1427 }
1335 1428
1336 return capabilities; 1429 return capabilities;
1337 } 1430 }
1338 1431
1339 } // namespace content 1432 } // 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