/*
 *  Copyright (c) 2014 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/video_engine/report_block_stats.h"

namespace webrtc {

namespace {
int FractionLost(uint32_t num_lost_sequence_numbers,
                 uint32_t num_sequence_numbers) {
  if (num_sequence_numbers == 0) {
    return 0;
  }
  return ((num_lost_sequence_numbers * 255) + (num_sequence_numbers / 2)) /
      num_sequence_numbers;
}
}  // namespace


// Helper class for rtcp statistics.
ReportBlockStats::ReportBlockStats()
    : num_sequence_numbers_(0),
      num_lost_sequence_numbers_(0) {
}

void ReportBlockStats::Store(const RtcpStatistics& rtcp_stats,
                             uint32_t remote_ssrc,
                             uint32_t source_ssrc) {
  RTCPReportBlock block;
  block.cumulativeLost = rtcp_stats.cumulative_lost;
  block.fractionLost = rtcp_stats.fraction_lost;
  block.extendedHighSeqNum = rtcp_stats.extended_max_sequence_number;
  block.jitter = rtcp_stats.jitter;
  block.remoteSSRC = remote_ssrc;
  block.sourceSSRC = source_ssrc;
  uint32_t num_sequence_numbers = 0;
  uint32_t num_lost_sequence_numbers = 0;
  StoreAndAddPacketIncrement(
      block, &num_sequence_numbers, &num_lost_sequence_numbers);
}

RTCPReportBlock ReportBlockStats::AggregateAndStore(
    const ReportBlockVector& report_blocks) {
  RTCPReportBlock aggregate;
  if (report_blocks.empty()) {
    return aggregate;
  }
  uint32_t num_sequence_numbers = 0;
  uint32_t num_lost_sequence_numbers = 0;
  ReportBlockVector::const_iterator report_block = report_blocks.begin();
  for (; report_block != report_blocks.end(); ++report_block) {
    aggregate.cumulativeLost += report_block->cumulativeLost;
    aggregate.jitter += report_block->jitter;
    StoreAndAddPacketIncrement(*report_block,
                               &num_sequence_numbers,
                               &num_lost_sequence_numbers);
  }

  if (report_blocks.size() == 1) {
    // No aggregation needed.
    return report_blocks[0];
  }
  // Fraction lost since previous report block.
  aggregate.fractionLost =
      FractionLost(num_lost_sequence_numbers, num_sequence_numbers);
  aggregate.jitter = static_cast<uint32_t>(
      (aggregate.jitter + report_blocks.size() / 2) / report_blocks.size());
  return aggregate;
}

void ReportBlockStats::StoreAndAddPacketIncrement(
    const RTCPReportBlock& report_block,
    uint32_t* num_sequence_numbers,
    uint32_t* num_lost_sequence_numbers) {
  // Get diff with previous report block.
  ReportBlockMap::iterator prev_report_block = prev_report_blocks_.find(
        report_block.sourceSSRC);
  if (prev_report_block != prev_report_blocks_.end()) {
    int seq_num_diff = report_block.extendedHighSeqNum -
                       prev_report_block->second.extendedHighSeqNum;
    int cum_loss_diff = report_block.cumulativeLost -
                        prev_report_block->second.cumulativeLost;
    if (seq_num_diff >= 0 && cum_loss_diff >= 0) {
      *num_sequence_numbers += seq_num_diff;
      *num_lost_sequence_numbers += cum_loss_diff;
      // Update total number of packets/lost packets.
      num_sequence_numbers_ += seq_num_diff;
      num_lost_sequence_numbers_ += cum_loss_diff;
    }
  }
  // Store current report block.
  prev_report_blocks_[report_block.sourceSSRC] = report_block;
}

int ReportBlockStats::FractionLostInPercent() const {
  if (num_sequence_numbers_ == 0) {
    return -1;
  }
  return FractionLost(
      num_lost_sequence_numbers_, num_sequence_numbers_) * 100 / 255;
}

}  // namespace webrtc

