File: clock_drift_smoother.cc

package info (click to toggle)
android-platform-tools 35.0.2-1~exp6
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 211,716 kB
  • sloc: cpp: 995,749; java: 290,495; ansic: 145,647; xml: 58,531; python: 39,608; sh: 14,500; javascript: 5,198; asm: 4,866; makefile: 3,115; yacc: 769; awk: 368; ruby: 183; sql: 140; perl: 88; lex: 67
file content (67 lines) | stat: -rw-r--r-- 2,234 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// 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 "cast/streaming/clock_drift_smoother.h"

#include <cmath>

#include "util/osp_logging.h"
#include "util/saturate_cast.h"

namespace openscreen {
namespace cast {

namespace {
constexpr Clock::time_point kNullTime = Clock::time_point::min();
}

ClockDriftSmoother::ClockDriftSmoother(Clock::duration time_constant)
    : time_constant_(time_constant),
      last_update_time_(kNullTime),
      estimated_tick_offset_(0.0) {
  OSP_DCHECK(time_constant_ > decltype(time_constant_)::zero());
}

ClockDriftSmoother::~ClockDriftSmoother() = default;

Clock::duration ClockDriftSmoother::Current() const {
  OSP_DCHECK(last_update_time_ != kNullTime);
  return Clock::duration(
      rounded_saturate_cast<Clock::duration::rep>(estimated_tick_offset_));
}

void ClockDriftSmoother::Reset(Clock::time_point now,
                               Clock::duration measured_offset) {
  OSP_DCHECK(now != kNullTime);
  last_update_time_ = now;
  estimated_tick_offset_ = static_cast<double>(measured_offset.count());
}

void ClockDriftSmoother::Update(Clock::time_point now,
                                Clock::duration measured_offset) {
  OSP_DCHECK(now != kNullTime);
  if (last_update_time_ == kNullTime) {
    Reset(now, measured_offset);
  } else if (now < last_update_time_) {
    // |now| is not monotonically non-decreasing.
    OSP_NOTREACHED();
  } else {
    const double elapsed_ticks =
        static_cast<double>((now - last_update_time_).count());
    last_update_time_ = now;
    // Compute a weighted-average between the last estimate and
    // |measured_offset|. The more time that has elasped since the last call to
    // Update(), the more-heavily |measured_offset| will be weighed.
    const double weight =
        elapsed_ticks / (elapsed_ticks + time_constant_.count());
    estimated_tick_offset_ = weight * measured_offset.count() +
                             (1.0 - weight) * estimated_tick_offset_;
  }
}

// static
constexpr std::chrono::seconds ClockDriftSmoother::kDefaultTimeConstant;

}  // namespace cast
}  // namespace openscreen