blob: ab444077f66d5b819d5897e3d6ff4a026567a829 [file] [log] [blame]
// 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 "media/cast/common/clock_drift_smoother.h"
#include "base/logging.h"
#include "starboard/types.h"
namespace cobalt {
namespace media {
namespace cast {
ClockDriftSmoother::ClockDriftSmoother(base::TimeDelta time_constant)
: time_constant_(time_constant), estimate_us_(0.0) {
DCHECK(time_constant_ > base::TimeDelta());
}
ClockDriftSmoother::~ClockDriftSmoother() {}
base::TimeDelta ClockDriftSmoother::Current() const {
DCHECK(!last_update_time_.is_null());
return base::TimeDelta::FromMicroseconds(static_cast<int64_t>(
estimate_us_ + 0.5)); // Round to nearest microsecond.
}
void ClockDriftSmoother::Reset(base::TimeTicks now,
base::TimeDelta measured_offset) {
DCHECK(!now.is_null());
last_update_time_ = now;
estimate_us_ = static_cast<double>(measured_offset.InMicroseconds());
}
void ClockDriftSmoother::Update(base::TimeTicks now,
base::TimeDelta measured_offset) {
DCHECK(!now.is_null());
if (last_update_time_.is_null()) {
Reset(now, measured_offset);
} else if (now < last_update_time_) {
// |now| is not monotonically non-decreasing.
NOTREACHED();
} else {
const double elapsed_us =
static_cast<double>((now - last_update_time_).InMicroseconds());
last_update_time_ = now;
const double weight =
elapsed_us / (elapsed_us + time_constant_.InMicroseconds());
estimate_us_ = weight * measured_offset.InMicroseconds() +
(1.0 - weight) * estimate_us_;
}
}
// static
base::TimeDelta ClockDriftSmoother::GetDefaultTimeConstant() {
static const int kDefaultTimeConstantInSeconds = 30;
return base::TimeDelta::FromSeconds(kDefaultTimeConstantInSeconds);
}
} // namespace cast
} // namespace media
} // namespace cobalt