aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/video_coding/inter_frame_delay.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/modules/video_coding/inter_frame_delay.cc')
-rw-r--r--webrtc/modules/video_coding/inter_frame_delay.cc107
1 files changed, 107 insertions, 0 deletions
diff --git a/webrtc/modules/video_coding/inter_frame_delay.cc b/webrtc/modules/video_coding/inter_frame_delay.cc
new file mode 100644
index 0000000000..fb3b54d204
--- /dev/null
+++ b/webrtc/modules/video_coding/inter_frame_delay.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/video_coding/inter_frame_delay.h"
+
+namespace webrtc {
+
+VCMInterFrameDelay::VCMInterFrameDelay(int64_t currentWallClock) {
+ Reset(currentWallClock);
+}
+
+// Resets the delay estimate
+void VCMInterFrameDelay::Reset(int64_t currentWallClock) {
+ _zeroWallClock = currentWallClock;
+ _wrapArounds = 0;
+ _prevWallClock = 0;
+ _prevTimestamp = 0;
+ _dTS = 0;
+}
+
+// Calculates the delay of a frame with the given timestamp.
+// This method is called when the frame is complete.
+bool VCMInterFrameDelay::CalculateDelay(uint32_t timestamp,
+ int64_t* delay,
+ int64_t currentWallClock) {
+ if (_prevWallClock == 0) {
+ // First set of data, initialization, wait for next frame
+ _prevWallClock = currentWallClock;
+ _prevTimestamp = timestamp;
+ *delay = 0;
+ return true;
+ }
+
+ int32_t prevWrapArounds = _wrapArounds;
+ CheckForWrapArounds(timestamp);
+
+ // This will be -1 for backward wrap arounds and +1 for forward wrap arounds
+ int32_t wrapAroundsSincePrev = _wrapArounds - prevWrapArounds;
+
+ // Account for reordering in jitter variance estimate in the future?
+ // Note that this also captures incomplete frames which are grabbed
+ // for decoding after a later frame has been complete, i.e. real
+ // packet losses.
+ if ((wrapAroundsSincePrev == 0 && timestamp < _prevTimestamp) ||
+ wrapAroundsSincePrev < 0) {
+ *delay = 0;
+ return false;
+ }
+
+ // Compute the compensated timestamp difference and convert it to ms and
+ // round it to closest integer.
+ _dTS = static_cast<int64_t>(
+ (timestamp + wrapAroundsSincePrev * (static_cast<int64_t>(1) << 32) -
+ _prevTimestamp) /
+ 90.0 +
+ 0.5);
+
+ // frameDelay is the difference of dT and dTS -- i.e. the difference of
+ // the wall clock time difference and the timestamp difference between
+ // two following frames.
+ *delay = static_cast<int64_t>(currentWallClock - _prevWallClock - _dTS);
+
+ _prevTimestamp = timestamp;
+ _prevWallClock = currentWallClock;
+
+ return true;
+}
+
+// Returns the current difference between incoming timestamps
+uint32_t VCMInterFrameDelay::CurrentTimeStampDiffMs() const {
+ if (_dTS < 0) {
+ return 0;
+ }
+ return static_cast<uint32_t>(_dTS);
+}
+
+// Investigates if the timestamp clock has overflowed since the last timestamp
+// and
+// keeps track of the number of wrap arounds since reset.
+void VCMInterFrameDelay::CheckForWrapArounds(uint32_t timestamp) {
+ if (timestamp < _prevTimestamp) {
+ // This difference will probably be less than -2^31 if we have had a wrap
+ // around
+ // (e.g. timestamp = 1, _previousTimestamp = 2^32 - 1). Since it is cast to
+ // a Word32,
+ // it should be positive.
+ if (static_cast<int32_t>(timestamp - _prevTimestamp) > 0) {
+ // Forward wrap around
+ _wrapArounds++;
+ }
+ // This difference will probably be less than -2^31 if we have had a
+ // backward
+ // wrap around.
+ // Since it is cast to a Word32, it should be positive.
+ } else if (static_cast<int32_t>(_prevTimestamp - timestamp) > 0) {
+ // Backward wrap around
+ _wrapArounds--;
+ }
+}
+} // namespace webrtc