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

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

Issue 12818004: Introduce VideoFrameStream, the video frame provider in media pipeline. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Call VideoDecoder::Reset()/Stop() during pending read. Created 7 years, 9 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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_base.h" 5 #include "media/filters/video_renderer_base.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/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/threading/platform_thread.h" 11 #include "base/threading/platform_thread.h"
12 #include "media/base/buffers.h" 12 #include "media/base/buffers.h"
13 #include "media/base/limits.h" 13 #include "media/base/limits.h"
14 #include "media/base/pipeline.h" 14 #include "media/base/pipeline.h"
15 #include "media/base/video_frame.h" 15 #include "media/base/video_frame.h"
16 #include "media/filters/decrypting_demuxer_stream.h" 16 #include "media/filters/decrypting_demuxer_stream.h"
17 #include "media/filters/video_decoder_selector.h"
18 17
19 namespace media { 18 namespace media {
20 19
21 base::TimeDelta VideoRendererBase::kMaxLastFrameDuration() { 20 base::TimeDelta VideoRendererBase::kMaxLastFrameDuration() {
22 return base::TimeDelta::FromMilliseconds(250); 21 return base::TimeDelta::FromMilliseconds(250);
23 } 22 }
24 23
25 VideoRendererBase::VideoRendererBase( 24 VideoRendererBase::VideoRendererBase(
26 const scoped_refptr<base::MessageLoopProxy>& message_loop, 25 const scoped_refptr<base::MessageLoopProxy>& message_loop,
27 const SetDecryptorReadyCB& set_decryptor_ready_cb, 26 const SetDecryptorReadyCB& set_decryptor_ready_cb,
28 const PaintCB& paint_cb, 27 const PaintCB& paint_cb,
29 const SetOpaqueCB& set_opaque_cb, 28 const SetOpaqueCB& set_opaque_cb,
30 bool drop_frames) 29 bool drop_frames)
31 : message_loop_(message_loop), 30 : message_loop_(message_loop),
32 weak_factory_(this), 31 weak_factory_(this),
33 set_decryptor_ready_cb_(set_decryptor_ready_cb), 32 video_frame_stream_(message_loop, set_decryptor_ready_cb),
34 received_end_of_stream_(false), 33 received_end_of_stream_(false),
35 frame_available_(&lock_), 34 frame_available_(&lock_),
36 state_(kUninitialized), 35 state_(kUninitialized),
37 thread_(base::kNullThreadHandle), 36 thread_(base::kNullThreadHandle),
38 pending_read_(false), 37 pending_read_(false),
39 drop_frames_(drop_frames), 38 drop_frames_(drop_frames),
40 playback_rate_(0), 39 playback_rate_(0),
41 paint_cb_(paint_cb), 40 paint_cb_(paint_cb),
42 set_opaque_cb_(set_opaque_cb), 41 set_opaque_cb_(set_opaque_cb),
43 last_timestamp_(kNoTimestamp()) { 42 last_timestamp_(kNoTimestamp()) {
(...skipping 22 matching lines...) Expand all
66 callback.Run(); 65 callback.Run();
67 } 66 }
68 67
69 void VideoRendererBase::Flush(const base::Closure& callback) { 68 void VideoRendererBase::Flush(const base::Closure& callback) {
70 DCHECK(message_loop_->BelongsToCurrentThread()); 69 DCHECK(message_loop_->BelongsToCurrentThread());
71 base::AutoLock auto_lock(lock_); 70 base::AutoLock auto_lock(lock_);
72 DCHECK_EQ(state_, kPaused); 71 DCHECK_EQ(state_, kPaused);
73 flush_cb_ = callback; 72 flush_cb_ = callback;
74 state_ = kFlushingDecoder; 73 state_ = kFlushingDecoder;
75 74
76 if (decrypting_demuxer_stream_) { 75 video_frame_stream_.Reset(base::Bind(
77 decrypting_demuxer_stream_->Reset(base::Bind( 76 &VideoRendererBase::OnVideoFrameStreamResetDone, weak_this_));
78 &VideoRendererBase::ResetDecoder, weak_this_));
79 return;
80 }
81
82 decoder_->Reset(base::Bind(
83 &VideoRendererBase::OnDecoderResetDone, weak_this_));
84 }
85
86 void VideoRendererBase::ResetDecoder() {
87 DCHECK(message_loop_->BelongsToCurrentThread());
88 base::AutoLock auto_lock(lock_);
89 decoder_->Reset(base::Bind(
90 &VideoRendererBase::OnDecoderResetDone, weak_this_));
91 } 77 }
92 78
93 void VideoRendererBase::Stop(const base::Closure& callback) { 79 void VideoRendererBase::Stop(const base::Closure& callback) {
94 DCHECK(message_loop_->BelongsToCurrentThread()); 80 DCHECK(message_loop_->BelongsToCurrentThread());
95 base::AutoLock auto_lock(lock_); 81 base::AutoLock auto_lock(lock_);
96 if (state_ == kUninitialized || state_ == kStopped) { 82 if (state_ == kUninitialized || state_ == kStopped) {
97 callback.Run(); 83 callback.Run();
98 return; 84 return;
99 } 85 }
100 86
(...skipping 13 matching lines...) Expand all
114 // thread waiting for a read to complete. 100 // thread waiting for a read to complete.
115 frame_available_.Signal(); 101 frame_available_.Signal();
116 std::swap(thread_, thread_to_join); 102 std::swap(thread_, thread_to_join);
117 } 103 }
118 104
119 if (thread_to_join != base::kNullThreadHandle) { 105 if (thread_to_join != base::kNullThreadHandle) {
120 base::AutoUnlock auto_unlock(lock_); 106 base::AutoUnlock auto_unlock(lock_);
121 base::PlatformThread::Join(thread_to_join); 107 base::PlatformThread::Join(thread_to_join);
122 } 108 }
123 109
124 if (decrypting_demuxer_stream_) { 110 video_frame_stream_.Stop(callback);
125 decrypting_demuxer_stream_->Reset(base::Bind(
126 &VideoRendererBase::StopDecoder, weak_this_, callback));
127 return;
128 }
129
130 if (decoder_) {
131 decoder_->Stop(callback);
132 return;
133 }
134
135 callback.Run();
136 }
137
138 void VideoRendererBase::StopDecoder(const base::Closure& callback) {
139 DCHECK(message_loop_->BelongsToCurrentThread());
140 base::AutoLock auto_lock(lock_);
141 decoder_->Stop(callback);
142 } 111 }
143 112
144 void VideoRendererBase::SetPlaybackRate(float playback_rate) { 113 void VideoRendererBase::SetPlaybackRate(float playback_rate) {
145 DCHECK(message_loop_->BelongsToCurrentThread()); 114 DCHECK(message_loop_->BelongsToCurrentThread());
146 base::AutoLock auto_lock(lock_); 115 base::AutoLock auto_lock(lock_);
147 playback_rate_ = playback_rate; 116 playback_rate_ = playback_rate;
148 } 117 }
149 118
150 void VideoRendererBase::Preroll(base::TimeDelta time, 119 void VideoRendererBase::Preroll(base::TimeDelta time,
151 const PipelineStatusCB& cb) { 120 const PipelineStatusCB& cb) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 init_cb_ = init_cb; 158 init_cb_ = init_cb;
190 statistics_cb_ = statistics_cb; 159 statistics_cb_ = statistics_cb;
191 max_time_cb_ = max_time_cb; 160 max_time_cb_ = max_time_cb;
192 size_changed_cb_ = size_changed_cb; 161 size_changed_cb_ = size_changed_cb;
193 ended_cb_ = ended_cb; 162 ended_cb_ = ended_cb;
194 error_cb_ = error_cb; 163 error_cb_ = error_cb;
195 get_time_cb_ = get_time_cb; 164 get_time_cb_ = get_time_cb;
196 get_duration_cb_ = get_duration_cb; 165 get_duration_cb_ = get_duration_cb;
197 state_ = kInitializing; 166 state_ = kInitializing;
198 167
199 scoped_ptr<VideoDecoderSelector> decoder_selector( 168 video_frame_stream_.Initialize(
200 new VideoDecoderSelector(base::MessageLoopProxy::current(),
201 decoders,
202 set_decryptor_ready_cb_));
203
204 // To avoid calling |decoder_selector| methods and passing ownership of
205 // |decoder_selector| in the same line.
206 VideoDecoderSelector* decoder_selector_ptr = decoder_selector.get();
207
208 decoder_selector_ptr->SelectVideoDecoder(
209 stream, 169 stream,
170 decoders,
210 statistics_cb, 171 statistics_cb,
211 base::Bind(&VideoRendererBase::OnDecoderSelected, weak_this_, 172 base::Bind(&VideoRendererBase::OnVideoFrameStreamInitialized,
212 base::Passed(&decoder_selector))); 173 weak_this_));
213 } 174 }
214 175
215 void VideoRendererBase::OnDecoderSelected( 176 void VideoRendererBase::OnVideoFrameStreamInitialized(bool success,
216 scoped_ptr<VideoDecoderSelector> decoder_selector, 177 bool has_alpha) {
217 const scoped_refptr<VideoDecoder>& selected_decoder,
218 const scoped_refptr<DecryptingDemuxerStream>& decrypting_demuxer_stream) {
219 DCHECK(message_loop_->BelongsToCurrentThread()); 178 DCHECK(message_loop_->BelongsToCurrentThread());
220 base::AutoLock auto_lock(lock_); 179 base::AutoLock auto_lock(lock_);
221 180
222 if (state_ == kStopped) 181 if (state_ == kStopped)
223 return; 182 return;
224 183
225 DCHECK_EQ(state_, kInitializing); 184 DCHECK_EQ(state_, kInitializing);
226 185
227 if (!selected_decoder) { 186 if (!success) {
228 state_ = kUninitialized; 187 state_ = kUninitialized;
229 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED); 188 base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
230 return; 189 return;
231 } 190 }
232 191
233 decoder_ = selected_decoder;
234 decrypting_demuxer_stream_ = decrypting_demuxer_stream;
235
236 // We're all good! Consider ourselves flushed. (ThreadMain() should never 192 // We're all good! Consider ourselves flushed. (ThreadMain() should never
237 // see us in the kUninitialized state). 193 // see us in the kUninitialized state).
238 // Since we had an initial Preroll(), we consider ourself flushed, because we 194 // Since we had an initial Preroll(), we consider ourself flushed, because we
239 // have not populated any buffers yet. 195 // have not populated any buffers yet.
240 state_ = kFlushed; 196 state_ = kFlushed;
241 197
242 set_opaque_cb_.Run(!decoder_->HasAlpha()); 198 set_opaque_cb_.Run(!has_alpha);
243 set_opaque_cb_.Reset(); 199 set_opaque_cb_.Reset();
244 200
245 // Create our video thread. 201 // Create our video thread.
246 if (!base::PlatformThread::Create(0, this, &thread_)) { 202 if (!base::PlatformThread::Create(0, this, &thread_)) {
247 NOTREACHED() << "Video thread creation failed"; 203 NOTREACHED() << "Video thread creation failed";
248 state_ = kError; 204 state_ = kError;
249 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); 205 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
250 return; 206 return;
251 } 207 }
252 208
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 ready_frames_.size() == static_cast<size_t>(limits::kMaxVideoFrames)) { 466 ready_frames_.size() == static_cast<size_t>(limits::kMaxVideoFrames)) {
511 return; 467 return;
512 } 468 }
513 469
514 switch (state_) { 470 switch (state_) {
515 case kPaused: 471 case kPaused:
516 case kFlushing: 472 case kFlushing:
517 case kPrerolling: 473 case kPrerolling:
518 case kPlaying: 474 case kPlaying:
519 pending_read_ = true; 475 pending_read_ = true;
520 decoder_->Read(base::Bind(&VideoRendererBase::FrameReady, weak_this_)); 476 video_frame_stream_.ReadFrame(base::Bind(&VideoRendererBase::FrameReady,
477 weak_this_));
521 return; 478 return;
522 479
523 case kUninitialized: 480 case kUninitialized:
524 case kInitializing: 481 case kInitializing:
525 case kPrerolled: 482 case kPrerolled:
526 case kFlushingDecoder: 483 case kFlushingDecoder:
527 case kFlushed: 484 case kFlushed:
528 case kEnded: 485 case kEnded:
529 case kStopped: 486 case kStopped:
530 case kError: 487 case kError:
531 return; 488 return;
532 } 489 }
533 } 490 }
534 491
535 void VideoRendererBase::OnDecoderResetDone() { 492 void VideoRendererBase::OnVideoFrameStreamResetDone() {
536 base::AutoLock auto_lock(lock_); 493 base::AutoLock auto_lock(lock_);
537 if (state_ == kStopped) 494 if (state_ == kStopped)
538 return; 495 return;
539 496
540 DCHECK_EQ(kFlushingDecoder, state_); 497 DCHECK_EQ(kFlushingDecoder, state_);
541 DCHECK(!pending_read_); 498 DCHECK(!pending_read_);
542 499
543 state_ = kFlushing; 500 state_ = kFlushing;
544 AttemptFlush_Locked(); 501 AttemptFlush_Locked();
545 } 502 }
(...skipping 26 matching lines...) Expand all
572 static_cast<int64>(sleep.InMicroseconds() / playback_rate)); 529 static_cast<int64>(sleep.InMicroseconds() / playback_rate));
573 } 530 }
574 531
575 void VideoRendererBase::DoStopOrError_Locked() { 532 void VideoRendererBase::DoStopOrError_Locked() {
576 lock_.AssertAcquired(); 533 lock_.AssertAcquired();
577 last_timestamp_ = kNoTimestamp(); 534 last_timestamp_ = kNoTimestamp();
578 ready_frames_.clear(); 535 ready_frames_.clear();
579 } 536 }
580 537
581 } // namespace media 538 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698