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" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
17 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
18 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" |
| 19 #include "base/threading/thread_checker.h" |
19 #include "base/trace_event/trace_event.h" | 20 #include "base/trace_event/trace_event.h" |
20 #include "content/common/gpu/media/android_copying_backing_strategy.h" | 21 #include "content/common/gpu/media/android_copying_backing_strategy.h" |
21 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h
" | 22 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h
" |
22 #include "content/common/gpu/media/avda_return_on_failure.h" | 23 #include "content/common/gpu/media/avda_return_on_failure.h" |
23 #include "content/common/gpu/media/shared_memory_region.h" | 24 #include "content/common/gpu/media/shared_memory_region.h" |
24 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 25 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
25 #include "gpu/command_buffer/service/mailbox_manager.h" | 26 #include "gpu/command_buffer/service/mailbox_manager.h" |
26 #include "gpu/ipc/service/gpu_channel.h" | 27 #include "gpu/ipc/service/gpu_channel.h" |
27 #include "media/base/android/media_codec_bridge.h" | 28 #include "media/base/android/media_codec_bridge.h" |
28 #include "media/base/android/media_codec_util.h" | 29 #include "media/base/android/media_codec_util.h" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 // behind this is that, if we're waiting for long enough, then either (a) | 173 // behind this is that, if we're waiting for long enough, then either (a) |
173 // MediaCodec is broken or (b) MediaCodec is waiting on us to change state | 174 // MediaCodec is broken or (b) MediaCodec is waiting on us to change state |
174 // (e.g., get new demuxed data / get a free picture buffer / return an output | 175 // (e.g., get new demuxed data / get a free picture buffer / return an output |
175 // buffer to MediaCodec). This is inherently a race, since we don't know if | 176 // buffer to MediaCodec). This is inherently a race, since we don't know if |
176 // MediaCodec is broken or just slow. Since the MediaCodec API doesn't let | 177 // MediaCodec is broken or just slow. Since the MediaCodec API doesn't let |
177 // us wait on MediaCodec state changes prior to L, we more or less have to | 178 // us wait on MediaCodec state changes prior to L, we more or less have to |
178 // time out or keep polling forever in some common cases. | 179 // time out or keep polling forever in some common cases. |
179 class AVDATimerManager { | 180 class AVDATimerManager { |
180 public: | 181 public: |
181 // Make sure that the construction thread is started for |avda_instance|. | 182 // Make sure that the construction thread is started for |avda_instance|. |
182 void StartThread(AndroidVideoDecodeAccelerator* avda_instance) { | 183 bool StartThread(AndroidVideoDecodeAccelerator* avda_instance) { |
183 if (thread_avda_instances_.empty()) | 184 DCHECK(thread_checker_.CalledOnValidThread()); |
184 construction_thread_.Start(); | 185 |
| 186 if (thread_avda_instances_.empty()) { |
| 187 if (!construction_thread_.Start()) { |
| 188 LOG(ERROR) << "Failed to start construction thread."; |
| 189 return false; |
| 190 } |
| 191 } |
185 | 192 |
186 thread_avda_instances_.insert(avda_instance); | 193 thread_avda_instances_.insert(avda_instance); |
| 194 return true; |
187 } | 195 } |
188 | 196 |
189 // |avda_instance| will no longer need the construction thread. Stop the | 197 // |avda_instance| will no longer need the construction thread. Stop the |
190 // thread if this is the last instance. | 198 // thread if this is the last instance. |
191 void StopThread(AndroidVideoDecodeAccelerator* avda_instance) { | 199 void StopThread(AndroidVideoDecodeAccelerator* avda_instance) { |
| 200 DCHECK(thread_checker_.CalledOnValidThread()); |
| 201 |
192 thread_avda_instances_.erase(avda_instance); | 202 thread_avda_instances_.erase(avda_instance); |
193 if (thread_avda_instances_.empty()) | 203 if (thread_avda_instances_.empty()) |
194 construction_thread_.Stop(); | 204 construction_thread_.Stop(); |
195 } | 205 } |
196 | 206 |
197 // Request periodic callback of |avda_instance|->DoIOTask(). Does nothing if | 207 // Request periodic callback of |avda_instance|->DoIOTask(). Does nothing if |
198 // the instance is already registered and the timer started. The first request | 208 // the instance is already registered and the timer started. The first request |
199 // will start the repeating timer on an interval of DecodePollDelay(). | 209 // will start the repeating timer on an interval of DecodePollDelay(). |
200 void StartTimer(AndroidVideoDecodeAccelerator* avda_instance) { | 210 void StartTimer(AndroidVideoDecodeAccelerator* avda_instance) { |
| 211 DCHECK(thread_checker_.CalledOnValidThread()); |
| 212 |
201 timer_avda_instances_.insert(avda_instance); | 213 timer_avda_instances_.insert(avda_instance); |
202 | 214 |
203 // If the timer is running, StopTimer() might have been called earlier, if | 215 // If the timer is running, StopTimer() might have been called earlier, if |
204 // so remove the instance from the pending erasures. | 216 // so remove the instance from the pending erasures. |
205 if (timer_running_) | 217 if (timer_running_) |
206 pending_erase_.erase(avda_instance); | 218 pending_erase_.erase(avda_instance); |
207 | 219 |
208 if (io_timer_.IsRunning()) | 220 if (io_timer_.IsRunning()) |
209 return; | 221 return; |
210 io_timer_.Start(FROM_HERE, DecodePollDelay(), this, | 222 io_timer_.Start(FROM_HERE, DecodePollDelay(), this, |
211 &AVDATimerManager::RunTimer); | 223 &AVDATimerManager::RunTimer); |
212 } | 224 } |
213 | 225 |
214 // Stop callbacks to |avda_instance|->DoIOTask(). Does nothing if the instance | 226 // Stop callbacks to |avda_instance|->DoIOTask(). Does nothing if the instance |
215 // is not registered. If there are no instances left, the repeating timer will | 227 // is not registered. If there are no instances left, the repeating timer will |
216 // be stopped. | 228 // be stopped. |
217 void StopTimer(AndroidVideoDecodeAccelerator* avda_instance) { | 229 void StopTimer(AndroidVideoDecodeAccelerator* avda_instance) { |
| 230 DCHECK(thread_checker_.CalledOnValidThread()); |
| 231 |
218 // If the timer is running, defer erasures to avoid iterator invalidation. | 232 // If the timer is running, defer erasures to avoid iterator invalidation. |
219 if (timer_running_) { | 233 if (timer_running_) { |
220 pending_erase_.insert(avda_instance); | 234 pending_erase_.insert(avda_instance); |
221 return; | 235 return; |
222 } | 236 } |
223 | 237 |
224 timer_avda_instances_.erase(avda_instance); | 238 timer_avda_instances_.erase(avda_instance); |
225 if (timer_avda_instances_.empty()) | 239 if (timer_avda_instances_.empty()) |
226 io_timer_.Stop(); | 240 io_timer_.Stop(); |
227 } | 241 } |
228 | 242 |
229 // Eventually, we should run the timer on this thread. For now, we just keep | 243 // Eventually, we should run the timer on this thread. For now, we just keep |
230 // it as a convenience for construction. | 244 // it as a convenience for construction. |
231 scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() { | 245 scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() { |
| 246 DCHECK(thread_checker_.CalledOnValidThread()); |
232 return construction_thread_.task_runner(); | 247 return construction_thread_.task_runner(); |
233 } | 248 } |
234 | 249 |
235 private: | 250 private: |
236 friend struct base::DefaultLazyInstanceTraits<AVDATimerManager>; | 251 friend struct base::DefaultLazyInstanceTraits<AVDATimerManager>; |
237 | 252 |
238 AVDATimerManager() : construction_thread_("AVDAThread") {} | 253 AVDATimerManager() : construction_thread_("AVDAThread") {} |
239 ~AVDATimerManager() { NOTREACHED(); } | 254 ~AVDATimerManager() { NOTREACHED(); } |
240 | 255 |
241 void RunTimer() { | 256 void RunTimer() { |
(...skipping 24 matching lines...) Expand all Loading... |
266 // Since we can't delete while iterating when using a set, defer erasure until | 281 // Since we can't delete while iterating when using a set, defer erasure until |
267 // after iteration complete. | 282 // after iteration complete. |
268 bool timer_running_ = false; | 283 bool timer_running_ = false; |
269 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; | 284 std::set<AndroidVideoDecodeAccelerator*> pending_erase_; |
270 | 285 |
271 // Repeating timer responsible for draining pending IO to the codecs. | 286 // Repeating timer responsible for draining pending IO to the codecs. |
272 base::RepeatingTimer io_timer_; | 287 base::RepeatingTimer io_timer_; |
273 | 288 |
274 base::Thread construction_thread_; | 289 base::Thread construction_thread_; |
275 | 290 |
| 291 base::ThreadChecker thread_checker_; |
| 292 |
276 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); | 293 DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); |
277 }; | 294 }; |
278 | 295 |
279 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = | 296 static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = |
280 LAZY_INSTANCE_INITIALIZER; | 297 LAZY_INSTANCE_INITIALIZER; |
281 | 298 |
282 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {} | 299 AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {} |
283 | 300 |
284 AndroidVideoDecodeAccelerator::CodecConfig::~CodecConfig() {} | 301 AndroidVideoDecodeAccelerator::CodecConfig::~CodecConfig() {} |
285 | 302 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 // TODO(watk,liberato): move this into the strategy. | 417 // TODO(watk,liberato): move this into the strategy. |
401 scoped_refptr<gfx::SurfaceTexture> surface_texture = | 418 scoped_refptr<gfx::SurfaceTexture> surface_texture = |
402 strategy_->GetSurfaceTexture(); | 419 strategy_->GetSurfaceTexture(); |
403 if (surface_texture) { | 420 if (surface_texture) { |
404 on_frame_available_handler_ = | 421 on_frame_available_handler_ = |
405 new OnFrameAvailableHandler(this, surface_texture); | 422 new OnFrameAvailableHandler(this, surface_texture); |
406 } | 423 } |
407 | 424 |
408 // Start the thread for async configuration, even if we don't need it now. | 425 // Start the thread for async configuration, even if we don't need it now. |
409 // ResetCodecState might rebuild the codec later, for example. | 426 // ResetCodecState might rebuild the codec later, for example. |
410 g_avda_timer.Pointer()->StartThread(this); | 427 if (!g_avda_timer.Pointer()->StartThread(this)) { |
| 428 LOG(ERROR) << "Failed to start thread for AVDA timer"; |
| 429 return false; |
| 430 } |
411 | 431 |
412 // If we are encrypted, then we aren't able to create the codec yet. | 432 // If we are encrypted, then we aren't able to create the codec yet. |
413 if (is_encrypted_) | 433 if (is_encrypted_) |
414 return true; | 434 return true; |
415 | 435 |
416 if (deferred_initialization_pending_) { | 436 if (deferred_initialization_pending_) { |
417 ConfigureMediaCodecAsynchronously(); | 437 ConfigureMediaCodecAsynchronously(); |
418 return true; | 438 return true; |
419 } | 439 } |
420 | 440 |
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1323 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { | 1343 if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { |
1324 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: | 1344 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: |
1325 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; | 1345 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; |
1326 } | 1346 } |
1327 } | 1347 } |
1328 | 1348 |
1329 return capabilities; | 1349 return capabilities; |
1330 } | 1350 } |
1331 | 1351 |
1332 } // namespace content | 1352 } // namespace content |
OLD | NEW |