1/* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "webrtc/modules/video_coding/inter_frame_delay.h" 12 13namespace webrtc { 14 15VCMInterFrameDelay::VCMInterFrameDelay(int64_t currentWallClock) { 16 Reset(currentWallClock); 17} 18 19// Resets the delay estimate 20void VCMInterFrameDelay::Reset(int64_t currentWallClock) { 21 _zeroWallClock = currentWallClock; 22 _wrapArounds = 0; 23 _prevWallClock = 0; 24 _prevTimestamp = 0; 25 _dTS = 0; 26} 27 28// Calculates the delay of a frame with the given timestamp. 29// This method is called when the frame is complete. 30bool VCMInterFrameDelay::CalculateDelay(uint32_t timestamp, 31 int64_t* delay, 32 int64_t currentWallClock) { 33 if (_prevWallClock == 0) { 34 // First set of data, initialization, wait for next frame 35 _prevWallClock = currentWallClock; 36 _prevTimestamp = timestamp; 37 *delay = 0; 38 return true; 39 } 40 41 int32_t prevWrapArounds = _wrapArounds; 42 CheckForWrapArounds(timestamp); 43 44 // This will be -1 for backward wrap arounds and +1 for forward wrap arounds 45 int32_t wrapAroundsSincePrev = _wrapArounds - prevWrapArounds; 46 47 // Account for reordering in jitter variance estimate in the future? 48 // Note that this also captures incomplete frames which are grabbed 49 // for decoding after a later frame has been complete, i.e. real 50 // packet losses. 51 if ((wrapAroundsSincePrev == 0 && timestamp < _prevTimestamp) || 52 wrapAroundsSincePrev < 0) { 53 *delay = 0; 54 return false; 55 } 56 57 // Compute the compensated timestamp difference and convert it to ms and 58 // round it to closest integer. 59 _dTS = static_cast<int64_t>( 60 (timestamp + wrapAroundsSincePrev * (static_cast<int64_t>(1) << 32) - 61 _prevTimestamp) / 62 90.0 + 63 0.5); 64 65 // frameDelay is the difference of dT and dTS -- i.e. the difference of 66 // the wall clock time difference and the timestamp difference between 67 // two following frames. 68 *delay = static_cast<int64_t>(currentWallClock - _prevWallClock - _dTS); 69 70 _prevTimestamp = timestamp; 71 _prevWallClock = currentWallClock; 72 73 return true; 74} 75 76// Returns the current difference between incoming timestamps 77uint32_t VCMInterFrameDelay::CurrentTimeStampDiffMs() const { 78 if (_dTS < 0) { 79 return 0; 80 } 81 return static_cast<uint32_t>(_dTS); 82} 83 84// Investigates if the timestamp clock has overflowed since the last timestamp 85// and 86// keeps track of the number of wrap arounds since reset. 87void VCMInterFrameDelay::CheckForWrapArounds(uint32_t timestamp) { 88 if (timestamp < _prevTimestamp) { 89 // This difference will probably be less than -2^31 if we have had a wrap 90 // around 91 // (e.g. timestamp = 1, _previousTimestamp = 2^32 - 1). Since it is cast to 92 // a Word32, 93 // it should be positive. 94 if (static_cast<int32_t>(timestamp - _prevTimestamp) > 0) { 95 // Forward wrap around 96 _wrapArounds++; 97 } 98 // This difference will probably be less than -2^31 if we have had a 99 // backward 100 // wrap around. 101 // Since it is cast to a Word32, it should be positive. 102 } else if (static_cast<int32_t>(_prevTimestamp - timestamp) > 0) { 103 // Backward wrap around 104 _wrapArounds--; 105 } 106} 107} // namespace webrtc 108