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 |
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/callback_helpers.h" |
16 #include "base/command_line.h" | 16 #include "base/command_line.h" |
17 #include "base/lazy_instance.h" | |
18 #include "base/logging.h" | 17 #include "base/logging.h" |
19 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
20 #include "base/metrics/histogram_macros.h" | 19 #include "base/metrics/histogram_macros.h" |
21 #include "base/sys_info.h" | 20 #include "base/sys_info.h" |
22 #include "base/task_runner_util.h" | 21 #include "base/task_runner_util.h" |
23 #include "base/threading/thread.h" | 22 #include "base/threading/thread.h" |
24 #include "base/threading/thread_checker.h" | 23 #include "base/threading/thread_checker.h" |
25 #include "base/threading/thread_task_runner_handle.h" | 24 #include "base/threading/thread_task_runner_handle.h" |
26 #include "base/trace_event/trace_event.h" | 25 #include "base/trace_event/trace_event.h" |
27 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 26 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 // - Starting and stopping a shared "construction" thread for instantiating and | 122 // - Starting and stopping a shared "construction" thread for instantiating and |
124 // releasing MediaCodecs. | 123 // releasing MediaCodecs. |
125 // - Detecting when a task has hung on the construction thread so AVDAs can | 124 // - Detecting when a task has hung on the construction thread so AVDAs can |
126 // stop using it. | 125 // stop using it. |
127 // - Running a RepeatingTimer so that AVDAs can get a regular callback to | 126 // - Running a RepeatingTimer so that AVDAs can get a regular callback to |
128 // DoIOTask(). | 127 // DoIOTask(). |
129 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when | 128 // - Tracking the allocation of surfaces to AVDAs and delivering callbacks when |
130 // surfaces are released. | 129 // surfaces are released. |
131 class AVDAManager { | 130 class AVDAManager { |
132 public: | 131 public: |
| 132 AVDAManager() {} |
| 133 |
133 // Request periodic callback of |avda|->DoIOTask(). Does nothing if the | 134 // Request periodic callback of |avda|->DoIOTask(). Does nothing if the |
134 // instance is already registered and the timer started. The first request | 135 // instance is already registered and the timer started. The first request |
135 // will start the repeating timer on an interval of DecodePollDelay. | 136 // will start the repeating timer on an interval of DecodePollDelay. |
136 void StartTimer(AndroidVideoDecodeAccelerator* avda) { | 137 void StartTimer(AndroidVideoDecodeAccelerator* avda) { |
137 DCHECK(thread_checker_.CalledOnValidThread()); | 138 DCHECK(thread_checker_.CalledOnValidThread()); |
138 | 139 |
139 timer_avda_instances_.insert(avda); | 140 timer_avda_instances_.insert(avda); |
140 | 141 |
141 // If the timer is running, StopTimer() might have been called earlier, if | 142 // If the timer is running, StopTimer() might have been called earlier, if |
142 // so remove the instance from the pending erasures. | 143 // so remove the instance from the pending erasures. |
(...skipping 16 matching lines...) Expand all Loading... |
159 pending_erase_.insert(avda); | 160 pending_erase_.insert(avda); |
160 return; | 161 return; |
161 } | 162 } |
162 | 163 |
163 timer_avda_instances_.erase(avda); | 164 timer_avda_instances_.erase(avda); |
164 if (timer_avda_instances_.empty()) | 165 if (timer_avda_instances_.empty()) |
165 io_timer_.Stop(); | 166 io_timer_.Stop(); |
166 } | 167 } |
167 | 168 |
168 private: | 169 private: |
169 friend struct base::DefaultLazyInstanceTraits<AVDAManager>; | 170 ~AVDAManager() = delete; |
170 | |
171 AVDAManager() {} | |
172 ~AVDAManager() { NOTREACHED(); } | |
173 | 171 |
174 void RunTimer() { | 172 void RunTimer() { |
175 { | 173 { |
176 // Call out to all AVDA instances, some of which may attempt to remove | 174 // Call out to all AVDA instances, some of which may attempt to remove |
177 // themselves from the list during this operation; those removals will be | 175 // themselves from the list during this operation; those removals will be |
178 // deferred until after all iterations are complete. | 176 // deferred until after all iterations are complete. |
179 base::AutoReset<bool> scoper(&timer_running_, true); | 177 base::AutoReset<bool> scoper(&timer_running_, true); |
180 for (auto* avda : timer_avda_instances_) | 178 for (auto* avda : timer_avda_instances_) |
181 avda->DoIOTask(false); | 179 avda->DoIOTask(false); |
182 } | 180 } |
(...skipping 16 matching lines...) Expand all Loading... |
199 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; | 197 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; |
200 | 198 |
201 // Repeating timer responsible for draining pending IO to the codecs. | 199 // Repeating timer responsible for draining pending IO to the codecs. |
202 base::RepeatingTimer io_timer_; | 200 base::RepeatingTimer io_timer_; |
203 | 201 |
204 base::ThreadChecker thread_checker_; | 202 base::ThreadChecker thread_checker_; |
205 | 203 |
206 DISALLOW_COPY_AND_ASSIGN(AVDAManager); | 204 DISALLOW_COPY_AND_ASSIGN(AVDAManager); |
207 }; | 205 }; |
208 | 206 |
209 static base::LazyInstance<AVDAManager>::Leaky g_avda_manager = | 207 static AVDAManager* GetManager() { |
210 LAZY_INSTANCE_INITIALIZER; | 208 static AVDAManager* manager = new AVDAManager(); |
| 209 return manager; |
| 210 } |
211 | 211 |
212 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( | 212 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( |
213 const BitstreamBuffer& bitstream_buffer) | 213 const BitstreamBuffer& bitstream_buffer) |
214 : buffer(bitstream_buffer) { | 214 : buffer(bitstream_buffer) { |
215 if (buffer.id() != -1) | 215 if (buffer.id() != -1) |
216 memory.reset(new SharedMemoryRegion(buffer, true)); | 216 memory.reset(new SharedMemoryRegion(buffer, true)); |
217 } | 217 } |
218 | 218 |
219 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( | 219 AndroidVideoDecodeAccelerator::BitstreamRecord::BitstreamRecord( |
220 BitstreamRecord&& other) | 220 BitstreamRecord&& other) |
(...skipping 15 matching lines...) Expand all Loading... |
236 pending_input_buf_index_(-1), | 236 pending_input_buf_index_(-1), |
237 during_initialize_(false), | 237 during_initialize_(false), |
238 deferred_initialization_pending_(false), | 238 deferred_initialization_pending_(false), |
239 codec_needs_reset_(false), | 239 codec_needs_reset_(false), |
240 defer_surface_creation_(false), | 240 defer_surface_creation_(false), |
241 last_release_task_type_(TaskType::AUTO_CODEC), | 241 last_release_task_type_(TaskType::AUTO_CODEC), |
242 weak_this_factory_(this) {} | 242 weak_this_factory_(this) {} |
243 | 243 |
244 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 244 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
245 DCHECK(thread_checker_.CalledOnValidThread()); | 245 DCHECK(thread_checker_.CalledOnValidThread()); |
246 g_avda_manager.Get().StopTimer(this); | 246 GetManager()->StopTimer(this); |
247 AVDACodecAllocator::Instance()->StopThread(this); | 247 AVDACodecAllocator::Instance()->StopThread(this); |
248 | 248 |
249 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 249 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
250 if (!media_drm_bridge_cdm_context_) | 250 if (!media_drm_bridge_cdm_context_) |
251 return; | 251 return; |
252 | 252 |
253 DCHECK(cdm_registration_id_); | 253 DCHECK(cdm_registration_id_); |
254 | 254 |
255 // Cancel previously registered callback (if any). | 255 // Cancel previously registered callback (if any). |
256 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( | 256 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( |
(...skipping 860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 // Flush the codec if possible, or create a new one if not. | 1117 // Flush the codec if possible, or create a new one if not. |
1118 if (!did_codec_error_happen && | 1118 if (!did_codec_error_happen && |
1119 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { | 1119 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
1120 DVLOG(3) << __func__ << " Flushing MediaCodec."; | 1120 DVLOG(3) << __func__ << " Flushing MediaCodec."; |
1121 media_codec_->Flush(); | 1121 media_codec_->Flush(); |
1122 // Since we just flushed all the output buffers, make sure that nothing is | 1122 // Since we just flushed all the output buffers, make sure that nothing is |
1123 // using them. | 1123 // using them. |
1124 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1124 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
1125 } else { | 1125 } else { |
1126 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; | 1126 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; |
1127 g_avda_manager.Get().StopTimer(this); | 1127 GetManager()->StopTimer(this); |
1128 ConfigureMediaCodecAsynchronously(); | 1128 ConfigureMediaCodecAsynchronously(); |
1129 } | 1129 } |
1130 } | 1130 } |
1131 | 1131 |
1132 void AndroidVideoDecodeAccelerator::Reset() { | 1132 void AndroidVideoDecodeAccelerator::Reset() { |
1133 DVLOG(1) << __func__; | 1133 DVLOG(1) << __func__; |
1134 DCHECK(thread_checker_.CalledOnValidThread()); | 1134 DCHECK(thread_checker_.CalledOnValidThread()); |
1135 TRACE_EVENT0("media", "AVDA::Reset"); | 1135 TRACE_EVENT0("media", "AVDA::Reset"); |
1136 | 1136 |
1137 if (defer_surface_creation_) { | 1137 if (defer_surface_creation_) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 } | 1191 } |
1192 | 1192 |
1193 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1193 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
1194 DVLOG(1) << __func__; | 1194 DVLOG(1) << __func__; |
1195 DCHECK(thread_checker_.CalledOnValidThread()); | 1195 DCHECK(thread_checker_.CalledOnValidThread()); |
1196 | 1196 |
1197 // 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 |
1198 // 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 |
1199 // our weak refs. | 1199 // our weak refs. |
1200 weak_this_factory_.InvalidateWeakPtrs(); | 1200 weak_this_factory_.InvalidateWeakPtrs(); |
1201 g_avda_manager.Get().StopTimer(this); | 1201 GetManager()->StopTimer(this); |
1202 ReleaseCodec(); | 1202 ReleaseCodec(); |
1203 | 1203 |
1204 // We no longer care about |surface_id|, in case we did before. It's okay | 1204 // We no longer care about |surface_id|, in case we did before. It's okay |
1205 // if we have no surface and/or weren't the owner or a waiter. | 1205 // if we have no surface and/or weren't the owner or a waiter. |
1206 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); | 1206 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); |
1207 | 1207 |
1208 // Hop the SurfaceTexture release call through the task runner used last time | 1208 // Hop the SurfaceTexture release call through the task runner used last time |
1209 // we released a codec. This ensures that we release the surface texture after | 1209 // we released a codec. This ensures that we release the surface texture after |
1210 // the codec it's attached to (if any) is released. It's not sufficient to use | 1210 // the codec it's attached to (if any) is released. It's not sufficient to use |
1211 // |codec_config_->task_type| because that might have changed since we | 1211 // |codec_config_->task_type| because that might have changed since we |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 // Make sure that we have done work recently enough, else stop the timer. | 1414 // Make sure that we have done work recently enough, else stop the timer. |
1415 if (now - most_recent_work_ > IdleTimerTimeOut) { | 1415 if (now - most_recent_work_ > IdleTimerTimeOut) { |
1416 most_recent_work_ = base::TimeTicks(); | 1416 most_recent_work_ = base::TimeTicks(); |
1417 should_be_running = false; | 1417 should_be_running = false; |
1418 } | 1418 } |
1419 } else { | 1419 } else { |
1420 most_recent_work_ = now; | 1420 most_recent_work_ = now; |
1421 } | 1421 } |
1422 | 1422 |
1423 if (should_be_running) | 1423 if (should_be_running) |
1424 g_avda_manager.Get().StartTimer(this); | 1424 GetManager()->StartTimer(this); |
1425 else | 1425 else |
1426 g_avda_manager.Get().StopTimer(this); | 1426 GetManager()->StopTimer(this); |
1427 } | 1427 } |
1428 | 1428 |
1429 // static | 1429 // static |
1430 VideoDecodeAccelerator::Capabilities | 1430 VideoDecodeAccelerator::Capabilities |
1431 AndroidVideoDecodeAccelerator::GetCapabilities( | 1431 AndroidVideoDecodeAccelerator::GetCapabilities( |
1432 const gpu::GpuPreferences& gpu_preferences) { | 1432 const gpu::GpuPreferences& gpu_preferences) { |
1433 Capabilities capabilities; | 1433 Capabilities capabilities; |
1434 SupportedProfiles& profiles = capabilities.supported_profiles; | 1434 SupportedProfiles& profiles = capabilities.supported_profiles; |
1435 | 1435 |
1436 if (MediaCodecUtil::IsVp8DecoderAvailable()) { | 1436 if (MediaCodecUtil::IsVp8DecoderAvailable()) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 if (!media_codec_) | 1593 if (!media_codec_) |
1594 return; | 1594 return; |
1595 | 1595 |
1596 picture_buffer_manager_.CodecChanged(nullptr); | 1596 picture_buffer_manager_.CodecChanged(nullptr); |
1597 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 1597 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
1598 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | 1598 std::move(media_codec_), codec_config_->task_type, config_.surface_id); |
1599 last_release_task_type_ = codec_config_->task_type; | 1599 last_release_task_type_ = codec_config_->task_type; |
1600 } | 1600 } |
1601 | 1601 |
1602 } // namespace media | 1602 } // namespace media |
OLD | NEW |