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