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 "media/base/time_delta_interpolator.h" 6 7 #include <algorithm> 8 9 #include "base/logging.h" 10 #include "base/time/tick_clock.h" 11 #include "media/base/buffers.h" 12 13 namespace media { 14 TimeDeltaInterpolator(base::TickClock * tick_clock)15TimeDeltaInterpolator::TimeDeltaInterpolator(base::TickClock* tick_clock) 16 : tick_clock_(tick_clock), 17 interpolating_(false), 18 upper_bound_(kNoTimestamp()), 19 playback_rate_(1.0f) { 20 DCHECK(tick_clock_); 21 } 22 ~TimeDeltaInterpolator()23TimeDeltaInterpolator::~TimeDeltaInterpolator() { 24 } 25 StartInterpolating()26base::TimeDelta TimeDeltaInterpolator::StartInterpolating() { 27 DCHECK(!interpolating_); 28 reference_ = tick_clock_->NowTicks(); 29 interpolating_ = true; 30 return lower_bound_; 31 } 32 StopInterpolating()33base::TimeDelta TimeDeltaInterpolator::StopInterpolating() { 34 DCHECK(interpolating_); 35 lower_bound_ = GetInterpolatedTime(); 36 interpolating_ = false; 37 return lower_bound_; 38 } 39 SetPlaybackRate(float playback_rate)40void TimeDeltaInterpolator::SetPlaybackRate(float playback_rate) { 41 lower_bound_ = GetInterpolatedTime(); 42 reference_ = tick_clock_->NowTicks(); 43 playback_rate_ = playback_rate; 44 } 45 SetBounds(base::TimeDelta lower_bound,base::TimeDelta upper_bound)46void TimeDeltaInterpolator::SetBounds(base::TimeDelta lower_bound, 47 base::TimeDelta upper_bound) { 48 DCHECK(lower_bound <= upper_bound); 49 DCHECK(lower_bound != kNoTimestamp()); 50 51 lower_bound_ = std::max(base::TimeDelta(), lower_bound); 52 upper_bound_ = std::max(base::TimeDelta(), upper_bound); 53 reference_ = tick_clock_->NowTicks(); 54 } 55 SetUpperBound(base::TimeDelta upper_bound)56void TimeDeltaInterpolator::SetUpperBound(base::TimeDelta upper_bound) { 57 DCHECK(upper_bound != kNoTimestamp()); 58 59 lower_bound_ = GetInterpolatedTime(); 60 reference_ = tick_clock_->NowTicks(); 61 upper_bound_ = upper_bound; 62 } 63 GetInterpolatedTime()64base::TimeDelta TimeDeltaInterpolator::GetInterpolatedTime() { 65 if (!interpolating_) 66 return lower_bound_; 67 68 int64 now_us = (tick_clock_->NowTicks() - reference_).InMicroseconds(); 69 now_us = static_cast<int64>(now_us * playback_rate_); 70 base::TimeDelta interpolated_time = 71 lower_bound_ + base::TimeDelta::FromMicroseconds(now_us); 72 73 if (upper_bound_ == kNoTimestamp()) 74 return interpolated_time; 75 76 return std::min(interpolated_time, upper_bound_); 77 } 78 79 } // namespace media 80