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