OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "base/callback.h" | 5 #include "base/callback.h" |
6 #include "media/base/buffers.h" | 6 #include "media/base/buffers.h" |
7 #include "media/base/filter_host.h" | 7 #include "media/base/filter_host.h" |
8 #include "media/base/video_frame.h" | 8 #include "media/base/video_frame.h" |
9 #include "media/filters/video_renderer_base.h" | 9 #include "media/filters/video_renderer_base.h" |
10 | 10 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 AutoLock auto_lock(lock_); | 144 AutoLock auto_lock(lock_); |
145 playback_rate_ = playback_rate; | 145 playback_rate_ = playback_rate; |
146 } | 146 } |
147 | 147 |
148 void VideoRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) { | 148 void VideoRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) { |
149 AutoLock auto_lock(lock_); | 149 AutoLock auto_lock(lock_); |
150 DCHECK_EQ(kPaused, state_); | 150 DCHECK_EQ(kPaused, state_); |
151 DCHECK_EQ(0u, pending_reads_) << "Pending reads should have completed"; | 151 DCHECK_EQ(0u, pending_reads_) << "Pending reads should have completed"; |
152 state_ = kSeeking; | 152 state_ = kSeeking; |
153 seek_callback_.reset(callback); | 153 seek_callback_.reset(callback); |
| 154 seek_timestamp_ = time; |
154 | 155 |
155 // Throw away everything and schedule our reads. | 156 // Throw away everything and schedule our reads. |
156 // TODO(jiesun): this should be guaranteed by pause/flush before seek happen. | 157 // TODO(jiesun): this should be guaranteed by pause/flush before seek happen. |
157 frames_queue_ready_.clear(); | 158 frames_queue_ready_.clear(); |
158 frames_queue_done_.clear(); | 159 frames_queue_done_.clear(); |
159 for (size_t i = 0; i < kMaxFrames; ++i) { | 160 for (size_t i = 0; i < kMaxFrames; ++i) { |
160 // TODO(jiesun): this is dummy read for ffmpeg path until we truely recycle | 161 // TODO(jiesun): this is dummy read for ffmpeg path until we truely recycle |
161 // in that path. | 162 // in that path. |
162 scoped_refptr<VideoFrame> null_frame; | 163 scoped_refptr<VideoFrame> null_frame; |
163 frames_queue_done_.push_back(null_frame); | 164 frames_queue_done_.push_back(null_frame); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 if (state_ == kStopped) { | 384 if (state_ == kStopped) { |
384 // TODO(jiesun): Remove this when flush before stop landed! | 385 // TODO(jiesun): Remove this when flush before stop landed! |
385 return; | 386 return; |
386 } | 387 } |
387 | 388 |
388 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying || | 389 DCHECK(state_ == kPaused || state_ == kSeeking || state_ == kPlaying || |
389 state_ == kEnded); | 390 state_ == kEnded); |
390 DCHECK_GT(pending_reads_, 0u); | 391 DCHECK_GT(pending_reads_, 0u); |
391 --pending_reads_; | 392 --pending_reads_; |
392 | 393 |
393 // Enqueue the frame. | 394 // Discard frames until we reach our desired seek timestamp. |
394 frames_queue_ready_.push_back(frame); | 395 if (state_ == kSeeking && !frame->IsEndOfStream() && |
395 DCHECK_LE(frames_queue_ready_.size(), kMaxFrames); | 396 (frame->GetTimestamp() + frame->GetDuration()) < seek_timestamp_) { |
396 frame_available_.Signal(); | 397 frames_queue_done_.push_back(frame); |
| 398 ScheduleRead_Locked(); |
| 399 } else { |
| 400 frames_queue_ready_.push_back(frame); |
| 401 DCHECK_LE(frames_queue_ready_.size(), kMaxFrames); |
| 402 frame_available_.Signal(); |
| 403 } |
397 | 404 |
398 // Check for our preroll complete condition. | 405 // Check for our preroll complete condition. |
399 if (state_ == kSeeking) { | 406 if (state_ == kSeeking) { |
400 DCHECK(seek_callback_.get()); | 407 DCHECK(seek_callback_.get()); |
401 if (frames_queue_ready_.size() == kMaxFrames) { | 408 if (frames_queue_ready_.size() == kMaxFrames) { |
402 // We're paused, so make sure we update |current_frame_| to represent | 409 // We're paused, so make sure we update |current_frame_| to represent |
403 // our new location. | 410 // our new location. |
404 state_ = kPaused; | 411 state_ = kPaused; |
405 | 412 |
406 // Because we might remain paused (i.e., we were not playing before we | 413 // Because we might remain paused (i.e., we were not playing before we |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 previous_time_ = now; | 484 previous_time_ = now; |
478 } | 485 } |
479 | 486 |
480 // Scale our sleep based on the playback rate. | 487 // Scale our sleep based on the playback rate. |
481 // TODO(scherkus): floating point badness and degrade gracefully. | 488 // TODO(scherkus): floating point badness and degrade gracefully. |
482 return base::TimeDelta::FromMicroseconds( | 489 return base::TimeDelta::FromMicroseconds( |
483 static_cast<int64>(sleep.InMicroseconds() / playback_rate)); | 490 static_cast<int64>(sleep.InMicroseconds() / playback_rate)); |
484 } | 491 } |
485 | 492 |
486 } // namespace media | 493 } // namespace media |
OLD | NEW |