OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/renderers/renderer_impl.h" | 5 #include "media/renderers/renderer_impl.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 pending_cdm_attached_cb_ = cdm_attached_cb; | 177 pending_cdm_attached_cb_ = cdm_attached_cb; |
178 | 178 |
179 InitializeAudioRenderer(); | 179 InitializeAudioRenderer(); |
180 } | 180 } |
181 | 181 |
182 void RendererImpl::Flush(const base::Closure& flush_cb) { | 182 void RendererImpl::Flush(const base::Closure& flush_cb) { |
183 DVLOG(1) << __func__; | 183 DVLOG(1) << __func__; |
184 DCHECK(task_runner_->BelongsToCurrentThread()); | 184 DCHECK(task_runner_->BelongsToCurrentThread()); |
185 DCHECK(flush_cb_.is_null()); | 185 DCHECK(flush_cb_.is_null()); |
186 | 186 |
| 187 if (state_ == STATE_FLUSHED) { |
| 188 task_runner_->PostTask(FROM_HERE, flush_cb); |
| 189 return; |
| 190 } |
| 191 |
187 if (state_ != STATE_PLAYING) { | 192 if (state_ != STATE_PLAYING) { |
188 DCHECK_EQ(state_, STATE_ERROR); | 193 DCHECK_EQ(state_, STATE_ERROR); |
189 return; | 194 return; |
190 } | 195 } |
191 | 196 |
192 flush_cb_ = flush_cb; | 197 flush_cb_ = flush_cb; |
193 state_ = STATE_FLUSHING; | 198 state_ = STATE_FLUSHING; |
194 | 199 |
195 if (time_ticking_) | 200 if (time_ticking_) |
196 PausePlayback(); | 201 PausePlayback(); |
197 | 202 |
198 FlushAudioRenderer(); | 203 FlushAudioRenderer(); |
199 } | 204 } |
200 | 205 |
201 void RendererImpl::StartPlayingFrom(base::TimeDelta time) { | 206 void RendererImpl::StartPlayingFrom(base::TimeDelta time) { |
202 DVLOG(1) << __func__; | 207 DVLOG(1) << __func__; |
203 DCHECK(task_runner_->BelongsToCurrentThread()); | 208 DCHECK(task_runner_->BelongsToCurrentThread()); |
204 | 209 |
205 if (state_ != STATE_PLAYING) { | 210 if (state_ != STATE_FLUSHED) { |
206 DCHECK_EQ(state_, STATE_ERROR); | 211 DCHECK_EQ(state_, STATE_ERROR); |
207 return; | 212 return; |
208 } | 213 } |
209 | 214 |
210 time_source_->SetMediaTime(time); | 215 time_source_->SetMediaTime(time); |
211 | 216 |
| 217 state_ = STATE_PLAYING; |
212 if (audio_renderer_) | 218 if (audio_renderer_) |
213 audio_renderer_->StartPlaying(); | 219 audio_renderer_->StartPlaying(); |
214 if (video_renderer_) | 220 if (video_renderer_) |
215 video_renderer_->StartPlayingFrom(time); | 221 video_renderer_->StartPlayingFrom(time); |
216 } | 222 } |
217 | 223 |
218 void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream, | 224 void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream, |
219 bool enabled, | 225 bool enabled, |
220 base::TimeDelta time) { | 226 base::TimeDelta time) { |
221 DCHECK(task_runner_->BelongsToCurrentThread()); | 227 DCHECK(task_runner_->BelongsToCurrentThread()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 DCHECK(audio_renderer_); | 277 DCHECK(audio_renderer_); |
272 audio_ended_ = false; | 278 audio_ended_ = false; |
273 audio_renderer_->StartPlaying(); | 279 audio_renderer_->StartPlaying(); |
274 } | 280 } |
275 | 281 |
276 void RendererImpl::SetPlaybackRate(double playback_rate) { | 282 void RendererImpl::SetPlaybackRate(double playback_rate) { |
277 DVLOG(1) << __func__ << "(" << playback_rate << ")"; | 283 DVLOG(1) << __func__ << "(" << playback_rate << ")"; |
278 DCHECK(task_runner_->BelongsToCurrentThread()); | 284 DCHECK(task_runner_->BelongsToCurrentThread()); |
279 | 285 |
280 // Playback rate changes are only carried out while playing. | 286 // Playback rate changes are only carried out while playing. |
281 if (state_ != STATE_PLAYING) | 287 if (state_ != STATE_PLAYING && state_ != STATE_FLUSHED) |
282 return; | 288 return; |
283 | 289 |
284 time_source_->SetPlaybackRate(playback_rate); | 290 time_source_->SetPlaybackRate(playback_rate); |
285 | 291 |
286 const double old_rate = playback_rate_; | 292 const double old_rate = playback_rate_; |
287 playback_rate_ = playback_rate; | 293 playback_rate_ = playback_rate; |
288 if (!time_ticking_ || !video_renderer_) | 294 if (!time_ticking_ || !video_renderer_) |
289 return; | 295 return; |
290 | 296 |
291 if (old_rate == 0 && playback_rate > 0) | 297 if (old_rate == 0 && playback_rate > 0) |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 media_resource_->SetStreamStatusChangeCB( | 479 media_resource_->SetStreamStatusChangeCB( |
474 base::Bind(&RendererImpl::OnStreamStatusChanged, weak_this_)); | 480 base::Bind(&RendererImpl::OnStreamStatusChanged, weak_this_)); |
475 | 481 |
476 if (audio_renderer_) { | 482 if (audio_renderer_) { |
477 time_source_ = audio_renderer_->GetTimeSource(); | 483 time_source_ = audio_renderer_->GetTimeSource(); |
478 } else if (!time_source_) { | 484 } else if (!time_source_) { |
479 wall_clock_time_source_.reset(new WallClockTimeSource()); | 485 wall_clock_time_source_.reset(new WallClockTimeSource()); |
480 time_source_ = wall_clock_time_source_.get(); | 486 time_source_ = wall_clock_time_source_.get(); |
481 } | 487 } |
482 | 488 |
483 state_ = STATE_PLAYING; | 489 state_ = STATE_FLUSHED; |
484 DCHECK(time_source_); | 490 DCHECK(time_source_); |
485 DCHECK(audio_renderer_ || video_renderer_); | 491 DCHECK(audio_renderer_ || video_renderer_); |
486 | 492 |
487 FinishInitialization(PIPELINE_OK); | 493 FinishInitialization(PIPELINE_OK); |
488 } | 494 } |
489 | 495 |
490 void RendererImpl::FlushAudioRenderer() { | 496 void RendererImpl::FlushAudioRenderer() { |
491 DVLOG(1) << __func__; | 497 DVLOG(1) << __func__; |
492 DCHECK(task_runner_->BelongsToCurrentThread()); | 498 DCHECK(task_runner_->BelongsToCurrentThread()); |
493 DCHECK_EQ(state_, STATE_FLUSHING); | 499 DCHECK_EQ(state_, STATE_FLUSHING); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 if (state_ == STATE_ERROR) { | 551 if (state_ == STATE_ERROR) { |
546 DCHECK(flush_cb_.is_null()); | 552 DCHECK(flush_cb_.is_null()); |
547 return; | 553 return; |
548 } | 554 } |
549 | 555 |
550 DCHECK_EQ(state_, STATE_FLUSHING); | 556 DCHECK_EQ(state_, STATE_FLUSHING); |
551 DCHECK(!flush_cb_.is_null()); | 557 DCHECK(!flush_cb_.is_null()); |
552 | 558 |
553 DCHECK_EQ(video_buffering_state_, BUFFERING_HAVE_NOTHING); | 559 DCHECK_EQ(video_buffering_state_, BUFFERING_HAVE_NOTHING); |
554 video_ended_ = false; | 560 video_ended_ = false; |
555 state_ = STATE_PLAYING; | 561 state_ = STATE_FLUSHED; |
556 base::ResetAndReturn(&flush_cb_).Run(); | 562 base::ResetAndReturn(&flush_cb_).Run(); |
557 } | 563 } |
558 | 564 |
559 void RendererImpl::OnStatisticsUpdate(const PipelineStatistics& stats) { | 565 void RendererImpl::OnStatisticsUpdate(const PipelineStatistics& stats) { |
560 DCHECK(task_runner_->BelongsToCurrentThread()); | 566 DCHECK(task_runner_->BelongsToCurrentThread()); |
561 client_->OnStatisticsUpdate(stats); | 567 client_->OnStatisticsUpdate(stats); |
562 } | 568 } |
563 | 569 |
564 bool RendererImpl::HandleRestartedStreamBufferingChanges( | 570 bool RendererImpl::HandleRestartedStreamBufferingChanges( |
565 DemuxerStream::Type type, | 571 DemuxerStream::Type type, |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 DCHECK(task_runner_->BelongsToCurrentThread()); | 732 DCHECK(task_runner_->BelongsToCurrentThread()); |
727 switch (state_) { | 733 switch (state_) { |
728 case STATE_PLAYING: | 734 case STATE_PLAYING: |
729 DCHECK(PlaybackHasEnded() || WaitingForEnoughData() || restarting_audio_) | 735 DCHECK(PlaybackHasEnded() || WaitingForEnoughData() || restarting_audio_) |
730 << "Playback should only pause due to ending or underflowing or" | 736 << "Playback should only pause due to ending or underflowing or" |
731 " when restarting audio stream"; | 737 " when restarting audio stream"; |
732 | 738 |
733 break; | 739 break; |
734 | 740 |
735 case STATE_FLUSHING: | 741 case STATE_FLUSHING: |
| 742 case STATE_FLUSHED: |
736 // It's OK to pause playback when flushing. | 743 // It's OK to pause playback when flushing. |
737 break; | 744 break; |
738 | 745 |
739 case STATE_UNINITIALIZED: | 746 case STATE_UNINITIALIZED: |
740 case STATE_INIT_PENDING_CDM: | 747 case STATE_INIT_PENDING_CDM: |
741 case STATE_INITIALIZING: | 748 case STATE_INITIALIZING: |
742 NOTREACHED() << "Invalid state: " << state_; | 749 NOTREACHED() << "Invalid state: " << state_; |
743 break; | 750 break; |
744 | 751 |
745 case STATE_ERROR: | 752 case STATE_ERROR: |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 DCHECK(task_runner_->BelongsToCurrentThread()); | 856 DCHECK(task_runner_->BelongsToCurrentThread()); |
850 client_->OnVideoNaturalSizeChange(size); | 857 client_->OnVideoNaturalSizeChange(size); |
851 } | 858 } |
852 | 859 |
853 void RendererImpl::OnVideoOpacityChange(bool opaque) { | 860 void RendererImpl::OnVideoOpacityChange(bool opaque) { |
854 DCHECK(task_runner_->BelongsToCurrentThread()); | 861 DCHECK(task_runner_->BelongsToCurrentThread()); |
855 client_->OnVideoOpacityChange(opaque); | 862 client_->OnVideoOpacityChange(opaque); |
856 } | 863 } |
857 | 864 |
858 } // namespace media | 865 } // namespace media |
OLD | NEW |