// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chromecast/media/cma/base/buffering_state.h" #include <sstream> #include "base/logging.h" #include "media/base/buffers.h" namespace chromecast { namespace media { BufferingConfig::BufferingConfig( base::TimeDelta low_level_threshold, base::TimeDelta high_level_threshold) : low_level_threshold_(low_level_threshold), high_level_threshold_(high_level_threshold) { } BufferingConfig::~BufferingConfig() { } BufferingState::BufferingState( const scoped_refptr<BufferingConfig>& config, const base::Closure& state_changed_cb, const HighLevelBufferCB& high_level_buffer_cb) : config_(config), state_changed_cb_(state_changed_cb), high_level_buffer_cb_(high_level_buffer_cb), state_(kLowLevel), media_time_(::media::kNoTimestamp()), max_rendering_time_(::media::kNoTimestamp()), buffered_time_(::media::kNoTimestamp()) { } BufferingState::~BufferingState() { } void BufferingState::OnConfigChanged() { state_ = GetBufferLevelState(); } void BufferingState::SetMediaTime(base::TimeDelta media_time) { media_time_ = media_time; switch (state_) { case kLowLevel: case kMediumLevel: case kHighLevel: UpdateState(GetBufferLevelState()); break; case kEosReached: break; } } void BufferingState::SetMaxRenderingTime(base::TimeDelta max_rendering_time) { max_rendering_time_ = max_rendering_time; } base::TimeDelta BufferingState::GetMaxRenderingTime() const { return max_rendering_time_; } void BufferingState::SetBufferedTime(base::TimeDelta buffered_time) { buffered_time_ = buffered_time; switch (state_) { case kLowLevel: case kMediumLevel: case kHighLevel: UpdateState(GetBufferLevelState()); break; case kEosReached: break; } } void BufferingState::NotifyEos() { UpdateState(kEosReached); } void BufferingState::NotifyMaxCapacity(base::TimeDelta buffered_time) { if (media_time_ == ::media::kNoTimestamp() || buffered_time == ::media::kNoTimestamp()) { LOG(WARNING) << "Max capacity with no timestamp"; return; } base::TimeDelta buffer_duration = buffered_time - media_time_; if (buffer_duration < config_->high_level()) high_level_buffer_cb_.Run(buffer_duration); } std::string BufferingState::ToString() const { std::ostringstream s; s << "state=" << state_ << " media_time_ms=" << media_time_.InMilliseconds() << " buffered_time_ms=" << buffered_time_.InMilliseconds() << " low_level_ms=" << config_->low_level().InMilliseconds() << " high_level_ms=" << config_->high_level().InMilliseconds(); return s.str(); } BufferingState::State BufferingState::GetBufferLevelState() const { if (media_time_ == ::media::kNoTimestamp() || buffered_time_ == ::media::kNoTimestamp()) { return kLowLevel; } base::TimeDelta buffer_duration = buffered_time_ - media_time_; if (buffer_duration < config_->low_level()) return kLowLevel; if (buffer_duration >= config_->high_level()) return kHighLevel; return kMediumLevel; } void BufferingState::UpdateState(State new_state) { if (new_state == state_) return; state_ = new_state; if (!state_changed_cb_.is_null()) state_changed_cb_.Run(); } } // namespace media } // namespace chromecast