Home | History | Annotate | Download | only in base
      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 
     15 TimeDeltaInterpolator::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 
     23 TimeDeltaInterpolator::~TimeDeltaInterpolator() {
     24 }
     25 
     26 base::TimeDelta TimeDeltaInterpolator::StartInterpolating() {
     27   DCHECK(!interpolating_);
     28   reference_ = tick_clock_->NowTicks();
     29   interpolating_ = true;
     30   return lower_bound_;
     31 }
     32 
     33 base::TimeDelta TimeDeltaInterpolator::StopInterpolating() {
     34   DCHECK(interpolating_);
     35   lower_bound_ = GetInterpolatedTime();
     36   interpolating_ = false;
     37   return lower_bound_;
     38 }
     39 
     40 void TimeDeltaInterpolator::SetPlaybackRate(float playback_rate) {
     41   lower_bound_ = GetInterpolatedTime();
     42   reference_ = tick_clock_->NowTicks();
     43   playback_rate_ = playback_rate;
     44 }
     45 
     46 void 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 
     56 void 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 
     64 base::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