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 | |
171 AVDAManager() {} | |
172 ~AVDAManager() { NOTREACHED(); } | 170 ~AVDAManager() { NOTREACHED(); } |
Mark Mentovai
2017/01/31 21:33:56
You can switch this to the “= delete” form too.
DaleCurtis
2017/01/31 22:04:33
Done.
| |
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 14 matching lines...) Expand all Loading... | |
235 cdm_registration_id_(0), | 235 cdm_registration_id_(0), |
236 pending_input_buf_index_(-1), | 236 pending_input_buf_index_(-1), |
237 deferred_initialization_pending_(false), | 237 deferred_initialization_pending_(false), |
238 codec_needs_reset_(false), | 238 codec_needs_reset_(false), |
239 defer_surface_creation_(false), | 239 defer_surface_creation_(false), |
240 last_release_task_type_(TaskType::AUTO_CODEC), | 240 last_release_task_type_(TaskType::AUTO_CODEC), |
241 weak_this_factory_(this) {} | 241 weak_this_factory_(this) {} |
242 | 242 |
243 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { | 243 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { |
244 DCHECK(thread_checker_.CalledOnValidThread()); | 244 DCHECK(thread_checker_.CalledOnValidThread()); |
245 g_avda_manager.Get().StopTimer(this); | 245 GetManager()->StopTimer(this); |
246 AVDACodecAllocator::Instance()->StopThread(this); | 246 AVDACodecAllocator::Instance()->StopThread(this); |
247 | 247 |
248 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) | 248 #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) |
249 if (!media_drm_bridge_cdm_context_) | 249 if (!media_drm_bridge_cdm_context_) |
250 return; | 250 return; |
251 | 251 |
252 DCHECK(cdm_registration_id_); | 252 DCHECK(cdm_registration_id_); |
253 | 253 |
254 // Cancel previously registered callback (if any). | 254 // Cancel previously registered callback (if any). |
255 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( | 255 media_drm_bridge_cdm_context_->SetMediaCryptoReadyCB( |
(...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1058 // Flush the codec if possible, or create a new one if not. | 1058 // Flush the codec if possible, or create a new one if not. |
1059 if (!did_codec_error_happen && | 1059 if (!did_codec_error_happen && |
1060 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { | 1060 !MediaCodecUtil::CodecNeedsFlushWorkaround(media_codec_.get())) { |
1061 DVLOG(3) << __func__ << " Flushing MediaCodec."; | 1061 DVLOG(3) << __func__ << " Flushing MediaCodec."; |
1062 media_codec_->Flush(); | 1062 media_codec_->Flush(); |
1063 // Since we just flushed all the output buffers, make sure that nothing is | 1063 // Since we just flushed all the output buffers, make sure that nothing is |
1064 // using them. | 1064 // using them. |
1065 picture_buffer_manager_.CodecChanged(media_codec_.get()); | 1065 picture_buffer_manager_.CodecChanged(media_codec_.get()); |
1066 } else { | 1066 } else { |
1067 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; | 1067 DVLOG(3) << __func__ << " Deleting the MediaCodec and creating a new one."; |
1068 g_avda_manager.Get().StopTimer(this); | 1068 GetManager()->StopTimer(this); |
1069 ConfigureMediaCodecAsynchronously(); | 1069 ConfigureMediaCodecAsynchronously(); |
1070 } | 1070 } |
1071 } | 1071 } |
1072 | 1072 |
1073 void AndroidVideoDecodeAccelerator::Reset() { | 1073 void AndroidVideoDecodeAccelerator::Reset() { |
1074 DVLOG(1) << __func__; | 1074 DVLOG(1) << __func__; |
1075 DCHECK(thread_checker_.CalledOnValidThread()); | 1075 DCHECK(thread_checker_.CalledOnValidThread()); |
1076 TRACE_EVENT0("media", "AVDA::Reset"); | 1076 TRACE_EVENT0("media", "AVDA::Reset"); |
1077 | 1077 |
1078 if (defer_surface_creation_) { | 1078 if (defer_surface_creation_) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1132 } | 1132 } |
1133 | 1133 |
1134 void AndroidVideoDecodeAccelerator::ActualDestroy() { | 1134 void AndroidVideoDecodeAccelerator::ActualDestroy() { |
1135 DVLOG(1) << __func__; | 1135 DVLOG(1) << __func__; |
1136 DCHECK(thread_checker_.CalledOnValidThread()); | 1136 DCHECK(thread_checker_.CalledOnValidThread()); |
1137 | 1137 |
1138 // Note that async codec construction might still be in progress. In that | 1138 // Note that async codec construction might still be in progress. In that |
1139 // case, the codec will be deleted when it completes once we invalidate all | 1139 // case, the codec will be deleted when it completes once we invalidate all |
1140 // our weak refs. | 1140 // our weak refs. |
1141 weak_this_factory_.InvalidateWeakPtrs(); | 1141 weak_this_factory_.InvalidateWeakPtrs(); |
1142 g_avda_manager.Get().StopTimer(this); | 1142 GetManager()->StopTimer(this); |
1143 ReleaseCodec(); | 1143 ReleaseCodec(); |
1144 | 1144 |
1145 // We no longer care about |surface_id|, in case we did before. It's okay | 1145 // We no longer care about |surface_id|, in case we did before. It's okay |
1146 // if we have no surface and/or weren't the owner or a waiter. | 1146 // if we have no surface and/or weren't the owner or a waiter. |
1147 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); | 1147 AVDACodecAllocator::Instance()->DeallocateSurface(this, config_.surface_id); |
1148 | 1148 |
1149 // Hop the SurfaceTexture release call through the task runner used last time | 1149 // Hop the SurfaceTexture release call through the task runner used last time |
1150 // we released a codec. This ensures that we release the surface texture after | 1150 // we released a codec. This ensures that we release the surface texture after |
1151 // the codec it's attached to (if any) is released. It's not sufficient to use | 1151 // the codec it's attached to (if any) is released. It's not sufficient to use |
1152 // |codec_config_->task_type| because that might have changed since we | 1152 // |codec_config_->task_type| because that might have changed since we |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1327 // Make sure that we have done work recently enough, else stop the timer. | 1327 // Make sure that we have done work recently enough, else stop the timer. |
1328 if (now - most_recent_work_ > IdleTimerTimeOut) { | 1328 if (now - most_recent_work_ > IdleTimerTimeOut) { |
1329 most_recent_work_ = base::TimeTicks(); | 1329 most_recent_work_ = base::TimeTicks(); |
1330 should_be_running = false; | 1330 should_be_running = false; |
1331 } | 1331 } |
1332 } else { | 1332 } else { |
1333 most_recent_work_ = now; | 1333 most_recent_work_ = now; |
1334 } | 1334 } |
1335 | 1335 |
1336 if (should_be_running) | 1336 if (should_be_running) |
1337 g_avda_manager.Get().StartTimer(this); | 1337 GetManager()->StartTimer(this); |
1338 else | 1338 else |
1339 g_avda_manager.Get().StopTimer(this); | 1339 GetManager()->StopTimer(this); |
1340 } | 1340 } |
1341 | 1341 |
1342 // static | 1342 // static |
1343 VideoDecodeAccelerator::Capabilities | 1343 VideoDecodeAccelerator::Capabilities |
1344 AndroidVideoDecodeAccelerator::GetCapabilities( | 1344 AndroidVideoDecodeAccelerator::GetCapabilities( |
1345 const gpu::GpuPreferences& gpu_preferences) { | 1345 const gpu::GpuPreferences& gpu_preferences) { |
1346 Capabilities capabilities; | 1346 Capabilities capabilities; |
1347 SupportedProfiles& profiles = capabilities.supported_profiles; | 1347 SupportedProfiles& profiles = capabilities.supported_profiles; |
1348 | 1348 |
1349 if (MediaCodecUtil::IsVp8DecoderAvailable()) { | 1349 if (MediaCodecUtil::IsVp8DecoderAvailable()) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1507 if (!media_codec_) | 1507 if (!media_codec_) |
1508 return; | 1508 return; |
1509 | 1509 |
1510 picture_buffer_manager_.CodecChanged(nullptr); | 1510 picture_buffer_manager_.CodecChanged(nullptr); |
1511 AVDACodecAllocator::Instance()->ReleaseMediaCodec( | 1511 AVDACodecAllocator::Instance()->ReleaseMediaCodec( |
1512 std::move(media_codec_), codec_config_->task_type, config_.surface_id); | 1512 std::move(media_codec_), codec_config_->task_type, config_.surface_id); |
1513 last_release_task_type_ = codec_config_->task_type; | 1513 last_release_task_type_ = codec_config_->task_type; |
1514 } | 1514 } |
1515 | 1515 |
1516 } // namespace media | 1516 } // namespace media |
OLD | NEW |