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