OLD | NEW |
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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/callback.h" | 6 #include "base/callback.h" |
7 #include "base/threading/platform_thread.h" | 7 #include "base/threading/platform_thread.h" |
8 #include "media/base/buffers.h" | 8 #include "media/base/buffers.h" |
9 #include "media/base/filter_host.h" | 9 #include "media/base/filter_host.h" |
10 #include "media/base/limits.h" | 10 #include "media/base/limits.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 void VideoRendererBase::Flush(const base::Closure& callback) { | 54 void VideoRendererBase::Flush(const base::Closure& callback) { |
55 base::AutoLock auto_lock(lock_); | 55 base::AutoLock auto_lock(lock_); |
56 DCHECK_EQ(state_, kPaused); | 56 DCHECK_EQ(state_, kPaused); |
57 flush_cb_ = callback; | 57 flush_cb_ = callback; |
58 state_ = kFlushing; | 58 state_ = kFlushing; |
59 | 59 |
60 AttemptFlush_Locked(); | 60 AttemptFlush_Locked(); |
61 } | 61 } |
62 | 62 |
63 void VideoRendererBase::Stop(const base::Closure& callback) { | 63 void VideoRendererBase::Stop(const base::Closure& callback) { |
| 64 if (state_ == kStopped) { |
| 65 callback.Run(); |
| 66 return; |
| 67 } |
| 68 |
64 base::PlatformThreadHandle thread_to_join = base::kNullThreadHandle; | 69 base::PlatformThreadHandle thread_to_join = base::kNullThreadHandle; |
65 { | 70 { |
66 base::AutoLock auto_lock(lock_); | 71 base::AutoLock auto_lock(lock_); |
67 state_ = kStopped; | 72 state_ = kStopped; |
68 | 73 |
69 statistics_cb_.Reset(); | 74 statistics_cb_.Reset(); |
70 time_cb_.Reset(); | 75 time_cb_.Reset(); |
71 if (!pending_paint_ && !pending_paint_with_last_available_) | 76 if (!pending_paint_ && !pending_paint_with_last_available_) |
72 DoStopOrError_Locked(); | 77 DoStopOrError_Locked(); |
73 | 78 |
74 // Clean up our thread if present. | 79 // Clean up our thread if present. |
75 if (thread_ != base::kNullThreadHandle) { | 80 if (thread_ != base::kNullThreadHandle) { |
76 // Signal the thread since it's possible to get stopped with the video | 81 // Signal the thread since it's possible to get stopped with the video |
77 // thread waiting for a read to complete. | 82 // thread waiting for a read to complete. |
78 frame_available_.Signal(); | 83 frame_available_.Signal(); |
79 thread_to_join = thread_; | 84 thread_to_join = thread_; |
80 thread_ = base::kNullThreadHandle; | 85 thread_ = base::kNullThreadHandle; |
81 } | 86 } |
82 } | 87 } |
83 if (thread_to_join != base::kNullThreadHandle) | 88 if (thread_to_join != base::kNullThreadHandle) |
84 base::PlatformThread::Join(thread_to_join); | 89 base::PlatformThread::Join(thread_to_join); |
85 | 90 |
86 callback.Run(); | 91 decoder_->Stop(callback); |
87 } | 92 } |
88 | 93 |
89 void VideoRendererBase::SetPlaybackRate(float playback_rate) { | 94 void VideoRendererBase::SetPlaybackRate(float playback_rate) { |
90 base::AutoLock auto_lock(lock_); | 95 base::AutoLock auto_lock(lock_); |
91 playback_rate_ = playback_rate; | 96 playback_rate_ = playback_rate; |
92 } | 97 } |
93 | 98 |
94 void VideoRendererBase::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { | 99 void VideoRendererBase::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { |
95 base::AutoLock auto_lock(lock_); | 100 base::AutoLock auto_lock(lock_); |
96 DCHECK_EQ(state_, kFlushed) << "Must flush prior to seeking."; | 101 DCHECK_EQ(state_, kFlushed) << "Must flush prior to seeking."; |
97 DCHECK(!cb.is_null()); | 102 DCHECK(!cb.is_null()); |
98 DCHECK(seek_cb_.is_null()); | 103 DCHECK(seek_cb_.is_null()); |
99 | 104 |
100 state_ = kSeeking; | 105 state_ = kSeeking; |
101 seek_cb_ = cb; | 106 seek_cb_ = cb; |
102 seek_timestamp_ = time; | 107 seek_timestamp_ = time; |
103 AttemptRead_Locked(); | 108 AttemptRead_Locked(); |
104 } | 109 } |
105 | 110 |
106 void VideoRendererBase::Initialize(VideoDecoder* decoder, | 111 void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder, |
107 const PipelineStatusCB& status_cb, | 112 const PipelineStatusCB& status_cb, |
108 const StatisticsCB& statistics_cb, | 113 const StatisticsCB& statistics_cb, |
109 const TimeCB& time_cb) { | 114 const TimeCB& time_cb) { |
110 base::AutoLock auto_lock(lock_); | 115 base::AutoLock auto_lock(lock_); |
111 DCHECK(decoder); | 116 DCHECK(decoder); |
112 DCHECK(!status_cb.is_null()); | 117 DCHECK(!status_cb.is_null()); |
113 DCHECK(!statistics_cb.is_null()); | 118 DCHECK(!statistics_cb.is_null()); |
114 DCHECK(!time_cb.is_null()); | 119 DCHECK(!time_cb.is_null()); |
115 DCHECK_EQ(kUninitialized, state_); | 120 DCHECK_EQ(kUninitialized, state_); |
116 decoder_ = decoder; | 121 decoder_ = decoder; |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 void VideoRendererBase::AttemptFlush_Locked() { | 455 void VideoRendererBase::AttemptFlush_Locked() { |
451 lock_.AssertAcquired(); | 456 lock_.AssertAcquired(); |
452 DCHECK_EQ(kFlushing, state_); | 457 DCHECK_EQ(kFlushing, state_); |
453 | 458 |
454 // Get rid of any ready frames. | 459 // Get rid of any ready frames. |
455 ready_frames_.clear(); | 460 ready_frames_.clear(); |
456 | 461 |
457 if (!pending_paint_ && !pending_read_) { | 462 if (!pending_paint_ && !pending_read_) { |
458 state_ = kFlushed; | 463 state_ = kFlushed; |
459 current_frame_ = NULL; | 464 current_frame_ = NULL; |
460 ResetAndRunCB(&flush_cb_); | 465 |
| 466 base::Closure flush_cb = flush_cb_; |
| 467 flush_cb_.Reset(); |
| 468 decoder_->Flush(flush_cb); |
461 } | 469 } |
462 } | 470 } |
463 | 471 |
464 base::TimeDelta VideoRendererBase::CalculateSleepDuration( | 472 base::TimeDelta VideoRendererBase::CalculateSleepDuration( |
465 const scoped_refptr<VideoFrame>& next_frame, | 473 const scoped_refptr<VideoFrame>& next_frame, |
466 float playback_rate) { | 474 float playback_rate) { |
467 // Determine the current and next presentation timestamps. | 475 // Determine the current and next presentation timestamps. |
468 base::TimeDelta now = host()->GetTime(); | 476 base::TimeDelta now = host()->GetTime(); |
469 base::TimeDelta this_pts = current_frame_->GetTimestamp(); | 477 base::TimeDelta this_pts = current_frame_->GetTimestamp(); |
470 base::TimeDelta next_pts; | 478 base::TimeDelta next_pts; |
(...skipping 20 matching lines...) Expand all Loading... |
491 | 499 |
492 int VideoRendererBase::NumFrames_Locked() const { | 500 int VideoRendererBase::NumFrames_Locked() const { |
493 lock_.AssertAcquired(); | 501 lock_.AssertAcquired(); |
494 int outstanding_frames = | 502 int outstanding_frames = |
495 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + | 503 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + |
496 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); | 504 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); |
497 return ready_frames_.size() + outstanding_frames; | 505 return ready_frames_.size() + outstanding_frames; |
498 } | 506 } |
499 | 507 |
500 } // namespace media | 508 } // namespace media |
OLD | NEW |