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 3 // found in the LICENSE file. 4 5 #include "chromecast/media/cma/base/buffering_state.h" 6 7 #include <sstream> 8 9 #include "base/logging.h" 10 #include "media/base/buffers.h" 11 12 namespace chromecast { 13 namespace media { 14 15 BufferingConfig::BufferingConfig( 16 base::TimeDelta low_level_threshold, 17 base::TimeDelta high_level_threshold) 18 : low_level_threshold_(low_level_threshold), 19 high_level_threshold_(high_level_threshold) { 20 } 21 22 BufferingConfig::~BufferingConfig() { 23 } 24 25 26 BufferingState::BufferingState( 27 const scoped_refptr<BufferingConfig>& config, 28 const base::Closure& state_changed_cb, 29 const HighLevelBufferCB& high_level_buffer_cb) 30 : config_(config), 31 state_changed_cb_(state_changed_cb), 32 high_level_buffer_cb_(high_level_buffer_cb), 33 state_(kLowLevel), 34 media_time_(::media::kNoTimestamp()), 35 max_rendering_time_(::media::kNoTimestamp()), 36 buffered_time_(::media::kNoTimestamp()) { 37 } 38 39 BufferingState::~BufferingState() { 40 } 41 42 void BufferingState::OnConfigChanged() { 43 state_ = GetBufferLevelState(); 44 } 45 46 void BufferingState::SetMediaTime(base::TimeDelta media_time) { 47 media_time_ = media_time; 48 switch (state_) { 49 case kLowLevel: 50 case kMediumLevel: 51 case kHighLevel: 52 UpdateState(GetBufferLevelState()); 53 break; 54 case kEosReached: 55 break; 56 } 57 } 58 59 void BufferingState::SetMaxRenderingTime(base::TimeDelta max_rendering_time) { 60 max_rendering_time_ = max_rendering_time; 61 } 62 63 base::TimeDelta BufferingState::GetMaxRenderingTime() const { 64 return max_rendering_time_; 65 } 66 67 void BufferingState::SetBufferedTime(base::TimeDelta buffered_time) { 68 buffered_time_ = buffered_time; 69 switch (state_) { 70 case kLowLevel: 71 case kMediumLevel: 72 case kHighLevel: 73 UpdateState(GetBufferLevelState()); 74 break; 75 case kEosReached: 76 break; 77 } 78 } 79 80 void BufferingState::NotifyEos() { 81 UpdateState(kEosReached); 82 } 83 84 void BufferingState::NotifyMaxCapacity(base::TimeDelta buffered_time) { 85 if (media_time_ == ::media::kNoTimestamp() || 86 buffered_time == ::media::kNoTimestamp()) { 87 LOG(WARNING) << "Max capacity with no timestamp"; 88 return; 89 } 90 base::TimeDelta buffer_duration = buffered_time - media_time_; 91 if (buffer_duration < config_->high_level()) 92 high_level_buffer_cb_.Run(buffer_duration); 93 } 94 95 std::string BufferingState::ToString() const { 96 std::ostringstream s; 97 s << "state=" << state_ 98 << " media_time_ms=" << media_time_.InMilliseconds() 99 << " buffered_time_ms=" << buffered_time_.InMilliseconds() 100 << " low_level_ms=" << config_->low_level().InMilliseconds() 101 << " high_level_ms=" << config_->high_level().InMilliseconds(); 102 return s.str(); 103 } 104 105 BufferingState::State BufferingState::GetBufferLevelState() const { 106 if (media_time_ == ::media::kNoTimestamp() || 107 buffered_time_ == ::media::kNoTimestamp()) { 108 return kLowLevel; 109 } 110 111 base::TimeDelta buffer_duration = buffered_time_ - media_time_; 112 if (buffer_duration < config_->low_level()) 113 return kLowLevel; 114 if (buffer_duration >= config_->high_level()) 115 return kHighLevel; 116 return kMediumLevel; 117 } 118 119 void BufferingState::UpdateState(State new_state) { 120 if (new_state == state_) 121 return; 122 123 state_ = new_state; 124 if (!state_changed_cb_.is_null()) 125 state_changed_cb_.Run(); 126 } 127 128 } // namespace media 129 } // namespace chromecast 130