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

Side by Side Diff: media/filters/video_renderer_impl.cc

Issue 65803002: Replace MessageLoopProxy with SingleThreadTaskRunner for media/filters/ + associated code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 12 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 | Annotate | Revision Log
« no previous file with comments | « media/filters/video_renderer_impl.h ('k') | media/filters/vpx_video_decoder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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/filters/video_renderer_impl.h" 5 #include "media/filters/video_renderer_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/location.h"
12 #include "base/single_thread_task_runner.h"
12 #include "base/threading/platform_thread.h" 13 #include "base/threading/platform_thread.h"
13 #include "media/base/buffers.h" 14 #include "media/base/buffers.h"
14 #include "media/base/limits.h" 15 #include "media/base/limits.h"
15 #include "media/base/pipeline.h" 16 #include "media/base/pipeline.h"
16 #include "media/base/video_frame.h" 17 #include "media/base/video_frame.h"
17 18
18 namespace media { 19 namespace media {
19 20
20 base::TimeDelta VideoRendererImpl::kMaxLastFrameDuration() { 21 base::TimeDelta VideoRendererImpl::kMaxLastFrameDuration() {
21 return base::TimeDelta::FromMilliseconds(250); 22 return base::TimeDelta::FromMilliseconds(250);
22 } 23 }
23 24
24 VideoRendererImpl::VideoRendererImpl( 25 VideoRendererImpl::VideoRendererImpl(
25 const scoped_refptr<base::MessageLoopProxy>& message_loop, 26 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
26 ScopedVector<VideoDecoder> decoders, 27 ScopedVector<VideoDecoder> decoders,
27 const SetDecryptorReadyCB& set_decryptor_ready_cb, 28 const SetDecryptorReadyCB& set_decryptor_ready_cb,
28 const PaintCB& paint_cb, 29 const PaintCB& paint_cb,
29 const SetOpaqueCB& set_opaque_cb, 30 const SetOpaqueCB& set_opaque_cb,
30 bool drop_frames) 31 bool drop_frames)
31 : message_loop_(message_loop), 32 : task_runner_(task_runner),
32 weak_factory_(this), 33 weak_factory_(this),
33 video_frame_stream_( 34 video_frame_stream_(
34 message_loop, decoders.Pass(), set_decryptor_ready_cb), 35 task_runner, decoders.Pass(), set_decryptor_ready_cb),
35 received_end_of_stream_(false), 36 received_end_of_stream_(false),
36 frame_available_(&lock_), 37 frame_available_(&lock_),
37 state_(kUninitialized), 38 state_(kUninitialized),
38 thread_(), 39 thread_(),
39 pending_read_(false), 40 pending_read_(false),
40 drop_frames_(drop_frames), 41 drop_frames_(drop_frames),
41 playback_rate_(0), 42 playback_rate_(0),
42 paint_cb_(paint_cb), 43 paint_cb_(paint_cb),
43 set_opaque_cb_(set_opaque_cb), 44 set_opaque_cb_(set_opaque_cb),
44 last_timestamp_(kNoTimestamp()), 45 last_timestamp_(kNoTimestamp()),
45 frames_decoded_(0), 46 frames_decoded_(0),
46 frames_dropped_(0) { 47 frames_dropped_(0) {
47 DCHECK(!paint_cb_.is_null()); 48 DCHECK(!paint_cb_.is_null());
48 } 49 }
49 50
50 VideoRendererImpl::~VideoRendererImpl() { 51 VideoRendererImpl::~VideoRendererImpl() {
51 base::AutoLock auto_lock(lock_); 52 base::AutoLock auto_lock(lock_);
52 CHECK(state_ == kStopped || state_ == kUninitialized) << state_; 53 CHECK(state_ == kStopped || state_ == kUninitialized) << state_;
53 CHECK(thread_.is_null()); 54 CHECK(thread_.is_null());
54 } 55 }
55 56
56 void VideoRendererImpl::Play(const base::Closure& callback) { 57 void VideoRendererImpl::Play(const base::Closure& callback) {
57 DCHECK(message_loop_->BelongsToCurrentThread()); 58 DCHECK(task_runner_->BelongsToCurrentThread());
58 base::AutoLock auto_lock(lock_); 59 base::AutoLock auto_lock(lock_);
59 DCHECK_EQ(kPrerolled, state_); 60 DCHECK_EQ(kPrerolled, state_);
60 state_ = kPlaying; 61 state_ = kPlaying;
61 callback.Run(); 62 callback.Run();
62 } 63 }
63 64
64 void VideoRendererImpl::Pause(const base::Closure& callback) { 65 void VideoRendererImpl::Pause(const base::Closure& callback) {
65 DCHECK(message_loop_->BelongsToCurrentThread()); 66 DCHECK(task_runner_->BelongsToCurrentThread());
66 base::AutoLock auto_lock(lock_); 67 base::AutoLock auto_lock(lock_);
67 DCHECK(state_ != kUninitialized || state_ == kError); 68 DCHECK(state_ != kUninitialized || state_ == kError);
68 state_ = kPaused; 69 state_ = kPaused;
69 callback.Run(); 70 callback.Run();
70 } 71 }
71 72
72 void VideoRendererImpl::Flush(const base::Closure& callback) { 73 void VideoRendererImpl::Flush(const base::Closure& callback) {
73 DCHECK(message_loop_->BelongsToCurrentThread()); 74 DCHECK(task_runner_->BelongsToCurrentThread());
74 base::AutoLock auto_lock(lock_); 75 base::AutoLock auto_lock(lock_);
75 DCHECK_EQ(state_, kPaused); 76 DCHECK_EQ(state_, kPaused);
76 flush_cb_ = callback; 77 flush_cb_ = callback;
77 state_ = kFlushing; 78 state_ = kFlushing;
78 79
79 // This is necessary if the |video_frame_stream_| has already seen an end of 80 // This is necessary if the |video_frame_stream_| has already seen an end of
80 // stream and needs to drain it before flushing it. 81 // stream and needs to drain it before flushing it.
81 ready_frames_.clear(); 82 ready_frames_.clear();
82 received_end_of_stream_ = false; 83 received_end_of_stream_ = false;
83 video_frame_stream_.Reset(base::Bind( 84 video_frame_stream_.Reset(base::Bind(
84 &VideoRendererImpl::OnVideoFrameStreamResetDone, weak_this_)); 85 &VideoRendererImpl::OnVideoFrameStreamResetDone, weak_this_));
85 } 86 }
86 87
87 void VideoRendererImpl::Stop(const base::Closure& callback) { 88 void VideoRendererImpl::Stop(const base::Closure& callback) {
88 DCHECK(message_loop_->BelongsToCurrentThread()); 89 DCHECK(task_runner_->BelongsToCurrentThread());
89 base::AutoLock auto_lock(lock_); 90 base::AutoLock auto_lock(lock_);
90 if (state_ == kUninitialized || state_ == kStopped) { 91 if (state_ == kUninitialized || state_ == kStopped) {
91 callback.Run(); 92 callback.Run();
92 return; 93 return;
93 } 94 }
94 95
95 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing 96 // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
96 // task-running guards that check |state_| with DCHECK(). 97 // task-running guards that check |state_| with DCHECK().
97 98
98 state_ = kStopped; 99 state_ = kStopped;
(...skipping 13 matching lines...) Expand all
112 113
113 if (!thread_to_join.is_null()) { 114 if (!thread_to_join.is_null()) {
114 base::AutoUnlock auto_unlock(lock_); 115 base::AutoUnlock auto_unlock(lock_);
115 base::PlatformThread::Join(thread_to_join); 116 base::PlatformThread::Join(thread_to_join);
116 } 117 }
117 118
118 video_frame_stream_.Stop(callback); 119 video_frame_stream_.Stop(callback);
119 } 120 }
120 121
121 void VideoRendererImpl::SetPlaybackRate(float playback_rate) { 122 void VideoRendererImpl::SetPlaybackRate(float playback_rate) {
122 DCHECK(message_loop_->BelongsToCurrentThread()); 123 DCHECK(task_runner_->BelongsToCurrentThread());
123 base::AutoLock auto_lock(lock_); 124 base::AutoLock auto_lock(lock_);
124 playback_rate_ = playback_rate; 125 playback_rate_ = playback_rate;
125 } 126 }
126 127
127 void VideoRendererImpl::Preroll(base::TimeDelta time, 128 void VideoRendererImpl::Preroll(base::TimeDelta time,
128 const PipelineStatusCB& cb) { 129 const PipelineStatusCB& cb) {
129 DCHECK(message_loop_->BelongsToCurrentThread()); 130 DCHECK(task_runner_->BelongsToCurrentThread());
130 base::AutoLock auto_lock(lock_); 131 base::AutoLock auto_lock(lock_);
131 DCHECK(!cb.is_null()); 132 DCHECK(!cb.is_null());
132 DCHECK(preroll_cb_.is_null()); 133 DCHECK(preroll_cb_.is_null());
133 DCHECK(state_ == kFlushed || state_== kPaused) << "state_ " << state_; 134 DCHECK(state_ == kFlushed || state_== kPaused) << "state_ " << state_;
134 135
135 if (state_ == kFlushed) { 136 if (state_ == kFlushed) {
136 DCHECK(time != kNoTimestamp()); 137 DCHECK(time != kNoTimestamp());
137 DCHECK(!pending_read_); 138 DCHECK(!pending_read_);
138 DCHECK(ready_frames_.empty()); 139 DCHECK(ready_frames_.empty());
139 } else { 140 } else {
(...skipping 14 matching lines...) Expand all
154 155
155 void VideoRendererImpl::Initialize(DemuxerStream* stream, 156 void VideoRendererImpl::Initialize(DemuxerStream* stream,
156 const PipelineStatusCB& init_cb, 157 const PipelineStatusCB& init_cb,
157 const StatisticsCB& statistics_cb, 158 const StatisticsCB& statistics_cb,
158 const TimeCB& max_time_cb, 159 const TimeCB& max_time_cb,
159 const NaturalSizeChangedCB& size_changed_cb, 160 const NaturalSizeChangedCB& size_changed_cb,
160 const base::Closure& ended_cb, 161 const base::Closure& ended_cb,
161 const PipelineStatusCB& error_cb, 162 const PipelineStatusCB& error_cb,
162 const TimeDeltaCB& get_time_cb, 163 const TimeDeltaCB& get_time_cb,
163 const TimeDeltaCB& get_duration_cb) { 164 const TimeDeltaCB& get_duration_cb) {
164 DCHECK(message_loop_->BelongsToCurrentThread()); 165 DCHECK(task_runner_->BelongsToCurrentThread());
165 base::AutoLock auto_lock(lock_); 166 base::AutoLock auto_lock(lock_);
166 DCHECK(stream); 167 DCHECK(stream);
167 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO); 168 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO);
168 DCHECK(!init_cb.is_null()); 169 DCHECK(!init_cb.is_null());
169 DCHECK(!statistics_cb.is_null()); 170 DCHECK(!statistics_cb.is_null());
170 DCHECK(!max_time_cb.is_null()); 171 DCHECK(!max_time_cb.is_null());
171 DCHECK(!size_changed_cb.is_null()); 172 DCHECK(!size_changed_cb.is_null());
172 DCHECK(!ended_cb.is_null()); 173 DCHECK(!ended_cb.is_null());
173 DCHECK(!get_time_cb.is_null()); 174 DCHECK(!get_time_cb.is_null());
174 DCHECK(!get_duration_cb.is_null()); 175 DCHECK(!get_duration_cb.is_null());
(...skipping 12 matching lines...) Expand all
187 188
188 video_frame_stream_.Initialize( 189 video_frame_stream_.Initialize(
189 stream, 190 stream,
190 statistics_cb, 191 statistics_cb,
191 base::Bind(&VideoRendererImpl::OnVideoFrameStreamInitialized, 192 base::Bind(&VideoRendererImpl::OnVideoFrameStreamInitialized,
192 weak_this_)); 193 weak_this_));
193 } 194 }
194 195
195 void VideoRendererImpl::OnVideoFrameStreamInitialized(bool success, 196 void VideoRendererImpl::OnVideoFrameStreamInitialized(bool success,
196 bool has_alpha) { 197 bool has_alpha) {
197 DCHECK(message_loop_->BelongsToCurrentThread()); 198 DCHECK(task_runner_->BelongsToCurrentThread());
198 base::AutoLock auto_lock(lock_); 199 base::AutoLock auto_lock(lock_);
199 200
200 if (state_ == kStopped) 201 if (state_ == kStopped)
201 return; 202 return;
202 203
203 DCHECK_EQ(state_, kInitializing); 204 DCHECK_EQ(state_, kInitializing);
204 205
205 if (!success) { 206 if (!success) {
206 state_ = kUninitialized; 207 state_ = kUninitialized;
207 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 208 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 last_timestamp_ = next_frame->GetTimestamp(); 325 last_timestamp_ = next_frame->GetTimestamp();
325 326
326 const gfx::Size& natural_size = next_frame->natural_size(); 327 const gfx::Size& natural_size = next_frame->natural_size();
327 if (natural_size != last_natural_size_) { 328 if (natural_size != last_natural_size_) {
328 last_natural_size_ = natural_size; 329 last_natural_size_ = natural_size;
329 size_changed_cb_.Run(natural_size); 330 size_changed_cb_.Run(natural_size);
330 } 331 }
331 332
332 paint_cb_.Run(next_frame); 333 paint_cb_.Run(next_frame);
333 334
334 message_loop_->PostTask(FROM_HERE, base::Bind( 335 task_runner_->PostTask(FROM_HERE, base::Bind(
335 &VideoRendererImpl::AttemptRead, weak_this_)); 336 &VideoRendererImpl::AttemptRead, weak_this_));
336 } 337 }
337 338
338 void VideoRendererImpl::DropNextReadyFrame_Locked() { 339 void VideoRendererImpl::DropNextReadyFrame_Locked() {
339 TRACE_EVENT0("media", "VideoRendererImpl:frameDropped"); 340 TRACE_EVENT0("media", "VideoRendererImpl:frameDropped");
340 341
341 lock_.AssertAcquired(); 342 lock_.AssertAcquired();
342 343
343 last_timestamp_ = ready_frames_.front()->GetTimestamp(); 344 last_timestamp_ = ready_frames_.front()->GetTimestamp();
344 ready_frames_.pop_front(); 345 ready_frames_.pop_front();
345 frames_decoded_++; 346 frames_decoded_++;
346 frames_dropped_++; 347 frames_dropped_++;
347 348
348 message_loop_->PostTask(FROM_HERE, base::Bind( 349 task_runner_->PostTask(FROM_HERE, base::Bind(
349 &VideoRendererImpl::AttemptRead, weak_this_)); 350 &VideoRendererImpl::AttemptRead, weak_this_));
350 } 351 }
351 352
352 void VideoRendererImpl::FrameReady(VideoFrameStream::Status status, 353 void VideoRendererImpl::FrameReady(VideoFrameStream::Status status,
353 const scoped_refptr<VideoFrame>& frame) { 354 const scoped_refptr<VideoFrame>& frame) {
354 base::AutoLock auto_lock(lock_); 355 base::AutoLock auto_lock(lock_);
355 DCHECK_NE(state_, kUninitialized); 356 DCHECK_NE(state_, kUninitialized);
356 DCHECK_NE(state_, kFlushed); 357 DCHECK_NE(state_, kFlushed);
357 358
358 CHECK(pending_read_); 359 CHECK(pending_read_);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 if (state_ == kPlaying) 451 if (state_ == kPlaying)
451 frame_available_.Signal(); 452 frame_available_.Signal();
452 } 453 }
453 454
454 void VideoRendererImpl::AttemptRead() { 455 void VideoRendererImpl::AttemptRead() {
455 base::AutoLock auto_lock(lock_); 456 base::AutoLock auto_lock(lock_);
456 AttemptRead_Locked(); 457 AttemptRead_Locked();
457 } 458 }
458 459
459 void VideoRendererImpl::AttemptRead_Locked() { 460 void VideoRendererImpl::AttemptRead_Locked() {
460 DCHECK(message_loop_->BelongsToCurrentThread()); 461 DCHECK(task_runner_->BelongsToCurrentThread());
461 lock_.AssertAcquired(); 462 lock_.AssertAcquired();
462 463
463 if (pending_read_ || received_end_of_stream_ || 464 if (pending_read_ || received_end_of_stream_ ||
464 ready_frames_.size() == static_cast<size_t>(limits::kMaxVideoFrames)) { 465 ready_frames_.size() == static_cast<size_t>(limits::kMaxVideoFrames)) {
465 return; 466 return;
466 } 467 }
467 468
468 switch (state_) { 469 switch (state_) {
469 case kPaused: 470 case kPaused:
470 case kPrerolling: 471 case kPrerolling:
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 statistics_cb_.Run(statistics); 549 statistics_cb_.Run(statistics);
549 550
550 frames_decoded_ = 0; 551 frames_decoded_ = 0;
551 frames_dropped_ = 0; 552 frames_dropped_ = 0;
552 } 553 }
553 554
554 frame_available_.TimedWait(wait_duration); 555 frame_available_.TimedWait(wait_duration);
555 } 556 }
556 557
557 } // namespace media 558 } // namespace media
OLDNEW
« no previous file with comments | « media/filters/video_renderer_impl.h ('k') | media/filters/vpx_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698