OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |