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 "media/gpu/android_video_decode_accelerator.h" | 5 #include "media/gpu/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 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 | 104 |
105 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); | 105 constexpr base::TimeDelta NoWaitTimeOut = base::TimeDelta::FromMicroseconds(0); |
106 | 106 |
107 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); | 107 constexpr base::TimeDelta IdleTimerTimeOut = base::TimeDelta::FromSeconds(1); |
108 | 108 |
109 // Time between when we notice an error, and when we actually notify somebody. | 109 // Time between when we notice an error, and when we actually notify somebody. |
110 // This is to prevent codec errors caused by SurfaceView fullscreen transitions | 110 // This is to prevent codec errors caused by SurfaceView fullscreen transitions |
111 // from breaking the pipeline, if we're about to be reset anyway. | 111 // from breaking the pipeline, if we're about to be reset anyway. |
112 constexpr base::TimeDelta ErrorPostingDelay = base::TimeDelta::FromSeconds(2); | 112 constexpr base::TimeDelta ErrorPostingDelay = base::TimeDelta::FromSeconds(2); |
113 | 113 |
114 // For RecordFormatChangedMetric. | |
115 enum FormatChangedValue { | |
116 CodecInitialized = false, | |
117 MissingFormatChanged = true | |
118 }; | |
119 | |
120 inline void RecordFormatChangedMetric(FormatChangedValue value) { | |
121 UMA_HISTOGRAM_BOOLEAN("Media.AVDA.MissingFormatChanged", !!value); | |
122 } | |
123 | |
124 } // namespace | 114 } // namespace |
125 | 115 |
126 static base::LazyInstance<AVDACodecAllocator>::Leaky g_avda_codec_allocator = | 116 static base::LazyInstance<AVDACodecAllocator>::Leaky g_avda_codec_allocator = |
127 LAZY_INSTANCE_INITIALIZER; | 117 LAZY_INSTANCE_INITIALIZER; |
128 | 118 |
129 // AVDAManager manages shared resources for a number of AVDA instances. | 119 // AVDAManager manages shared resources for a number of AVDA instances. |
130 // Its responsibilities include: | 120 // Its responsibilities include: |
131 // - Starting and stopping a shared "construction" thread for instantiating and | 121 // - Starting and stopping a shared "construction" thread for instantiating and |
132 // releasing MediaCodecs. | 122 // releasing MediaCodecs. |
133 // - Detecting when a task has hung on the construction thread so AVDAs can | 123 // - Detecting when a task has hung on the construction thread so AVDAs can |
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 OnDrainCompleted(); | 738 OnDrainCompleted(); |
749 return false; | 739 return false; |
750 } | 740 } |
751 | 741 |
752 if (IsDrainingForResetOrDestroy()) { | 742 if (IsDrainingForResetOrDestroy()) { |
753 media_codec_->ReleaseOutputBuffer(buf_index, false); | 743 media_codec_->ReleaseOutputBuffer(buf_index, false); |
754 return true; | 744 return true; |
755 } | 745 } |
756 | 746 |
757 if (!picturebuffers_requested_) { | 747 if (!picturebuffers_requested_) { |
758 // If, somehow, we get a decoded frame back before a FORMAT_CHANGED | 748 // In 0.01% of playbacks MediaCodec returns a frame before FORMAT_CHANGED. |
759 // message, then we might not have any picture buffers to use. This | 749 // Occurs on JB and M. (See the Media.AVDA.MissingFormatChanged histogram.) |
760 // isn't supposed to happen (see EncodeDecodeTest.java#617). | |
761 // Log a metric to see how common this is. | |
762 RecordFormatChangedMetric(FormatChangedValue::MissingFormatChanged); | |
763 media_codec_->ReleaseOutputBuffer(buf_index, false); | 750 media_codec_->ReleaseOutputBuffer(buf_index, false); |
764 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED."); | 751 POST_ERROR(PLATFORM_FAILURE, "Dequeued buffers before FORMAT_CHANGED."); |
765 return false; | 752 return false; |
766 } | 753 } |
767 | 754 |
768 // Get the bitstream buffer id from the timestamp. | 755 // Get the bitstream buffer id from the timestamp. |
769 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); | 756 auto it = bitstream_buffers_in_decoder_.find(presentation_timestamp); |
770 | 757 |
771 if (it != bitstream_buffers_in_decoder_.end()) { | 758 if (it != bitstream_buffers_in_decoder_.end()) { |
772 const int32_t bitstream_buffer_id = it->second; | 759 const int32_t bitstream_buffer_id = it->second; |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 codec_config->csd0_, codec_config->csd1_, true, require_software_codec)); | 1039 codec_config->csd0_, codec_config->csd1_, true, require_software_codec)); |
1053 | 1040 |
1054 return codec; | 1041 return codec; |
1055 } | 1042 } |
1056 | 1043 |
1057 void AndroidVideoDecodeAccelerator::OnCodecConfigured( | 1044 void AndroidVideoDecodeAccelerator::OnCodecConfigured( |
1058 std::unique_ptr<VideoCodecBridge> media_codec) { | 1045 std::unique_ptr<VideoCodecBridge> media_codec) { |
1059 DCHECK(thread_checker_.CalledOnValidThread()); | 1046 DCHECK(thread_checker_.CalledOnValidThread()); |
1060 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); | 1047 DCHECK(state_ == WAITING_FOR_CODEC || state_ == SURFACE_DESTROYED); |
1061 | 1048 |
1062 // Record one instance of the codec being initialized. | |
1063 RecordFormatChangedMetric(FormatChangedValue::CodecInitialized); | |
1064 | |
1065 // If we are supposed to notify that initialization is complete, then do so | 1049 // If we are supposed to notify that initialization is complete, then do so |
1066 // now. Otherwise, this is a reconfiguration. | 1050 // now. Otherwise, this is a reconfiguration. |
1067 if (deferred_initialization_pending_) { | 1051 if (deferred_initialization_pending_) { |
1068 // Losing the output surface is not considered an error state, so notify | 1052 // Losing the output surface is not considered an error state, so notify |
1069 // success. The client will destroy this soon. | 1053 // success. The client will destroy this soon. |
1070 NotifyInitializationComplete(state_ == SURFACE_DESTROYED ? true | 1054 NotifyInitializationComplete(state_ == SURFACE_DESTROYED ? true |
1071 : !!media_codec); | 1055 : !!media_codec); |
1072 deferred_initialization_pending_ = false; | 1056 deferred_initialization_pending_ = false; |
1073 } | 1057 } |
1074 | 1058 |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 | 1577 |
1594 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() | 1578 bool AndroidVideoDecodeAccelerator::IsMediaCodecSoftwareDecodingForbidden() |
1595 const { | 1579 const { |
1596 // Prevent MediaCodec from using its internal software decoders when we have | 1580 // Prevent MediaCodec from using its internal software decoders when we have |
1597 // more secure and up to date versions in the renderer process. | 1581 // more secure and up to date versions in the renderer process. |
1598 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || | 1582 return !config_.is_encrypted && (codec_config_->codec_ == kCodecVP8 || |
1599 codec_config_->codec_ == kCodecVP9); | 1583 codec_config_->codec_ == kCodecVP9); |
1600 } | 1584 } |
1601 | 1585 |
1602 } // namespace media | 1586 } // namespace media |
OLD | NEW |