Chromium Code Reviews| 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 14 matching lines...) Expand all Loading... | |
| 25 #include "media/base/video_renderer.h" | 25 #include "media/base/video_renderer.h" |
| 26 #include "media/base/wall_clock_time_source.h" | 26 #include "media/base/wall_clock_time_source.h" |
| 27 | 27 |
| 28 namespace media { | 28 namespace media { |
| 29 | 29 |
| 30 // See |video_underflow_threshold_|. | 30 // See |video_underflow_threshold_|. |
| 31 static const int kDefaultVideoUnderflowThresholdMs = 3000; | 31 static const int kDefaultVideoUnderflowThresholdMs = 3000; |
| 32 | 32 |
| 33 static const int kAudioRestartUnderflowThresholdMs = 2000; | 33 static const int kAudioRestartUnderflowThresholdMs = 2000; |
| 34 | 34 |
| 35 // Specifies the delay for postponed stream status changes while another status | |
| 36 // change of the same stream type is being handled. | |
| 37 static const int kStreamStatusHandlingDelayMs = 10; | |
|
xhwang
2017/01/04 19:34:02
nit: no need to use "static" here. Namespace scope
servolk
2017/01/04 21:29:30
Done.
| |
| 38 | |
| 35 class RendererImpl::RendererClientInternal : public RendererClient { | 39 class RendererImpl::RendererClientInternal : public RendererClient { |
| 36 public: | 40 public: |
| 37 RendererClientInternal(DemuxerStream::Type type, RendererImpl* renderer) | 41 RendererClientInternal(DemuxerStream::Type type, RendererImpl* renderer) |
| 38 : type_(type), renderer_(renderer) { | 42 : type_(type), renderer_(renderer) { |
| 39 DCHECK((type_ == DemuxerStream::AUDIO) || (type_ == DemuxerStream::VIDEO)); | 43 DCHECK((type_ == DemuxerStream::AUDIO) || (type_ == DemuxerStream::VIDEO)); |
| 40 } | 44 } |
| 41 | 45 |
| 42 void OnError(PipelineStatus error) override { renderer_->OnError(error); } | 46 void OnError(PipelineStatus error) override { renderer_->OnError(error); } |
| 43 void OnEnded() override { renderer_->OnRendererEnded(type_); } | 47 void OnEnded() override { renderer_->OnRendererEnded(type_); } |
| 44 void OnStatisticsUpdate(const PipelineStatistics& stats) override { | 48 void OnStatisticsUpdate(const PipelineStatistics& stats) override { |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 } | 205 } |
| 202 | 206 |
| 203 time_source_->SetMediaTime(time); | 207 time_source_->SetMediaTime(time); |
| 204 | 208 |
| 205 if (audio_renderer_) | 209 if (audio_renderer_) |
| 206 audio_renderer_->StartPlaying(); | 210 audio_renderer_->StartPlaying(); |
| 207 if (video_renderer_) | 211 if (video_renderer_) |
| 208 video_renderer_->StartPlayingFrom(time); | 212 video_renderer_->StartPlayingFrom(time); |
| 209 } | 213 } |
| 210 | 214 |
| 211 void RendererImpl::RestartStreamPlayback(DemuxerStream* stream, | 215 void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream, |
| 212 bool enabled, | 216 bool enabled, |
| 213 base::TimeDelta time) { | 217 base::TimeDelta time) { |
| 214 DCHECK(task_runner_->BelongsToCurrentThread()); | 218 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 215 DCHECK(stream); | 219 DCHECK(stream); |
| 216 bool video = (stream->type() == DemuxerStream::VIDEO); | 220 bool video = (stream->type() == DemuxerStream::VIDEO); |
| 217 DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream | 221 DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream |
| 218 << " enabled=" << stream->enabled() << " time=" << time.InSecondsF(); | 222 << " enabled=" << enabled << " time=" << time.InSecondsF(); |
| 219 if ((state_ != STATE_PLAYING) || (audio_ended_ && video_ended_)) | 223 if ((state_ != STATE_PLAYING) || (audio_ended_ && video_ended_)) |
| 220 return; | 224 return; |
| 221 if (stream->type() == DemuxerStream::VIDEO) { | 225 if (stream->type() == DemuxerStream::VIDEO) { |
| 222 DCHECK(video_renderer_); | 226 DCHECK(video_renderer_); |
| 223 if (restarting_video_) | 227 if (restarting_video_) { |
| 228 DVLOG(3) << __func__ << ": postponed stream " << stream | |
| 229 << " status change handling."; | |
| 230 task_runner_->PostDelayedTask( | |
| 231 FROM_HERE, base::Bind(&RendererImpl::OnStreamStatusChanged, | |
| 232 weak_this_, stream, enabled, time), | |
| 233 base::TimeDelta::FromMilliseconds(kStreamStatusHandlingDelayMs)); | |
| 224 return; | 234 return; |
| 235 } | |
| 225 restarting_video_ = true; | 236 restarting_video_ = true; |
| 226 video_renderer_->Flush( | 237 video_renderer_->Flush( |
| 227 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time)); | 238 base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time)); |
| 228 } else if (stream->type() == DemuxerStream::AUDIO) { | 239 } else if (stream->type() == DemuxerStream::AUDIO) { |
| 229 DCHECK(audio_renderer_); | 240 DCHECK(audio_renderer_); |
| 230 DCHECK(time_source_); | 241 DCHECK(time_source_); |
| 231 if (restarting_audio_) | 242 if (restarting_audio_) { |
| 243 DVLOG(3) << __func__ << ": postponed stream " << stream | |
| 244 << " status change handling."; | |
| 245 task_runner_->PostDelayedTask( | |
| 246 FROM_HERE, base::Bind(&RendererImpl::OnStreamStatusChanged, | |
| 247 weak_this_, stream, enabled, time), | |
| 248 base::TimeDelta::FromMilliseconds(kStreamStatusHandlingDelayMs)); | |
| 232 return; | 249 return; |
| 250 } | |
| 233 restarting_audio_ = true; | 251 restarting_audio_ = true; |
| 234 // Stop ticking (transition into paused state) in audio renderer before | 252 // Stop ticking (transition into paused state) in audio renderer before |
| 235 // calling Flush, since after Flush we are going to restart playback by | 253 // calling Flush, since after Flush we are going to restart playback by |
| 236 // calling audio renderer StartPlaying which would fail in playing state. | 254 // calling audio renderer StartPlaying which would fail in playing state. |
| 237 if (time_ticking_) { | 255 if (time_ticking_) { |
| 238 time_ticking_ = false; | 256 time_ticking_ = false; |
| 239 time_source_->StopTicking(); | 257 time_source_->StopTicking(); |
| 240 } | 258 } |
| 241 audio_renderer_->Flush( | 259 audio_renderer_->Flush( |
| 242 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); | 260 base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 | 391 |
| 374 DemuxerStream* audio_stream = | 392 DemuxerStream* audio_stream = |
| 375 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); | 393 demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); |
| 376 if (!audio_stream) { | 394 if (!audio_stream) { |
| 377 audio_renderer_.reset(); | 395 audio_renderer_.reset(); |
| 378 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); | 396 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); |
| 379 return; | 397 return; |
| 380 } | 398 } |
| 381 | 399 |
| 382 audio_stream->SetStreamStatusChangeCB(base::Bind( | 400 audio_stream->SetStreamStatusChangeCB(base::Bind( |
| 383 &RendererImpl::RestartStreamPlayback, weak_this_, audio_stream)); | 401 &RendererImpl::OnStreamStatusChanged, weak_this_, audio_stream)); |
| 384 | 402 |
| 385 audio_renderer_client_.reset( | 403 audio_renderer_client_.reset( |
| 386 new RendererClientInternal(DemuxerStream::AUDIO, this)); | 404 new RendererClientInternal(DemuxerStream::AUDIO, this)); |
| 387 // Note: After the initialization of a renderer, error events from it may | 405 // Note: After the initialization of a renderer, error events from it may |
| 388 // happen at any time and all future calls must guard against STATE_ERROR. | 406 // happen at any time and all future calls must guard against STATE_ERROR. |
| 389 audio_renderer_->Initialize(audio_stream, cdm_context_, | 407 audio_renderer_->Initialize(audio_stream, cdm_context_, |
| 390 audio_renderer_client_.get(), done_cb); | 408 audio_renderer_client_.get(), done_cb); |
| 391 } | 409 } |
| 392 | 410 |
| 393 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) { | 411 void RendererImpl::OnAudioRendererInitializeDone(PipelineStatus status) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 422 | 440 |
| 423 DemuxerStream* video_stream = | 441 DemuxerStream* video_stream = |
| 424 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); | 442 demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); |
| 425 if (!video_stream) { | 443 if (!video_stream) { |
| 426 video_renderer_.reset(); | 444 video_renderer_.reset(); |
| 427 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); | 445 task_runner_->PostTask(FROM_HERE, base::Bind(done_cb, PIPELINE_OK)); |
| 428 return; | 446 return; |
| 429 } | 447 } |
| 430 | 448 |
| 431 video_stream->SetStreamStatusChangeCB(base::Bind( | 449 video_stream->SetStreamStatusChangeCB(base::Bind( |
| 432 &RendererImpl::RestartStreamPlayback, weak_this_, video_stream)); | 450 &RendererImpl::OnStreamStatusChanged, weak_this_, video_stream)); |
| 433 | 451 |
| 434 video_renderer_client_.reset( | 452 video_renderer_client_.reset( |
| 435 new RendererClientInternal(DemuxerStream::VIDEO, this)); | 453 new RendererClientInternal(DemuxerStream::VIDEO, this)); |
| 436 video_renderer_->Initialize( | 454 video_renderer_->Initialize( |
| 437 video_stream, cdm_context_, video_renderer_client_.get(), | 455 video_stream, cdm_context_, video_renderer_client_.get(), |
| 438 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)), | 456 base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)), |
| 439 done_cb); | 457 done_cb); |
| 440 } | 458 } |
| 441 | 459 |
| 442 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) { | 460 void RendererImpl::OnVideoRendererInitializeDone(PipelineStatus status) { |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 834 DCHECK(task_runner_->BelongsToCurrentThread()); | 852 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 835 client_->OnVideoNaturalSizeChange(size); | 853 client_->OnVideoNaturalSizeChange(size); |
| 836 } | 854 } |
| 837 | 855 |
| 838 void RendererImpl::OnVideoOpacityChange(bool opaque) { | 856 void RendererImpl::OnVideoOpacityChange(bool opaque) { |
| 839 DCHECK(task_runner_->BelongsToCurrentThread()); | 857 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 840 client_->OnVideoOpacityChange(opaque); | 858 client_->OnVideoOpacityChange(opaque); |
| 841 } | 859 } |
| 842 | 860 |
| 843 } // namespace media | 861 } // namespace media |
| OLD | NEW |