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 "chromecast/media/cma/pipeline/media_pipeline_impl.h" | 5 #include "chromecast/media/cma/pipeline/media_pipeline_impl.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 MediaPipelineImpl::MediaPipelineImpl() | 80 MediaPipelineImpl::MediaPipelineImpl() |
81 : cdm_(nullptr), | 81 : cdm_(nullptr), |
82 backend_state_(BACKEND_STATE_UNINITIALIZED), | 82 backend_state_(BACKEND_STATE_UNINITIALIZED), |
83 playback_rate_(1.0f), | 83 playback_rate_(1.0f), |
84 audio_decoder_(nullptr), | 84 audio_decoder_(nullptr), |
85 video_decoder_(nullptr), | 85 video_decoder_(nullptr), |
86 pending_time_update_task_(false), | 86 pending_time_update_task_(false), |
87 statistics_rolling_counter_(0), | 87 statistics_rolling_counter_(0), |
88 audio_bytes_for_bitrate_estimation_(0), | 88 audio_bytes_for_bitrate_estimation_(0), |
89 video_bytes_for_bitrate_estimation_(0), | 89 video_bytes_for_bitrate_estimation_(0), |
90 playback_stalled_(false), | |
91 playback_stalled_notification_sent_(false), | |
90 weak_factory_(this) { | 92 weak_factory_(this) { |
91 CMALOG(kLogControl) << __FUNCTION__; | 93 CMALOG(kLogControl) << __FUNCTION__; |
92 weak_this_ = weak_factory_.GetWeakPtr(); | 94 weak_this_ = weak_factory_.GetWeakPtr(); |
93 thread_checker_.DetachFromThread(); | 95 thread_checker_.DetachFromThread(); |
94 } | 96 } |
95 | 97 |
96 MediaPipelineImpl::~MediaPipelineImpl() { | 98 MediaPipelineImpl::~MediaPipelineImpl() { |
97 CMALOG(kLogControl) << __FUNCTION__; | 99 CMALOG(kLogControl) << __FUNCTION__; |
98 DCHECK(thread_checker_.CalledOnValidThread()); | 100 DCHECK(thread_checker_.CalledOnValidThread()); |
99 | 101 |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
416 metrics::CastMetricsHelper::GetInstance()->RecordApplicationEvent( | 418 metrics::CastMetricsHelper::GetInstance()->RecordApplicationEvent( |
417 "Cast.Platform.Pause"); | 419 "Cast.Platform.Pause"); |
418 } else if (!is_buffering && (backend_state_ == BACKEND_STATE_PAUSED)) { | 420 } else if (!is_buffering && (backend_state_ == BACKEND_STATE_PAUSED)) { |
419 // Once we finish buffering, we need to honour the desired playback rate | 421 // Once we finish buffering, we need to honour the desired playback rate |
420 // (rather than just resuming). This way, if playback was paused while | 422 // (rather than just resuming). This way, if playback was paused while |
421 // buffering, it will remain paused rather than incorrectly resuming. | 423 // buffering, it will remain paused rather than incorrectly resuming. |
422 SetPlaybackRate(playback_rate_); | 424 SetPlaybackRate(playback_rate_); |
423 } | 425 } |
424 } | 426 } |
425 | 427 |
428 void MediaPipelineImpl::CheckForPlaybackStall(base::TimeDelta media_time, | |
429 base::TimeTicks current_stc) { | |
alokp
2016/06/02 00:09:33
DCHECK(media_time >= last_media_time)
ejason
2016/06/03 16:48:47
I added this DCHECK but during my local longevity
| |
430 // Check to see if a stall condition exists. If not, check to see if we need | |
431 // to transition out of the previous stall condition. | |
432 if (media_time != last_media_time_) { | |
433 if (playback_stalled_) { | |
434 // Transition out of the stalled condition. | |
435 base::TimeDelta stall_duration = current_stc - playback_stalled_time_; | |
436 LOG(INFO) << "Transitioning out of stalled state. Stall duration was " | |
alokp
2016/06/02 00:09:33
LOG(INFO) -> CMALOG
ejason
2016/06/03 16:48:47
Done.
| |
437 << stall_duration.InMilliseconds() << " ms"; | |
438 playback_stalled_ = false; | |
439 playback_stalled_notification_sent_ = false; | |
440 } | |
441 return; | |
442 } | |
443 | |
444 // Check to see if this is a new stall condition. | |
445 if (!playback_stalled_) { | |
446 playback_stalled_ = true; | |
447 playback_stalled_time_ = current_stc; | |
448 return; | |
449 } | |
450 | |
451 // If we are in an existing stall, check to see if we've been stalled for more | |
452 // than 2.5 s. If so, send a single notification of the stall event. | |
453 if (!playback_stalled_notification_sent_) { | |
454 base::TimeDelta current_stall_duration = | |
455 current_stc - playback_stalled_time_; | |
456 if (current_stall_duration.InMilliseconds() >= 2500) { | |
alokp
2016/06/02 00:09:33
move 2500 into a constant.
ejason
2016/06/03 16:48:47
Done.
| |
457 LOG(INFO) << "Playback stalled"; | |
458 metrics::CastMetricsHelper::GetInstance()->RecordApplicationEvent( | |
459 "Cast.Platform.PlaybackStall"); | |
460 playback_stalled_notification_sent_ = true; | |
461 } | |
462 return; | |
463 } | |
464 } | |
465 | |
426 void MediaPipelineImpl::UpdateMediaTime() { | 466 void MediaPipelineImpl::UpdateMediaTime() { |
alokp
2016/06/02 00:09:33
verify that this is not scheduled when playback_ra
ejason
2016/06/03 16:48:47
I reviewed the code and it appears to be the case.
| |
427 pending_time_update_task_ = false; | 467 pending_time_update_task_ = false; |
428 if ((backend_state_ != BACKEND_STATE_PLAYING) && | 468 if ((backend_state_ != BACKEND_STATE_PLAYING) && |
429 (backend_state_ != BACKEND_STATE_PAUSED)) | 469 (backend_state_ != BACKEND_STATE_PAUSED)) |
430 return; | 470 return; |
431 | 471 |
432 if (statistics_rolling_counter_ == 0) { | 472 if (statistics_rolling_counter_ == 0) { |
433 if (audio_pipeline_) | 473 if (audio_pipeline_) |
434 audio_pipeline_->UpdateStatistics(); | 474 audio_pipeline_->UpdateStatistics(); |
435 if (video_pipeline_) | 475 if (video_pipeline_) |
436 video_pipeline_->UpdateStatistics(); | 476 video_pipeline_->UpdateStatistics(); |
(...skipping 29 matching lines...) Expand all Loading... | |
466 media_pipeline_backend_->GetCurrentPts()); | 506 media_pipeline_backend_->GetCurrentPts()); |
467 if (media_time == ::media::kNoTimestamp()) { | 507 if (media_time == ::media::kNoTimestamp()) { |
468 pending_time_update_task_ = true; | 508 pending_time_update_task_ = true; |
469 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 509 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
470 FROM_HERE, base::Bind(&MediaPipelineImpl::UpdateMediaTime, weak_this_), | 510 FROM_HERE, base::Bind(&MediaPipelineImpl::UpdateMediaTime, weak_this_), |
471 kTimeUpdateInterval); | 511 kTimeUpdateInterval); |
472 return; | 512 return; |
473 } | 513 } |
474 base::TimeTicks stc = base::TimeTicks::Now(); | 514 base::TimeTicks stc = base::TimeTicks::Now(); |
475 | 515 |
516 CheckForPlaybackStall(media_time, stc); | |
517 | |
476 base::TimeDelta max_rendering_time = media_time; | 518 base::TimeDelta max_rendering_time = media_time; |
477 if (buffering_controller_) { | 519 if (buffering_controller_) { |
478 buffering_controller_->SetMediaTime(media_time); | 520 buffering_controller_->SetMediaTime(media_time); |
479 | 521 |
480 // Receiving the same time twice in a row means playback isn't moving, | 522 // Receiving the same time twice in a row means playback isn't moving, |
481 // so don't interpolate ahead. | 523 // so don't interpolate ahead. |
482 if (media_time != last_media_time_) { | 524 if (media_time != last_media_time_) { |
483 max_rendering_time = buffering_controller_->GetMaxRenderingTime(); | 525 max_rendering_time = buffering_controller_->GetMaxRenderingTime(); |
484 if (max_rendering_time == ::media::kNoTimestamp()) | 526 if (max_rendering_time == ::media::kNoTimestamp()) |
485 max_rendering_time = media_time; | 527 max_rendering_time = media_time; |
(...skipping 27 matching lines...) Expand all Loading... | |
513 | 555 |
514 void MediaPipelineImpl::ResetBitrateState() { | 556 void MediaPipelineImpl::ResetBitrateState() { |
515 elapsed_time_delta_ = base::TimeDelta::FromSeconds(0); | 557 elapsed_time_delta_ = base::TimeDelta::FromSeconds(0); |
516 audio_bytes_for_bitrate_estimation_ = 0; | 558 audio_bytes_for_bitrate_estimation_ = 0; |
517 video_bytes_for_bitrate_estimation_ = 0; | 559 video_bytes_for_bitrate_estimation_ = 0; |
518 last_sample_time_ = base::TimeTicks::Now(); | 560 last_sample_time_ = base::TimeTicks::Now(); |
519 } | 561 } |
520 | 562 |
521 } // namespace media | 563 } // namespace media |
522 } // namespace chromecast | 564 } // namespace chromecast |
OLD | NEW |