OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <limits> | |
12 | |
11 #include "webrtc/base/logging.h" | 13 #include "webrtc/base/logging.h" |
12 #include "webrtc/base/timestampaligner.h" | 14 #include "webrtc/base/timestampaligner.h" |
13 | 15 |
14 namespace rtc { | 16 namespace rtc { |
15 | 17 |
16 TimestampAligner::TimestampAligner() : frames_seen_(0), offset_us_(0) {} | 18 TimestampAligner::TimestampAligner() |
19 : frames_seen_(0), | |
20 offset_us_(0), | |
21 clip_bias_us_(0), | |
22 prev_translated_time_us_(std::numeric_limits<int64_t>::min()) {} | |
17 | 23 |
18 TimestampAligner::~TimestampAligner() {} | 24 TimestampAligner::~TimestampAligner() {} |
19 | 25 |
26 int64_t TimestampAligner::TranslateTimestamp(int64_t camera_time_us, | |
27 int64_t system_time_us) { | |
28 return ClipTimestamp( | |
29 camera_time_us + UpdateOffset(camera_time_us, system_time_us), | |
30 system_time_us); | |
31 } | |
32 | |
20 int64_t TimestampAligner::UpdateOffset(int64_t camera_time_us, | 33 int64_t TimestampAligner::UpdateOffset(int64_t camera_time_us, |
21 int64_t system_time_us) { | 34 int64_t system_time_us) { |
22 // Estimate the offset between system monotonic time and the capture | 35 // Estimate the offset between system monotonic time and the capture |
23 // time from the camera. The camera is assumed to provide more | 36 // time from the camera. The camera is assumed to provide more |
24 // accurate timestamps than we get from the system time. But the | 37 // accurate timestamps than we get from the system time. But the |
25 // camera may use its own free-running clock with a large offset and | 38 // camera may use its own free-running clock with a large offset and |
26 // a small drift compared to the system clock. So the model is | 39 // a small drift compared to the system clock. So the model is |
27 // basically | 40 // basically |
28 // | 41 // |
29 // y_k = c_0 + c_1 * x_k + v_k | 42 // y_k = c_0 + c_1 * x_k + v_k |
(...skipping 26 matching lines...) Expand all Loading... | |
56 // exponential averaging. | 69 // exponential averaging. |
57 | 70 |
58 // The input for averaging, y_k - x_k in the above notation. | 71 // The input for averaging, y_k - x_k in the above notation. |
59 int64_t diff_us = system_time_us - camera_time_us; | 72 int64_t diff_us = system_time_us - camera_time_us; |
60 // The deviation from the current average. | 73 // The deviation from the current average. |
61 int64_t error_us = diff_us - offset_us_; | 74 int64_t error_us = diff_us - offset_us_; |
62 | 75 |
63 // If the current difference is far from the currently estimated | 76 // If the current difference is far from the currently estimated |
64 // offset, the filter is reset. This could happen, e.g., if the | 77 // offset, the filter is reset. This could happen, e.g., if the |
65 // camera clock is reset, or cameras are plugged in and out, or if | 78 // camera clock is reset, or cameras are plugged in and out, or if |
66 // the application process is temporarily suspended. The limit of | 79 // the application process is temporarily suspended. Expected to |
67 // 300 ms should make this unlikely in normal operation, and at the | 80 // happen for the very first timestamp (|frames_seen_| = 0), but |
68 // same time, converging gradually rather than resetting the filter | 81 // otherwise very rare. The threshold of 300 ms should make this |
noahric
2016/09/09 23:37:55
I'd remove the "otherwise very rare"; I wouldn't e
nisse-webrtc
2016/09/12 06:58:22
Done.
| |
69 // should be tolerable for jumps in camera time below this | 82 // unlikely in normal operation, and at the same time, converging |
70 // threshold. | 83 // gradually rather than resetting the filter should be tolerable |
71 static const int64_t kResetLimitUs = 300000; | 84 // for jumps in camera time below this threshold. |
72 if (std::abs(error_us) > kResetLimitUs) { | 85 static const int64_t kResetThresholdUs = 300000; |
86 if (std::abs(error_us) > kResetThresholdUs) { | |
73 LOG(LS_INFO) << "Resetting timestamp translation after averaging " | 87 LOG(LS_INFO) << "Resetting timestamp translation after averaging " |
74 << frames_seen_ << " frames. Old offset: " << offset_us_ | 88 << frames_seen_ << " frames. Old offset: " << offset_us_ |
75 << ", new offset: " << diff_us; | 89 << ", new offset: " << diff_us; |
76 frames_seen_ = 0; | 90 frames_seen_ = 0; |
77 prev_translated_time_us_ = rtc::Optional<int64_t>(); | 91 clip_bias_us_ = 0; |
78 } | 92 } |
79 | 93 |
80 static const int kWindowSize = 100; | 94 static const int kWindowSize = 100; |
81 if (frames_seen_ < kWindowSize) { | 95 if (frames_seen_ < kWindowSize) { |
82 ++frames_seen_; | 96 ++frames_seen_; |
83 } | 97 } |
84 offset_us_ += error_us / frames_seen_; | 98 offset_us_ += error_us / frames_seen_; |
85 return offset_us_; | 99 return offset_us_; |
86 } | 100 } |
87 | 101 |
88 int64_t TimestampAligner::ClipTimestamp(int64_t time_us, | 102 int64_t TimestampAligner::ClipTimestamp(int64_t time_us, |
89 int64_t system_time_us) { | 103 int64_t system_time_us) { |
90 // Make timestamps monotonic. | 104 // Make timestamps monotonic. |
91 if (!prev_translated_time_us_) { | 105 if (time_us <= prev_translated_time_us_) { |
92 // Initialize. | 106 time_us = prev_translated_time_us_ + 1; |
noahric
2016/09/09 23:37:55
I'd bump it 1ms, just to make sure it's monotonic
nisse-webrtc
2016/09/12 06:58:22
This makes sense at first.
But should we then al
perkj_webrtc
2016/09/12 09:33:46
We regardless need to drop frames with old ts in l
| |
93 clip_bias_us_ = 0; | |
94 } else if (time_us < *prev_translated_time_us_) { | |
95 time_us = *prev_translated_time_us_; | |
96 } | 107 } |
97 | 108 |
98 // Clip to make sure we don't produce time stamps in the future. | 109 // Clip to make sure we don't produce timestamps in the future. In |
110 // the anomalous case that this function is called multiple times | |
111 // with exactly the same system_time_us, we may also output the same | |
112 // timestamp several times, violating strict monotonicity. | |
noahric
2016/09/09 23:37:55
Since we can detect that, consider logging when it
nisse-webrtc
2016/09/12 06:58:22
Done. Added a DCHECK_GE to check that time_us >= p
| |
99 time_us -= clip_bias_us_; | 113 time_us -= clip_bias_us_; |
100 if (time_us > system_time_us) { | 114 if (time_us > system_time_us) { |
101 clip_bias_us_ += time_us - system_time_us; | 115 clip_bias_us_ += time_us - system_time_us; |
102 time_us = system_time_us; | 116 time_us = system_time_us; |
103 } | 117 } |
104 prev_translated_time_us_ = rtc::Optional<int64_t>(time_us); | 118 prev_translated_time_us_ = time_us; |
105 return time_us; | 119 return time_us; |
106 } | 120 } |
107 | 121 |
108 } // namespace rtc | 122 } // namespace rtc |
OLD | NEW |