/*
 *  Copyright (c) 2012 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/modules/rtp_rtcp/source/producer_fec.h"

#include <memory>
#include <utility>

#include "webrtc/base/basictypes.h"
#include "webrtc/base/checks.h"
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"

namespace webrtc {

constexpr size_t kRedForFecHeaderLength = 1;

// This controls the maximum amount of excess overhead (actual - target)
// allowed in order to trigger GenerateFec(), before |params_.max_fec_frames|
// is reached. Overhead here is defined as relative to number of media packets.
constexpr int kMaxExcessOverhead = 50;  // Q8.

// This is the minimum number of media packets required (above some protection
// level) in order to trigger GenerateFec(), before |params_.max_fec_frames| is
// reached.
constexpr size_t kMinMediaPackets = 4;

// Threshold on the received FEC protection level, above which we enforce at
// least |kMinMediaPackets| packets for the FEC code. Below this
// threshold |kMinMediaPackets| is set to default value of 1.
//
// The range is between 0 and 255, where 255 corresponds to 100% overhead
// (relative to the number of protected media packets).
constexpr uint8_t kHighProtectionThreshold = 80;

// This threshold is used to adapt the |kMinMediaPackets| threshold, based
// on the average number of packets per frame seen so far. When there are few
// packets per frame (as given by this threshold), at least
// |kMinMediaPackets| + 1 packets are sent to the FEC code.
constexpr float kMinMediaPacketsAdaptationThreshold = 2.0f;

RedPacket::RedPacket(size_t length)
    : data_(new uint8_t[length]),
      length_(length),
      header_length_(0) {
}

void RedPacket::CreateHeader(const uint8_t* rtp_header,
                             size_t header_length,
                             int red_payload_type,
                             int payload_type) {
  RTC_DCHECK_LE(header_length + kRedForFecHeaderLength, length_);
  memcpy(data_.get(), rtp_header, header_length);
  // Replace payload type.
  data_[1] &= 0x80;
  data_[1] += red_payload_type;
  // Add RED header
  // f-bit always 0
  data_[header_length] = static_cast<uint8_t>(payload_type);
  header_length_ = header_length + kRedForFecHeaderLength;
}

void RedPacket::SetSeqNum(int seq_num) {
  RTC_DCHECK_GE(seq_num, 0);
  RTC_DCHECK_LT(seq_num, 1 << 16);

  ByteWriter<uint16_t>::WriteBigEndian(&data_[2], seq_num);
}

void RedPacket::AssignPayload(const uint8_t* payload, size_t length) {
  RTC_DCHECK_LE(header_length_ + length, length_);
  memcpy(data_.get() + header_length_, payload, length);
}

void RedPacket::ClearMarkerBit() {
  data_[1] &= 0x7F;
}

uint8_t* RedPacket::data() const {
  return data_.get();
}

size_t RedPacket::length() const {
  return length_;
}

ProducerFec::ProducerFec(ForwardErrorCorrection* fec)
    : fec_(fec),
      media_packets_(),
      generated_fec_packets_(),
      num_protected_frames_(0),
      num_important_packets_(0),
      min_num_media_packets_(1),
      params_(),
      new_params_() {
  memset(&params_, 0, sizeof(params_));
  memset(&new_params_, 0, sizeof(new_params_));
}

ProducerFec::~ProducerFec() {
  DeleteMediaPackets();
}

std::unique_ptr<RedPacket> ProducerFec::BuildRedPacket(
    const uint8_t* data_buffer,
    size_t payload_length,
    size_t rtp_header_length,
    int red_payload_type) {
  std::unique_ptr<RedPacket> red_packet(new RedPacket(
      payload_length + kRedForFecHeaderLength + rtp_header_length));
  int payload_type = data_buffer[1] & 0x7f;
  red_packet->CreateHeader(data_buffer, rtp_header_length, red_payload_type,
                           payload_type);
  red_packet->AssignPayload(data_buffer + rtp_header_length, payload_length);
  return red_packet;
}

void ProducerFec::SetFecParameters(const FecProtectionParams* params,
                                   int num_important_packets) {
  // Number of important packets (i.e. number of packets receiving additional
  // protection in 'unequal protection mode') cannot exceed kMaxMediaPackets.
  RTC_DCHECK_GE(params->fec_rate, 0);
  RTC_DCHECK_LE(params->fec_rate, 255);
  if (num_important_packets >
      static_cast<int>(ForwardErrorCorrection::kMaxMediaPackets)) {
    num_important_packets = ForwardErrorCorrection::kMaxMediaPackets;
  }
  // Store the new params and apply them for the next set of FEC packets being
  // produced.
  new_params_ = *params;
  num_important_packets_ = num_important_packets;
  if (params->fec_rate > kHighProtectionThreshold) {
    min_num_media_packets_ = kMinMediaPackets;
  } else {
    min_num_media_packets_ = 1;
  }
}

int ProducerFec::AddRtpPacketAndGenerateFec(const uint8_t* data_buffer,
                                            size_t payload_length,
                                            size_t rtp_header_length) {
  RTC_DCHECK(generated_fec_packets_.empty());
  if (media_packets_.empty()) {
    params_ = new_params_;
  }
  bool complete_frame = false;
  const bool marker_bit = (data_buffer[1] & kRtpMarkerBitMask) ? true : false;
  if (media_packets_.size() < ForwardErrorCorrection::kMaxMediaPackets) {
    // Generic FEC can only protect up to |kMaxMediaPackets| packets.
    std::unique_ptr<ForwardErrorCorrection::Packet> packet(
        new ForwardErrorCorrection::Packet());
    packet->length = payload_length + rtp_header_length;
    memcpy(packet->data, data_buffer, packet->length);
    media_packets_.push_back(std::move(packet));
  }
  if (marker_bit) {
    ++num_protected_frames_;
    complete_frame = true;
  }
  // Produce FEC over at most |params_.max_fec_frames| frames, or as soon as:
  // (1) the excess overhead (actual overhead - requested/target overhead) is
  // less than |kMaxExcessOverhead|, and
  // (2) at least |min_num_media_packets_| media packets is reached.
  if (complete_frame &&
      (num_protected_frames_ == params_.max_fec_frames ||
       (ExcessOverheadBelowMax() && MinimumMediaPacketsReached()))) {
    RTC_DCHECK_LE(num_important_packets_,
                  static_cast<int>(ForwardErrorCorrection::kMaxMediaPackets));
    // TODO(pbos): Consider whether unequal protection should be enabled or not,
    // it is currently always disabled.
    //
    // Since unequal protection is disabled, the value of
    // |num_important_packets_| has no importance when calling GenerateFec().
    constexpr bool kUseUnequalProtection = false;
    int ret = fec_->GenerateFec(media_packets_, params_.fec_rate,
                                num_important_packets_, kUseUnequalProtection,
                                params_.fec_mask_type, &generated_fec_packets_);
    if (generated_fec_packets_.empty()) {
      num_protected_frames_ = 0;
      DeleteMediaPackets();
    }
    return ret;
  }
  return 0;
}

bool ProducerFec::ExcessOverheadBelowMax() const {
  return ((Overhead() - params_.fec_rate) < kMaxExcessOverhead);
}

bool ProducerFec::MinimumMediaPacketsReached() const {
  float average_num_packets_per_frame =
      static_cast<float>(media_packets_.size()) / num_protected_frames_;
  int num_media_packets = static_cast<int>(media_packets_.size());
  if (average_num_packets_per_frame < kMinMediaPacketsAdaptationThreshold) {
    return num_media_packets >= min_num_media_packets_;
  } else {
    // For larger rates (more packets/frame), increase the threshold.
    // TODO(brandtr): Investigate what impact this adaptation has.
    return num_media_packets >= min_num_media_packets_ + 1;
  }
}

bool ProducerFec::FecAvailable() const {
  return !generated_fec_packets_.empty();
}

size_t ProducerFec::NumAvailableFecPackets() const {
  return generated_fec_packets_.size();
}

std::vector<std::unique_ptr<RedPacket>> ProducerFec::GetFecPacketsAsRed(
    int red_payload_type,
    int ulpfec_payload_type,
    uint16_t first_seq_num,
    size_t rtp_header_length) {
  std::vector<std::unique_ptr<RedPacket>> red_packets;
  red_packets.reserve(generated_fec_packets_.size());
  RTC_DCHECK(!media_packets_.empty());
  ForwardErrorCorrection::Packet* last_media_packet =
      media_packets_.back().get();
  uint16_t seq_num = first_seq_num;
  for (const auto& fec_packet : generated_fec_packets_) {
    // Wrap FEC packet (including FEC headers) in a RED packet. Since the
    // FEC packets in |generated_fec_packets_| don't have RTP headers, we
    // reuse the header from the last media packet.
    std::unique_ptr<RedPacket> red_packet(new RedPacket(
        fec_packet->length + kRedForFecHeaderLength + rtp_header_length));
    red_packet->CreateHeader(last_media_packet->data, rtp_header_length,
                             red_payload_type, ulpfec_payload_type);
    red_packet->SetSeqNum(seq_num++);
    red_packet->ClearMarkerBit();
    red_packet->AssignPayload(fec_packet->data, fec_packet->length);

    red_packets.push_back(std::move(red_packet));
  }

  // Reset state.
  DeleteMediaPackets();
  generated_fec_packets_.clear();
  num_protected_frames_ = 0;

  return red_packets;
}

int ProducerFec::Overhead() const {
  // Overhead is defined as relative to the number of media packets, and not
  // relative to total number of packets. This definition is inherited from the
  // protection factor produced by video_coding module and how the FEC
  // generation is implemented.
  RTC_DCHECK(!media_packets_.empty());
  int num_fec_packets =
      fec_->GetNumberOfFecPackets(media_packets_.size(), params_.fec_rate);
  // Return the overhead in Q8.
  return (num_fec_packets << 8) / media_packets_.size();
}

void ProducerFec::DeleteMediaPackets() {
  media_packets_.clear();
}

}  // namespace webrtc
