| 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" |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 | 402 |
| 403 NOTIMPLEMENTED(); | 403 NOTIMPLEMENTED(); |
| 404 NotifyCdmAttached(false); | 404 NotifyCdmAttached(false); |
| 405 | 405 |
| 406 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 406 #endif // !defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
| 407 } | 407 } |
| 408 | 408 |
| 409 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { | 409 void AndroidVideoDecodeAccelerator::DoIOTask(bool start_timer) { |
| 410 DCHECK(thread_checker_.CalledOnValidThread()); | 410 DCHECK(thread_checker_.CalledOnValidThread()); |
| 411 TRACE_EVENT0("media", "AVDA::DoIOTask"); | 411 TRACE_EVENT0("media", "AVDA::DoIOTask"); |
| 412 if (state_ == ERROR) { | 412 |
| 413 if (state_ == ERROR || state_ == PENDING_CODEC_REINITIALIZATION) |
| 413 return; | 414 return; |
| 414 } | |
| 415 | 415 |
| 416 bool did_work = QueueInput(); | 416 bool did_work = QueueInput(); |
| 417 while (DequeueOutput()) | 417 while (DequeueOutput()) |
| 418 did_work = true; | 418 did_work = true; |
| 419 | 419 |
| 420 ManageTimer(did_work || start_timer); | 420 ManageTimer(did_work || start_timer); |
| 421 } | 421 } |
| 422 | 422 |
| 423 bool AndroidVideoDecodeAccelerator::QueueInput() { | 423 bool AndroidVideoDecodeAccelerator::QueueInput() { |
| 424 DCHECK(thread_checker_.CalledOnValidThread()); | 424 DCHECK(thread_checker_.CalledOnValidThread()); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 } | 775 } |
| 776 } | 776 } |
| 777 | 777 |
| 778 void AndroidVideoDecodeAccelerator::DecodeBuffer( | 778 void AndroidVideoDecodeAccelerator::DecodeBuffer( |
| 779 const media::BitstreamBuffer& bitstream_buffer) { | 779 const media::BitstreamBuffer& bitstream_buffer) { |
| 780 pending_bitstream_buffers_.push( | 780 pending_bitstream_buffers_.push( |
| 781 std::make_pair(bitstream_buffer, base::Time::Now())); | 781 std::make_pair(bitstream_buffer, base::Time::Now())); |
| 782 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", | 782 TRACE_COUNTER1("media", "AVDA::PendingBitstreamBufferCount", |
| 783 pending_bitstream_buffers_.size()); | 783 pending_bitstream_buffers_.size()); |
| 784 | 784 |
| 785 if (state_ == PENDING_CODEC_REINITIALIZATION) { |
| 786 base::AutoReset<bool> auto_reset(&defer_errors_, true); |
| 787 if (!ConfigureMediaCodec()) { |
| 788 POST_ERROR(PLATFORM_FAILURE, "Failed to configure MediaCodec."); |
| 789 return; |
| 790 } |
| 791 state_ = NO_ERROR; |
| 792 } |
| 793 |
| 785 DoIOTask(true); | 794 DoIOTask(true); |
| 786 } | 795 } |
| 787 | 796 |
| 788 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { | 797 void AndroidVideoDecodeAccelerator::RequestPictureBuffers() { |
| 789 client_->ProvidePictureBuffers(kNumPictureBuffers, | 798 client_->ProvidePictureBuffers(kNumPictureBuffers, |
| 790 strategy_->GetPictureBufferSize(), | 799 strategy_->GetPictureBufferSize(), |
| 791 strategy_->GetTextureTarget()); | 800 strategy_->GetTextureTarget()); |
| 792 } | 801 } |
| 793 | 802 |
| 794 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( | 803 void AndroidVideoDecodeAccelerator::AssignPictureBuffers( |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 LOG(ERROR) << "Failed to create MediaCodec instance."; | 892 LOG(ERROR) << "Failed to create MediaCodec instance."; |
| 884 return false; | 893 return false; |
| 885 } | 894 } |
| 886 | 895 |
| 887 ManageTimer(true); | 896 ManageTimer(true); |
| 888 return true; | 897 return true; |
| 889 } | 898 } |
| 890 | 899 |
| 891 void AndroidVideoDecodeAccelerator::ResetCodecState() { | 900 void AndroidVideoDecodeAccelerator::ResetCodecState() { |
| 892 DCHECK(thread_checker_.CalledOnValidThread()); | 901 DCHECK(thread_checker_.CalledOnValidThread()); |
| 902 |
| 903 if (state_ == PENDING_CODEC_REINITIALIZATION) |
| 904 return |
| 905 |
| 893 bitstream_buffers_in_decoder_.clear(); | 906 bitstream_buffers_in_decoder_.clear(); |
| 894 | |
| 895 // We don't dismiss picture buffers here since we might not get a format | |
| 896 // changed message to re-request them, such as during a seek. In that case, | |
| 897 // we want to reuse the existing buffers. However, we're about to invalidate | |
| 898 // all the output buffers, so we must be sure that the strategy no longer | |
| 899 // refers to them. | |
| 900 | |
| 901 if (pending_input_buf_index_ != -1) { | 907 if (pending_input_buf_index_ != -1) { |
| 902 // The data for that index exists in the input buffer, but corresponding | 908 // The data for that index exists in the input buffer, but corresponding |
| 903 // shm block been deleted. Check that it is safe to flush the coec, i.e. | 909 // shm block been deleted. Check that it is safe to flush the coec, i.e. |
| 904 // |pending_bitstream_buffers_| is empty. | 910 // |pending_bitstream_buffers_| is empty. |
| 905 // TODO(timav): keep shm block for that buffer and remove this restriction. | 911 // TODO(timav): keep shm block for that buffer and remove this restriction. |
| 906 DCHECK(pending_bitstream_buffers_.empty()); | 912 DCHECK(pending_bitstream_buffers_.empty()); |
| 907 pending_input_buf_index_ = -1; | 913 pending_input_buf_index_ = -1; |
| 908 } | 914 } |
| 909 | 915 |
| 910 if (state_ == WAITING_FOR_KEY) | 916 // We don't dismiss picture buffers here since we might not get a format |
| 911 state_ = NO_ERROR; | 917 // changed message to re-request them, such as during a seek. In that case, |
| 918 // we want to reuse the existing buffers. However, we're about to invalidate |
| 919 // all the output buffers, so we must be sure that the strategy no longer |
| 920 // refers to them. |
| 912 | 921 |
| 913 // We might increment error_sequence_token here to cancel any delayed errors, | 922 // We might increment error_sequence_token here to cancel any delayed errors, |
| 914 // but right now it's unclear that it's safe to do so. If we are in an error | 923 // but right now it's unclear that it's safe to do so. If we are in an error |
| 915 // state because of a codec error, then it would be okay. Otherwise, it's | 924 // state because of a codec error, then it would be okay. Otherwise, it's |
| 916 // less obvious that we are exiting the error state. Since deferred errors | 925 // less obvious that we are exiting the error state. Since deferred errors |
| 917 // are only intended for fullscreen transitions right now, we take the more | 926 // are only intended for fullscreen transitions right now, we take the more |
| 918 // conservative approach and let the errors post. | 927 // conservative approach and let the errors post. |
| 919 // TODO(liberato): revisit this once we sort out the error state a bit more. | 928 // TODO(liberato): revisit this once we sort out the error state a bit more. |
| 920 | 929 |
| 921 // When codec is not in error state we can quickly reset (internally calls | 930 // When codec is not in error state we can quickly reset (internally calls |
| 922 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs | 931 // flush()) for JB-MR2 and beyond. Prior to JB-MR2, flush() had several bugs |
| 923 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new | 932 // (b/8125974, b/8347958) so we must delete the MediaCodec and create a new |
| 924 // one. The full reconfigure is much slower and may cause visible freezing if | 933 // one. The full reconfigure is much slower and may cause visible freezing if |
| 925 // done mid-stream. | 934 // done mid-stream. |
| 926 if (state_ == NO_ERROR && | 935 if (state_ != ERROR && |
| 927 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { | 936 base::android::BuildInfo::GetInstance()->sdk_int() >= 18) { |
| 928 DVLOG(3) << __FUNCTION__ << " Doing fast MediaCodec reset (flush)."; | 937 DVLOG(3) << __FUNCTION__ << ": flushing the MediaCodec."; |
| 929 media_codec_->Reset(); | 938 media_codec_->Reset(); |
| 930 // Since we just flushed all the output buffers, make sure that nothing is | 939 state_ = NO_ERROR; |
| 931 // using them. | |
| 932 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); | |
| 933 } else { | 940 } else { |
| 934 DVLOG(3) << __FUNCTION__ | 941 DVLOG(3) << __FUNCTION__ << ": deleting the MediaCodec."; |
| 935 << " Deleting the MediaCodec and creating a new one."; | |
| 936 g_avda_timer.Pointer()->StopTimer(this); | |
| 937 media_codec_.reset(); | 942 media_codec_.reset(); |
| 938 // Changing the codec will also notify the strategy to forget about any | 943 // The MediaCodec will be initialized lazily on the next Decode(). |
| 939 // output buffers it has currently. | 944 // TODO(liberato): After asynchronous MediaCodec initialization is |
| 940 state_ = NO_ERROR; | 945 // implemented, we should choose to eagerly reinitialize the MediaCodec when |
| 941 if (!ConfigureMediaCodec()) | 946 // we know a Decode() call is coming soon anyway. |
| 942 POST_ERROR(PLATFORM_FAILURE, "Failed to create MediaCodec."); | 947 state_ = PENDING_CODEC_REINITIALIZATION; |
| 943 } | 948 } |
| 949 |
| 950 // Notify the strategy that the MediaCodec changed because any output buffers |
| 951 // it owns are now invalid. |
| 952 strategy_->CodecChanged(media_codec_.get(), output_picture_buffers_); |
| 953 g_avda_timer.Pointer()->StopTimer(this); |
| 944 } | 954 } |
| 945 | 955 |
| 946 void AndroidVideoDecodeAccelerator::DismissPictureBuffers() { | 956 void AndroidVideoDecodeAccelerator::DismissPictureBuffers() { |
| 947 DCHECK(thread_checker_.CalledOnValidThread()); | 957 DCHECK(thread_checker_.CalledOnValidThread()); |
| 948 DVLOG(3) << __FUNCTION__; | 958 DVLOG(3) << __FUNCTION__; |
| 949 | 959 |
| 950 for (const auto& pb : output_picture_buffers_) { | 960 for (const auto& pb : output_picture_buffers_) { |
| 951 strategy_->DismissOnePictureBuffer(pb.second); | 961 strategy_->DismissOnePictureBuffer(pb.second); |
| 952 client_->DismissPictureBuffer(pb.first); | 962 client_->DismissPictureBuffer(pb.first); |
| 953 dismissed_picture_ids_.insert(pb.first); | 963 dismissed_picture_ids_.insert(pb.first); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: | 1222 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: |
| 1213 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | | 1223 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | |
| 1214 media::VideoDecodeAccelerator::Capabilities:: | 1224 media::VideoDecodeAccelerator::Capabilities:: |
| 1215 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1225 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
| 1216 } | 1226 } |
| 1217 | 1227 |
| 1218 return capabilities; | 1228 return capabilities; |
| 1219 } | 1229 } |
| 1220 | 1230 |
| 1221 } // namespace content | 1231 } // namespace content |
| OLD | NEW |