text: /*
   *  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 "modules/audio_coding/neteq/rtcp.h"
  
  #include <stdlib.h>
  #include <string.h>
  
  #include <algorithm>
  
  #include BOSS_WEBRTC_U_modules__include__module_common_types_h //original-code:"modules/include/module_common_types.h"
  
  namespace webrtc {
  
  void Rtcp::Init(uint16_t start_sequence_number) {
    cycles_ = 0;
    max_seq_no_ = start_sequence_number;
    base_seq_no_ = start_sequence_number;
    received_packets_ = 0;
    received_packets_prior_ = 0;
    expected_prior_ = 0;
    jitter_ = 0;
    transit_ = 0;
  }
  
  void Rtcp::Update(const RTPHeader& rtp_header, uint32_t receive_timestamp) {
    // Update number of received packets, and largest packet number received.
    received_packets_++;
    int16_t sn_diff = rtp_header.sequenceNumber - max_seq_no_;
    if (sn_diff >= 0) {
      if (rtp_header.sequenceNumber < max_seq_no_) {
        // Wrap-around detected.
        cycles_++;
      }
      max_seq_no_ = rtp_header.sequenceNumber;
    }
  
    // Calculate jitter according to RFC 3550, and update previous timestamps.
    // Note that the value in |jitter_| is in Q4.
    if (received_packets_ > 1) {
      int32_t ts_diff = receive_timestamp - (rtp_header.timestamp - transit_);
      int64_t jitter_diff = (std::abs(int64_t{ts_diff}) << 4) - jitter_;
      // Calculate 15 * jitter_ / 16 + jitter_diff / 16 (with proper rounding).
      jitter_ = jitter_ + ((jitter_diff + 8) >> 4);
      RTC_DCHECK_GE(jitter_, 0);
    }
    transit_ = rtp_header.timestamp - receive_timestamp;
  }
  
  void Rtcp::GetStatistics(bool no_reset, RtcpStatistics* stats) {
    // Extended highest sequence number received.
    stats->extended_highest_sequence_number =
        (static_cast<int>(cycles_) << 16) + max_seq_no_;
  
    // Calculate expected number of packets and compare it with the number of
    // packets that were actually received. The cumulative number of lost packets
    // can be extracted.
    uint32_t expected_packets =
        stats->extended_highest_sequence_number - base_seq_no_ + 1;
    if (received_packets_ == 0) {
      // No packets received, assume none lost.
      stats->packets_lost = 0;
    } else if (expected_packets > received_packets_) {
      stats->packets_lost = expected_packets - received_packets_;
      if (stats->packets_lost > 0xFFFFFF) {
        stats->packets_lost = 0xFFFFFF;
      }
    } else {
      stats->packets_lost = 0;
    }
  
    // Fraction lost since last report.
    uint32_t expected_since_last = expected_packets - expected_prior_;
    uint32_t received_since_last = received_packets_ - received_packets_prior_;
    if (!no_reset) {
      expected_prior_ = expected_packets;
      received_packets_prior_ = received_packets_;
    }
    int32_t lost = expected_since_last - received_since_last;
    if (expected_since_last == 0 || lost <= 0 || received_packets_ == 0) {
      stats->fraction_lost = 0;
    } else {
      stats->fraction_lost = std::min(0xFFU, (lost << 8) / expected_since_last);
    }
  
    stats->jitter = jitter_ >> 4;  // Scaling from Q4.
  }
  
  }  // namespace webrtc
  