/*
 *  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 "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
