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 "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/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 DCHECK(!cb.is_null()); | 105 DCHECK(!cb.is_null()); |
106 DCHECK(preroll_cb_.is_null()); | 106 DCHECK(preroll_cb_.is_null()); |
107 | 107 |
108 state_ = kPrerolling; | 108 state_ = kPrerolling; |
109 preroll_cb_ = cb; | 109 preroll_cb_ = cb; |
110 preroll_timestamp_ = time; | 110 preroll_timestamp_ = time; |
111 prerolling_delayed_frame_ = NULL; | 111 prerolling_delayed_frame_ = NULL; |
112 AttemptRead_Locked(); | 112 AttemptRead_Locked(); |
113 } | 113 } |
114 | 114 |
115 void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder, | 115 void VideoRendererBase::Initialize(const scoped_refptr<DemuxerStream>& stream, |
| 116 const VideoDecoderList& decoders, |
116 const PipelineStatusCB& init_cb, | 117 const PipelineStatusCB& init_cb, |
117 const StatisticsCB& statistics_cb, | 118 const StatisticsCB& statistics_cb, |
118 const TimeCB& max_time_cb, | 119 const TimeCB& max_time_cb, |
119 const NaturalSizeChangedCB& size_changed_cb, | 120 const NaturalSizeChangedCB& size_changed_cb, |
120 const base::Closure& ended_cb, | 121 const base::Closure& ended_cb, |
121 const PipelineStatusCB& error_cb, | 122 const PipelineStatusCB& error_cb, |
122 const TimeDeltaCB& get_time_cb, | 123 const TimeDeltaCB& get_time_cb, |
123 const TimeDeltaCB& get_duration_cb) { | 124 const TimeDeltaCB& get_duration_cb) { |
124 base::AutoLock auto_lock(lock_); | 125 base::AutoLock auto_lock(lock_); |
125 DCHECK(decoder); | 126 DCHECK(stream); |
| 127 DCHECK(!decoders.empty()); |
| 128 DCHECK_EQ(stream->type(), DemuxerStream::VIDEO); |
126 DCHECK(!init_cb.is_null()); | 129 DCHECK(!init_cb.is_null()); |
127 DCHECK(!statistics_cb.is_null()); | 130 DCHECK(!statistics_cb.is_null()); |
128 DCHECK(!max_time_cb.is_null()); | 131 DCHECK(!max_time_cb.is_null()); |
129 DCHECK(!size_changed_cb.is_null()); | 132 DCHECK(!size_changed_cb.is_null()); |
130 DCHECK(!ended_cb.is_null()); | 133 DCHECK(!ended_cb.is_null()); |
131 DCHECK(!get_time_cb.is_null()); | 134 DCHECK(!get_time_cb.is_null()); |
132 DCHECK(!get_duration_cb.is_null()); | 135 DCHECK(!get_duration_cb.is_null()); |
133 DCHECK_EQ(kUninitialized, state_); | 136 DCHECK_EQ(kUninitialized, state_); |
134 decoder_ = decoder; | |
135 | 137 |
| 138 init_cb_ = init_cb; |
136 statistics_cb_ = statistics_cb; | 139 statistics_cb_ = statistics_cb; |
137 max_time_cb_ = max_time_cb; | 140 max_time_cb_ = max_time_cb; |
138 size_changed_cb_ = size_changed_cb; | 141 size_changed_cb_ = size_changed_cb; |
139 ended_cb_ = ended_cb; | 142 ended_cb_ = ended_cb; |
140 error_cb_ = error_cb; | 143 error_cb_ = error_cb; |
141 get_time_cb_ = get_time_cb; | 144 get_time_cb_ = get_time_cb; |
142 get_duration_cb_ = get_duration_cb; | 145 get_duration_cb_ = get_duration_cb; |
143 | 146 |
| 147 scoped_ptr<VideoDecoderList> decoder_list(new VideoDecoderList(decoders)); |
| 148 InitializeNextDecoder(stream, decoder_list.Pass()); |
| 149 } |
| 150 |
| 151 void VideoRendererBase::InitializeNextDecoder( |
| 152 const scoped_refptr<DemuxerStream>& demuxer_stream, |
| 153 scoped_ptr<VideoDecoderList> decoders) { |
| 154 lock_.AssertAcquired(); |
| 155 DCHECK(!decoders->empty()); |
| 156 |
| 157 scoped_refptr<VideoDecoder> decoder = decoders->front(); |
| 158 decoders->pop_front(); |
| 159 |
| 160 DCHECK(decoder); |
| 161 decoder_ = decoder; |
| 162 |
| 163 base::AutoUnlock auto_unlock(lock_); |
| 164 decoder->Initialize( |
| 165 demuxer_stream, |
| 166 base::Bind(&VideoRendererBase::OnDecoderInitDone, this, |
| 167 demuxer_stream, |
| 168 base::Passed(&decoders)), |
| 169 statistics_cb_); |
| 170 } |
| 171 |
| 172 void VideoRendererBase::OnDecoderInitDone( |
| 173 const scoped_refptr<DemuxerStream>& demuxer_stream, |
| 174 scoped_ptr<VideoDecoderList> decoders, |
| 175 PipelineStatus status) { |
| 176 base::AutoLock auto_lock(lock_); |
| 177 |
| 178 if (state_ == kStopped) |
| 179 return; |
| 180 |
| 181 if (!decoders->empty() && status == DECODER_ERROR_NOT_SUPPORTED) { |
| 182 InitializeNextDecoder(demuxer_stream, decoders.Pass()); |
| 183 return; |
| 184 } |
| 185 |
| 186 if (status != PIPELINE_OK) { |
| 187 state_ = kError; |
| 188 base::ResetAndReturn(&init_cb_).Run(status); |
| 189 return; |
| 190 } |
| 191 |
144 // We're all good! Consider ourselves flushed. (ThreadMain() should never | 192 // We're all good! Consider ourselves flushed. (ThreadMain() should never |
145 // see us in the kUninitialized state). | 193 // see us in the kUninitialized state). |
146 // 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 |
147 // have not populated any buffers yet. | 195 // have not populated any buffers yet. |
148 state_ = kFlushed; | 196 state_ = kFlushed; |
149 | 197 |
150 set_opaque_cb_.Run(!decoder->HasAlpha()); | 198 set_opaque_cb_.Run(!decoder_->HasAlpha()); |
151 set_opaque_cb_.Reset(); | 199 set_opaque_cb_.Reset(); |
152 | 200 |
153 // Create our video thread. | 201 // Create our video thread. |
154 if (!base::PlatformThread::Create(0, this, &thread_)) { | 202 if (!base::PlatformThread::Create(0, this, &thread_)) { |
155 NOTREACHED() << "Video thread creation failed"; | 203 NOTREACHED() << "Video thread creation failed"; |
156 state_ = kError; | 204 state_ = kError; |
157 init_cb.Run(PIPELINE_ERROR_INITIALIZATION_FAILED); | 205 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
158 return; | 206 return; |
159 } | 207 } |
160 | 208 |
161 #if defined(OS_WIN) | 209 #if defined(OS_WIN) |
162 // Bump up our priority so our sleeping is more accurate. | 210 // Bump up our priority so our sleeping is more accurate. |
163 // TODO(scherkus): find out if this is necessary, but it seems to help. | 211 // TODO(scherkus): find out if this is necessary, but it seems to help. |
164 ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL); | 212 ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL); |
165 #endif // defined(OS_WIN) | 213 #endif // defined(OS_WIN) |
166 init_cb.Run(PIPELINE_OK); | 214 base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| 215 } |
| 216 |
| 217 void VideoRendererBase::PrepareForShutdownHack() { |
| 218 base::AutoLock auto_lock(lock_); |
| 219 if (decoder_) |
| 220 decoder_->PrepareForShutdownHack(); |
167 } | 221 } |
168 | 222 |
169 // PlatformThread::Delegate implementation. | 223 // PlatformThread::Delegate implementation. |
170 void VideoRendererBase::ThreadMain() { | 224 void VideoRendererBase::ThreadMain() { |
171 base::PlatformThread::SetName("CrVideoRenderer"); | 225 base::PlatformThread::SetName("CrVideoRenderer"); |
172 | 226 |
173 // The number of milliseconds to idle when we do not have anything to do. | 227 // The number of milliseconds to idle when we do not have anything to do. |
174 // Nothing special about the value, other than we're being more OS-friendly | 228 // Nothing special about the value, other than we're being more OS-friendly |
175 // than sleeping for 1 millisecond. | 229 // than sleeping for 1 millisecond. |
176 // | 230 // |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 | 627 |
574 int VideoRendererBase::NumFrames_Locked() const { | 628 int VideoRendererBase::NumFrames_Locked() const { |
575 lock_.AssertAcquired(); | 629 lock_.AssertAcquired(); |
576 int outstanding_frames = | 630 int outstanding_frames = |
577 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + | 631 (current_frame_ ? 1 : 0) + (last_available_frame_ ? 1 : 0) + |
578 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); | 632 (current_frame_ && (current_frame_ == last_available_frame_) ? -1 : 0); |
579 return ready_frames_.size() + outstanding_frames; | 633 return ready_frames_.size() + outstanding_frames; |
580 } | 634 } |
581 | 635 |
582 } // namespace media | 636 } // namespace media |
OLD | NEW |