Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: content/common/gpu/media/android_video_decode_accelerator.cc

Issue 1903013002: media: Check StartThread() result in AVDATimerManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698