/*
 *  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/rtp_rtcp_impl.h"

#include <string.h>

#include <set>
#include <string>

#include "webrtc/base/checks.h"
#include "webrtc/base/logging.h"
#include "webrtc/common_types.h"
#include "webrtc/config.h"
#include "webrtc/system_wrappers/include/trace.h"

#ifdef _WIN32
// Disable warning C4355: 'this' : used in base member initializer list.
#pragma warning(disable : 4355)
#endif

namespace webrtc {

RTPExtensionType StringToRtpExtensionType(const std::string& extension) {
  if (extension == RtpExtension::kTimestampOffsetUri)
    return kRtpExtensionTransmissionTimeOffset;
  if (extension == RtpExtension::kAudioLevelUri)
    return kRtpExtensionAudioLevel;
  if (extension == RtpExtension::kAbsSendTimeUri)
    return kRtpExtensionAbsoluteSendTime;
  if (extension == RtpExtension::kVideoRotationUri)
    return kRtpExtensionVideoRotation;
  if (extension == RtpExtension::kTransportSequenceNumberUri)
    return kRtpExtensionTransportSequenceNumber;
  if (extension == RtpExtension::kPlayoutDelayUri)
    return kRtpExtensionPlayoutDelay;
  RTC_NOTREACHED() << "Looking up unsupported RTP extension.";
  return kRtpExtensionNone;
}

RtpRtcp::Configuration::Configuration()
    : audio(false),
      receiver_only(false),
      clock(nullptr),
      receive_statistics(NullObjectReceiveStatistics()),
      outgoing_transport(nullptr),
      intra_frame_callback(nullptr),
      bandwidth_callback(nullptr),
      transport_feedback_callback(nullptr),
      rtt_stats(nullptr),
      rtcp_packet_type_counter_observer(nullptr),
      remote_bitrate_estimator(nullptr),
      paced_sender(nullptr),
      transport_sequence_number_allocator(nullptr),
      send_bitrate_observer(nullptr),
      send_frame_count_observer(nullptr),
      send_side_delay_observer(nullptr),
      event_log(nullptr),
      send_packet_observer(nullptr) {}

RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) {
  if (configuration.clock) {
    return new ModuleRtpRtcpImpl(configuration);
  } else {
    // No clock implementation provided, use default clock.
    RtpRtcp::Configuration configuration_copy;
    memcpy(&configuration_copy, &configuration,
           sizeof(RtpRtcp::Configuration));
    configuration_copy.clock = Clock::GetRealTimeClock();
    return new ModuleRtpRtcpImpl(configuration_copy);
  }
}

ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
    : rtp_sender_(configuration.audio,
                  configuration.clock,
                  configuration.outgoing_transport,
                  configuration.paced_sender,
                  configuration.transport_sequence_number_allocator,
                  configuration.transport_feedback_callback,
                  configuration.send_bitrate_observer,
                  configuration.send_frame_count_observer,
                  configuration.send_side_delay_observer,
                  configuration.event_log,
                  configuration.send_packet_observer),
      rtcp_sender_(configuration.audio,
                   configuration.clock,
                   configuration.receive_statistics,
                   configuration.rtcp_packet_type_counter_observer,
                   configuration.event_log,
                   configuration.outgoing_transport),
      rtcp_receiver_(configuration.clock,
                     configuration.receiver_only,
                     configuration.rtcp_packet_type_counter_observer,
                     configuration.bandwidth_callback,
                     configuration.intra_frame_callback,
                     configuration.transport_feedback_callback,
                     this),
      clock_(configuration.clock),
      audio_(configuration.audio),
      collision_detected_(false),
      last_process_time_(configuration.clock->TimeInMilliseconds()),
      last_bitrate_process_time_(configuration.clock->TimeInMilliseconds()),
      last_rtt_process_time_(configuration.clock->TimeInMilliseconds()),
      packet_overhead_(28),  // IPV4 UDP.
      nack_last_time_sent_full_(0),
      nack_last_time_sent_full_prev_(0),
      nack_last_seq_number_sent_(0),
      key_frame_req_method_(kKeyFrameReqPliRtcp),
      remote_bitrate_(configuration.remote_bitrate_estimator),
      rtt_stats_(configuration.rtt_stats),
      rtt_ms_(0) {
  // Make sure that RTCP objects are aware of our SSRC.
  uint32_t SSRC = rtp_sender_.SSRC();
  rtcp_sender_.SetSSRC(SSRC);
  SetRtcpReceiverSsrcs(SSRC);
  SetMaxTransferUnit(IP_PACKET_SIZE);
}

// Returns the number of milliseconds until the module want a worker thread
// to call Process.
int64_t ModuleRtpRtcpImpl::TimeUntilNextProcess() {
  const int64_t now = clock_->TimeInMilliseconds();
  const int64_t kRtpRtcpMaxIdleTimeProcessMs = 5;
  return kRtpRtcpMaxIdleTimeProcessMs - (now - last_process_time_);
}

// Process any pending tasks such as timeouts (non time critical events).
void ModuleRtpRtcpImpl::Process() {
  const int64_t now = clock_->TimeInMilliseconds();
  last_process_time_ = now;

  const int64_t kRtpRtcpBitrateProcessTimeMs = 10;
  if (now >= last_bitrate_process_time_ + kRtpRtcpBitrateProcessTimeMs) {
    rtp_sender_.ProcessBitrate();
    last_bitrate_process_time_ = now;
  }

  const int64_t kRtpRtcpRttProcessTimeMs = 1000;
  bool process_rtt = now >= last_rtt_process_time_ + kRtpRtcpRttProcessTimeMs;
  if (rtcp_sender_.Sending()) {
    // Process RTT if we have received a receiver report and we haven't
    // processed RTT for at least |kRtpRtcpRttProcessTimeMs| milliseconds.
    if (rtcp_receiver_.LastReceivedReceiverReport() >
        last_rtt_process_time_ && process_rtt) {
      std::vector<RTCPReportBlock> receive_blocks;
      rtcp_receiver_.StatisticsReceived(&receive_blocks);
      int64_t max_rtt = 0;
      for (std::vector<RTCPReportBlock>::iterator it = receive_blocks.begin();
           it != receive_blocks.end(); ++it) {
        int64_t rtt = 0;
        rtcp_receiver_.RTT(it->remoteSSRC, &rtt, NULL, NULL, NULL);
        max_rtt = (rtt > max_rtt) ? rtt : max_rtt;
      }
      // Report the rtt.
      if (rtt_stats_ && max_rtt != 0)
        rtt_stats_->OnRttUpdate(max_rtt);
    }

    // Verify receiver reports are delivered and the reported sequence number
    // is increasing.
    int64_t rtcp_interval = RtcpReportInterval();
    if (rtcp_receiver_.RtcpRrTimeout(rtcp_interval)) {
      LOG_F(LS_WARNING) << "Timeout: No RTCP RR received.";
    } else if (rtcp_receiver_.RtcpRrSequenceNumberTimeout(rtcp_interval)) {
      LOG_F(LS_WARNING) <<
          "Timeout: No increase in RTCP RR extended highest sequence number.";
    }

    if (remote_bitrate_ && rtcp_sender_.TMMBR()) {
      unsigned int target_bitrate = 0;
      std::vector<unsigned int> ssrcs;
      if (remote_bitrate_->LatestEstimate(&ssrcs, &target_bitrate)) {
        if (!ssrcs.empty()) {
          target_bitrate = target_bitrate / ssrcs.size();
        }
        rtcp_sender_.SetTargetBitrate(target_bitrate);
      }
    }
  } else {
    // Report rtt from receiver.
    if (process_rtt) {
       int64_t rtt_ms;
       if (rtt_stats_ && rtcp_receiver_.GetAndResetXrRrRtt(&rtt_ms)) {
         rtt_stats_->OnRttUpdate(rtt_ms);
       }
    }
  }

  // Get processed rtt.
  if (process_rtt) {
    last_rtt_process_time_ = now;
    if (rtt_stats_) {
      // Make sure we have a valid RTT before setting.
      int64_t last_rtt = rtt_stats_->LastProcessedRtt();
      if (last_rtt >= 0)
        set_rtt_ms(last_rtt);
    }
  }

  // For sending streams, make sure to not send a SR before media has been sent.
  if (rtcp_sender_.TimeToSendRTCPReport()) {
    RTCPSender::FeedbackState state = GetFeedbackState();
    // Prevent sending streams to send SR before any media has been sent.
    if (!rtcp_sender_.Sending() || state.packets_sent > 0)
      rtcp_sender_.SendRTCP(state, kRtcpReport);
  }

  if (UpdateRTCPReceiveInformationTimers()) {
    // A receiver has timed out
    rtcp_receiver_.UpdateTMMBR();
  }
}

void ModuleRtpRtcpImpl::SetRtxSendStatus(int mode) {
  rtp_sender_.SetRtxStatus(mode);
}

int ModuleRtpRtcpImpl::RtxSendStatus() const {
  return rtp_sender_.RtxStatus();
}

void ModuleRtpRtcpImpl::SetRtxSsrc(uint32_t ssrc) {
  rtp_sender_.SetRtxSsrc(ssrc);
}

void ModuleRtpRtcpImpl::SetRtxSendPayloadType(int payload_type,
                                              int associated_payload_type) {
  rtp_sender_.SetRtxPayloadType(payload_type, associated_payload_type);
}

int32_t ModuleRtpRtcpImpl::IncomingRtcpPacket(
    const uint8_t* rtcp_packet,
    const size_t length) {
  // Allow receive of non-compound RTCP packets.
  RTCPUtility::RTCPParserV2 rtcp_parser(rtcp_packet, length, true);

  const bool valid_rtcpheader = rtcp_parser.IsValid();
  if (!valid_rtcpheader) {
    LOG(LS_WARNING) << "Incoming invalid RTCP packet";
    return -1;
  }
  RTCPHelp::RTCPPacketInformation rtcp_packet_information;
  int32_t ret_val = rtcp_receiver_.IncomingRTCPPacket(
      rtcp_packet_information, &rtcp_parser);
  if (ret_val == 0) {
    rtcp_receiver_.TriggerCallbacksFromRTCPPacket(rtcp_packet_information);
  }
  return ret_val;
}

int32_t ModuleRtpRtcpImpl::RegisterSendPayload(
    const CodecInst& voice_codec) {
  return rtp_sender_.RegisterPayload(
           voice_codec.plname,
           voice_codec.pltype,
           voice_codec.plfreq,
           voice_codec.channels,
           (voice_codec.rate < 0) ? 0 : voice_codec.rate);
}

int32_t ModuleRtpRtcpImpl::RegisterSendPayload(const VideoCodec& video_codec) {
  return rtp_sender_.RegisterPayload(video_codec.plName, video_codec.plType,
                                     90000, 0, 0);
}

void ModuleRtpRtcpImpl::RegisterVideoSendPayload(int payload_type,
                                                 const char* payload_name) {
  RTC_CHECK_EQ(
      0, rtp_sender_.RegisterPayload(payload_name, payload_type, 90000, 0, 0));
}

int32_t ModuleRtpRtcpImpl::DeRegisterSendPayload(const int8_t payload_type) {
  return rtp_sender_.DeRegisterSendPayload(payload_type);
}

int8_t ModuleRtpRtcpImpl::SendPayloadType() const {
  return rtp_sender_.SendPayloadType();
}

uint32_t ModuleRtpRtcpImpl::StartTimestamp() const {
  return rtp_sender_.StartTimestamp();
}

// Configure start timestamp, default is a random number.
void ModuleRtpRtcpImpl::SetStartTimestamp(const uint32_t timestamp) {
  rtcp_sender_.SetStartTimestamp(timestamp);
  rtp_sender_.SetStartTimestamp(timestamp, true);
}

uint16_t ModuleRtpRtcpImpl::SequenceNumber() const {
  return rtp_sender_.SequenceNumber();
}

// Set SequenceNumber, default is a random number.
void ModuleRtpRtcpImpl::SetSequenceNumber(const uint16_t seq_num) {
  rtp_sender_.SetSequenceNumber(seq_num);
}

void ModuleRtpRtcpImpl::SetRtpState(const RtpState& rtp_state) {
  SetStartTimestamp(rtp_state.start_timestamp);
  rtp_sender_.SetRtpState(rtp_state);
}

void ModuleRtpRtcpImpl::SetRtxState(const RtpState& rtp_state) {
  rtp_sender_.SetRtxRtpState(rtp_state);
}

RtpState ModuleRtpRtcpImpl::GetRtpState() const {
  return rtp_sender_.GetRtpState();
}

RtpState ModuleRtpRtcpImpl::GetRtxState() const {
  return rtp_sender_.GetRtxRtpState();
}

uint32_t ModuleRtpRtcpImpl::SSRC() const {
  return rtp_sender_.SSRC();
}

// Configure SSRC, default is a random number.
void ModuleRtpRtcpImpl::SetSSRC(const uint32_t ssrc) {
  rtp_sender_.SetSSRC(ssrc);
  rtcp_sender_.SetSSRC(ssrc);
  SetRtcpReceiverSsrcs(ssrc);
}

void ModuleRtpRtcpImpl::SetCsrcs(const std::vector<uint32_t>& csrcs) {
  rtcp_sender_.SetCsrcs(csrcs);
  rtp_sender_.SetCsrcs(csrcs);
}

// TODO(pbos): Handle media and RTX streams separately (separate RTCP
// feedbacks).
RTCPSender::FeedbackState ModuleRtpRtcpImpl::GetFeedbackState() {
  StreamDataCounters rtp_stats;
  StreamDataCounters rtx_stats;
  rtp_sender_.GetDataCounters(&rtp_stats, &rtx_stats);

  RTCPSender::FeedbackState state;
  state.send_payload_type = SendPayloadType();
  state.frequency_hz = CurrentSendFrequencyHz();
  state.packets_sent = rtp_stats.transmitted.packets +
                       rtx_stats.transmitted.packets;
  state.media_bytes_sent = rtp_stats.transmitted.payload_bytes +
                           rtx_stats.transmitted.payload_bytes;
  state.module = this;

  LastReceivedNTP(&state.last_rr_ntp_secs,
                  &state.last_rr_ntp_frac,
                  &state.remote_sr);

  state.has_last_xr_rr = LastReceivedXrReferenceTimeInfo(&state.last_xr_rr);

  uint32_t tmp;
  BitrateSent(&state.send_bitrate, &tmp, &tmp, &tmp);
  return state;
}

int ModuleRtpRtcpImpl::CurrentSendFrequencyHz() const {
  return rtp_sender_.SendPayloadFrequency();
}

int32_t ModuleRtpRtcpImpl::SetSendingStatus(const bool sending) {
  if (rtcp_sender_.Sending() != sending) {
    // Sends RTCP BYE when going from true to false
    if (rtcp_sender_.SetSendingStatus(GetFeedbackState(), sending) != 0) {
      LOG(LS_WARNING) << "Failed to send RTCP BYE";
    }

    collision_detected_ = false;

    // Generate a new time_stamp if true and not configured via API
    // Generate a new SSRC for the next "call" if false
    rtp_sender_.SetSendingStatus(sending);
    if (sending) {
      // Make sure the RTCP sender has the same timestamp offset.
      rtcp_sender_.SetStartTimestamp(rtp_sender_.StartTimestamp());
    }

    // Make sure that RTCP objects are aware of our SSRC (it could have changed
    // Due to collision)
    uint32_t SSRC = rtp_sender_.SSRC();
    rtcp_sender_.SetSSRC(SSRC);
    SetRtcpReceiverSsrcs(SSRC);

    return 0;
  }
  return 0;
}

bool ModuleRtpRtcpImpl::Sending() const {
  return rtcp_sender_.Sending();
}

void ModuleRtpRtcpImpl::SetSendingMediaStatus(const bool sending) {
  rtp_sender_.SetSendingMediaStatus(sending);
}

bool ModuleRtpRtcpImpl::SendingMedia() const {
  return rtp_sender_.SendingMedia();
}

int32_t ModuleRtpRtcpImpl::SendOutgoingData(
    FrameType frame_type,
    int8_t payload_type,
    uint32_t time_stamp,
    int64_t capture_time_ms,
    const uint8_t* payload_data,
    size_t payload_size,
    const RTPFragmentationHeader* fragmentation,
    const RTPVideoHeader* rtp_video_hdr) {
  rtcp_sender_.SetLastRtpTime(time_stamp, capture_time_ms);
  // Make sure an RTCP report isn't queued behind a key frame.
  if (rtcp_sender_.TimeToSendRTCPReport(kVideoFrameKey == frame_type)) {
      rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpReport);
  }
  return rtp_sender_.SendOutgoingData(
      frame_type, payload_type, time_stamp, capture_time_ms, payload_data,
      payload_size, fragmentation, rtp_video_hdr);
}

bool ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc,
                                         uint16_t sequence_number,
                                         int64_t capture_time_ms,
                                         bool retransmission,
                                         int probe_cluster_id) {
  if (SendingMedia() && ssrc == rtp_sender_.SSRC()) {
    return rtp_sender_.TimeToSendPacket(sequence_number, capture_time_ms,
                                        retransmission, probe_cluster_id);
  }
  // No RTP sender is interested in sending this packet.
  return true;
}

size_t ModuleRtpRtcpImpl::TimeToSendPadding(size_t bytes,
                                            int probe_cluster_id) {
  return rtp_sender_.TimeToSendPadding(bytes, probe_cluster_id);
}

uint16_t ModuleRtpRtcpImpl::MaxPayloadLength() const {
  return rtp_sender_.MaxPayloadLength();
}

uint16_t ModuleRtpRtcpImpl::MaxDataPayloadLength() const {
  return rtp_sender_.MaxDataPayloadLength();
}

int32_t ModuleRtpRtcpImpl::SetTransportOverhead(
    const bool tcp,
    const bool ipv6,
    const uint8_t authentication_overhead) {
  uint16_t packet_overhead = 0;
  if (ipv6) {
    packet_overhead = 40;
  } else {
    packet_overhead = 20;
  }
  if (tcp) {
    // TCP.
    packet_overhead += 20;
  } else {
    // UDP.
    packet_overhead += 8;
  }
  packet_overhead += authentication_overhead;

  if (packet_overhead == packet_overhead_) {
    // Ok same as before.
    return 0;
  }

  size_t mtu = rtp_sender_.MaxPayloadLength() + packet_overhead_;
  size_t max_payload_length = mtu - packet_overhead;
  packet_overhead_ = packet_overhead;
  rtcp_sender_.SetMaxPayloadLength(max_payload_length);
  rtp_sender_.SetMaxPayloadLength(max_payload_length);
  return 0;
}

int32_t ModuleRtpRtcpImpl::SetMaxTransferUnit(uint16_t mtu) {
  RTC_DCHECK_LE(mtu, IP_PACKET_SIZE) << "MTU too large: " << mtu;
  RTC_DCHECK_GT(mtu, packet_overhead_) << "MTU too small: " << mtu;
  size_t max_payload_length = mtu - packet_overhead_;
  rtcp_sender_.SetMaxPayloadLength(max_payload_length);
  rtp_sender_.SetMaxPayloadLength(max_payload_length);
  return 0;
}

RtcpMode ModuleRtpRtcpImpl::RTCP() const {
  return rtcp_sender_.Status();
}

// Configure RTCP status i.e on/off.
void ModuleRtpRtcpImpl::SetRTCPStatus(const RtcpMode method) {
  rtcp_sender_.SetRTCPStatus(method);
}

int32_t ModuleRtpRtcpImpl::SetCNAME(const char* c_name) {
  return rtcp_sender_.SetCNAME(c_name);
}

int32_t ModuleRtpRtcpImpl::AddMixedCNAME(uint32_t ssrc, const char* c_name) {
  return rtcp_sender_.AddMixedCNAME(ssrc, c_name);
}

int32_t ModuleRtpRtcpImpl::RemoveMixedCNAME(const uint32_t ssrc) {
  return rtcp_sender_.RemoveMixedCNAME(ssrc);
}

int32_t ModuleRtpRtcpImpl::RemoteCNAME(
    const uint32_t remote_ssrc,
    char c_name[RTCP_CNAME_SIZE]) const {
  return rtcp_receiver_.CNAME(remote_ssrc, c_name);
}

int32_t ModuleRtpRtcpImpl::RemoteNTP(
    uint32_t* received_ntpsecs,
    uint32_t* received_ntpfrac,
    uint32_t* rtcp_arrival_time_secs,
    uint32_t* rtcp_arrival_time_frac,
    uint32_t* rtcp_timestamp) const {
  return rtcp_receiver_.NTP(received_ntpsecs,
                            received_ntpfrac,
                            rtcp_arrival_time_secs,
                            rtcp_arrival_time_frac,
                            rtcp_timestamp)
             ? 0
             : -1;
}

// Get RoundTripTime.
int32_t ModuleRtpRtcpImpl::RTT(const uint32_t remote_ssrc,
                               int64_t* rtt,
                               int64_t* avg_rtt,
                               int64_t* min_rtt,
                               int64_t* max_rtt) const {
  int32_t ret = rtcp_receiver_.RTT(remote_ssrc, rtt, avg_rtt, min_rtt, max_rtt);
  if (rtt && *rtt == 0) {
    // Try to get RTT from RtcpRttStats class.
    *rtt = rtt_ms();
  }
  return ret;
}

// Force a send of an RTCP packet.
// Normal SR and RR are triggered via the process function.
int32_t ModuleRtpRtcpImpl::SendRTCP(RTCPPacketType packet_type) {
  return rtcp_sender_.SendRTCP(GetFeedbackState(), packet_type);
}

// Force a send of an RTCP packet.
// Normal SR and RR are triggered via the process function.
int32_t ModuleRtpRtcpImpl::SendCompoundRTCP(
    const std::set<RTCPPacketType>& packet_types) {
  return rtcp_sender_.SendCompoundRTCP(GetFeedbackState(), packet_types);
}

int32_t ModuleRtpRtcpImpl::SetRTCPApplicationSpecificData(
    const uint8_t sub_type,
    const uint32_t name,
    const uint8_t* data,
    const uint16_t length) {
  return  rtcp_sender_.SetApplicationSpecificData(sub_type, name, data, length);
}

// (XR) VOIP metric.
int32_t ModuleRtpRtcpImpl::SetRTCPVoIPMetrics(
  const RTCPVoIPMetric* voip_metric) {
  return  rtcp_sender_.SetRTCPVoIPMetrics(voip_metric);
}

void ModuleRtpRtcpImpl::SetRtcpXrRrtrStatus(bool enable) {
  rtcp_receiver_.SetRtcpXrRrtrStatus(enable);
  rtcp_sender_.SendRtcpXrReceiverReferenceTime(enable);
}

bool ModuleRtpRtcpImpl::RtcpXrRrtrStatus() const {
  return rtcp_sender_.RtcpXrReceiverReferenceTime();
}

// TODO(asapersson): Replace this method with the one below.
int32_t ModuleRtpRtcpImpl::DataCountersRTP(
    size_t* bytes_sent,
    uint32_t* packets_sent) const {
  StreamDataCounters rtp_stats;
  StreamDataCounters rtx_stats;
  rtp_sender_.GetDataCounters(&rtp_stats, &rtx_stats);

  if (bytes_sent) {
    *bytes_sent = rtp_stats.transmitted.payload_bytes +
                  rtp_stats.transmitted.padding_bytes +
                  rtp_stats.transmitted.header_bytes +
                  rtx_stats.transmitted.payload_bytes +
                  rtx_stats.transmitted.padding_bytes +
                  rtx_stats.transmitted.header_bytes;
  }
  if (packets_sent) {
    *packets_sent = rtp_stats.transmitted.packets +
                    rtx_stats.transmitted.packets;
  }
  return 0;
}

void ModuleRtpRtcpImpl::GetSendStreamDataCounters(
    StreamDataCounters* rtp_counters,
    StreamDataCounters* rtx_counters) const {
  rtp_sender_.GetDataCounters(rtp_counters, rtx_counters);
}

void ModuleRtpRtcpImpl::GetRtpPacketLossStats(
    bool outgoing,
    uint32_t ssrc,
    struct RtpPacketLossStats* loss_stats) const {
  if (!loss_stats) return;
  const PacketLossStats* stats_source = NULL;
  if (outgoing) {
    if (SSRC() == ssrc) {
      stats_source = &send_loss_stats_;
    }
  } else {
    if (rtcp_receiver_.RemoteSSRC() == ssrc) {
      stats_source = &receive_loss_stats_;
    }
  }
  if (stats_source) {
    loss_stats->single_packet_loss_count =
        stats_source->GetSingleLossCount();
    loss_stats->multiple_packet_loss_event_count =
        stats_source->GetMultipleLossEventCount();
    loss_stats->multiple_packet_loss_packet_count =
        stats_source->GetMultipleLossPacketCount();
  }
}

int32_t ModuleRtpRtcpImpl::RemoteRTCPStat(RTCPSenderInfo* sender_info) {
  return rtcp_receiver_.SenderInfoReceived(sender_info);
}

// Received RTCP report.
int32_t ModuleRtpRtcpImpl::RemoteRTCPStat(
    std::vector<RTCPReportBlock>* receive_blocks) const {
  return rtcp_receiver_.StatisticsReceived(receive_blocks);
}

// (REMB) Receiver Estimated Max Bitrate.
bool ModuleRtpRtcpImpl::REMB() const {
  return rtcp_sender_.REMB();
}

void ModuleRtpRtcpImpl::SetREMBStatus(const bool enable) {
  rtcp_sender_.SetREMBStatus(enable);
}

void ModuleRtpRtcpImpl::SetREMBData(const uint32_t bitrate,
                                    const std::vector<uint32_t>& ssrcs) {
  rtcp_sender_.SetREMBData(bitrate, ssrcs);
}

int32_t ModuleRtpRtcpImpl::RegisterSendRtpHeaderExtension(
    const RTPExtensionType type,
    const uint8_t id) {
  return rtp_sender_.RegisterRtpHeaderExtension(type, id);
}

int32_t ModuleRtpRtcpImpl::DeregisterSendRtpHeaderExtension(
    const RTPExtensionType type) {
  return rtp_sender_.DeregisterRtpHeaderExtension(type);
}

// (TMMBR) Temporary Max Media Bit Rate.
bool ModuleRtpRtcpImpl::TMMBR() const {
  return rtcp_sender_.TMMBR();
}

void ModuleRtpRtcpImpl::SetTMMBRStatus(const bool enable) {
  rtcp_sender_.SetTMMBRStatus(enable);
}

void ModuleRtpRtcpImpl::SetTMMBN(
    const std::vector<rtcp::TmmbItem>* bounding_set) {
  rtcp_sender_.SetTMMBN(bounding_set);
}

// Returns the currently configured retransmission mode.
int ModuleRtpRtcpImpl::SelectiveRetransmissions() const {
  return rtp_sender_.SelectiveRetransmissions();
}

// Enable or disable a retransmission mode, which decides which packets will
// be retransmitted if NACKed.
int ModuleRtpRtcpImpl::SetSelectiveRetransmissions(uint8_t settings) {
  return rtp_sender_.SetSelectiveRetransmissions(settings);
}

// Send a Negative acknowledgment packet.
int32_t ModuleRtpRtcpImpl::SendNACK(const uint16_t* nack_list,
                                    const uint16_t size) {
  for (int i = 0; i < size; ++i) {
    receive_loss_stats_.AddLostPacket(nack_list[i]);
  }
  uint16_t nack_length = size;
  uint16_t start_id = 0;
  int64_t now = clock_->TimeInMilliseconds();
  if (TimeToSendFullNackList(now)) {
    nack_last_time_sent_full_ = now;
    nack_last_time_sent_full_prev_ = now;
  } else {
    // Only send extended list.
    if (nack_last_seq_number_sent_ == nack_list[size - 1]) {
      // Last sequence number is the same, do not send list.
      return 0;
    }
    // Send new sequence numbers.
    for (int i = 0; i < size; ++i) {
      if (nack_last_seq_number_sent_ == nack_list[i]) {
        start_id = i + 1;
        break;
      }
    }
    nack_length = size - start_id;
  }

  // Our RTCP NACK implementation is limited to kRtcpMaxNackFields sequence
  // numbers per RTCP packet.
  if (nack_length > kRtcpMaxNackFields) {
    nack_length = kRtcpMaxNackFields;
  }
  nack_last_seq_number_sent_ = nack_list[start_id + nack_length - 1];

  return rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpNack, nack_length,
                               &nack_list[start_id]);
}

void ModuleRtpRtcpImpl::SendNack(
    const std::vector<uint16_t>& sequence_numbers) {
  rtcp_sender_.SendRTCP(GetFeedbackState(), kRtcpNack, sequence_numbers.size(),
                        sequence_numbers.data());
}

bool ModuleRtpRtcpImpl::TimeToSendFullNackList(int64_t now) const {
  // Use RTT from RtcpRttStats class if provided.
  int64_t rtt = rtt_ms();
  if (rtt == 0) {
    rtcp_receiver_.RTT(rtcp_receiver_.RemoteSSRC(), NULL, &rtt, NULL, NULL);
  }

  const int64_t kStartUpRttMs = 100;
  int64_t wait_time = 5 + ((rtt * 3) >> 1);  // 5 + RTT * 1.5.
  if (rtt == 0) {
    wait_time = kStartUpRttMs;
  }

  // Send a full NACK list once within every |wait_time|.
  if (rtt_stats_) {
    return now - nack_last_time_sent_full_ > wait_time;
  }
  return now - nack_last_time_sent_full_prev_ > wait_time;
}

// Store the sent packets, needed to answer to Negative acknowledgment requests.
void ModuleRtpRtcpImpl::SetStorePacketsStatus(const bool enable,
                                              const uint16_t number_to_store) {
  rtp_sender_.SetStorePacketsStatus(enable, number_to_store);
}

bool ModuleRtpRtcpImpl::StorePackets() const {
  return rtp_sender_.StorePackets();
}

void ModuleRtpRtcpImpl::RegisterRtcpStatisticsCallback(
    RtcpStatisticsCallback* callback) {
  rtcp_receiver_.RegisterRtcpStatisticsCallback(callback);
}

RtcpStatisticsCallback* ModuleRtpRtcpImpl::GetRtcpStatisticsCallback() {
  return rtcp_receiver_.GetRtcpStatisticsCallback();
}

bool ModuleRtpRtcpImpl::SendFeedbackPacket(
    const rtcp::TransportFeedback& packet) {
  return rtcp_sender_.SendFeedbackPacket(packet);
}

// Send a TelephoneEvent tone using RFC 2833 (4733).
int32_t ModuleRtpRtcpImpl::SendTelephoneEventOutband(
    const uint8_t key,
    const uint16_t time_ms,
    const uint8_t level) {
  return rtp_sender_.SendTelephoneEvent(key, time_ms, level);
}

// Set audio packet size, used to determine when it's time to send a DTMF
// packet in silence (CNG).
int32_t ModuleRtpRtcpImpl::SetAudioPacketSize(
    const uint16_t packet_size_samples) {
  return rtp_sender_.SetAudioPacketSize(packet_size_samples);
}

int32_t ModuleRtpRtcpImpl::SetAudioLevel(
    const uint8_t level_d_bov) {
  return rtp_sender_.SetAudioLevel(level_d_bov);
}

// Set payload type for Redundant Audio Data RFC 2198.
int32_t ModuleRtpRtcpImpl::SetSendREDPayloadType(
    const int8_t payload_type) {
  return rtp_sender_.SetRED(payload_type);
}

// Get payload type for Redundant Audio Data RFC 2198.
int32_t ModuleRtpRtcpImpl::SendREDPayloadType(int8_t* payload_type) const {
  return rtp_sender_.RED(payload_type);
}

void ModuleRtpRtcpImpl::SetTargetSendBitrate(uint32_t bitrate_bps) {
  rtp_sender_.SetTargetBitrate(bitrate_bps);
}

int32_t ModuleRtpRtcpImpl::SetKeyFrameRequestMethod(
    const KeyFrameRequestMethod method) {
  key_frame_req_method_ = method;
  return 0;
}

int32_t ModuleRtpRtcpImpl::RequestKeyFrame() {
  switch (key_frame_req_method_) {
    case kKeyFrameReqPliRtcp:
      return SendRTCP(kRtcpPli);
    case kKeyFrameReqFirRtcp:
      return SendRTCP(kRtcpFir);
  }
  return -1;
}

int32_t ModuleRtpRtcpImpl::SendRTCPSliceLossIndication(
    const uint8_t picture_id) {
  return rtcp_sender_.SendRTCP(
      GetFeedbackState(), kRtcpSli, 0, 0, false, picture_id);
}

void ModuleRtpRtcpImpl::SetGenericFECStatus(
    const bool enable,
    const uint8_t payload_type_red,
    const uint8_t payload_type_fec) {
  rtp_sender_.SetGenericFECStatus(enable, payload_type_red, payload_type_fec);
}

void ModuleRtpRtcpImpl::GenericFECStatus(bool* enable,
                                         uint8_t* payload_type_red,
                                         uint8_t* payload_type_fec) {
  rtp_sender_.GenericFECStatus(enable, payload_type_red, payload_type_fec);
}

int32_t ModuleRtpRtcpImpl::SetFecParameters(
    const FecProtectionParams* delta_params,
    const FecProtectionParams* key_params) {
  return rtp_sender_.SetFecParameters(delta_params, key_params);
}

void ModuleRtpRtcpImpl::SetRemoteSSRC(const uint32_t ssrc) {
  // Inform about the incoming SSRC.
  rtcp_sender_.SetRemoteSSRC(ssrc);
  rtcp_receiver_.SetRemoteSSRC(ssrc);

  // Check for a SSRC collision.
  if (rtp_sender_.SSRC() == ssrc && !collision_detected_) {
    // If we detect a collision change the SSRC but only once.
    collision_detected_ = true;
    uint32_t new_ssrc = rtp_sender_.GenerateNewSSRC();
    if (new_ssrc == 0) {
      // Configured via API ignore.
      return;
    }
    if (RtcpMode::kOff != rtcp_sender_.Status()) {
      // Send RTCP bye on the current SSRC.
      SendRTCP(kRtcpBye);
    }
    // Change local SSRC and inform all objects about the new SSRC.
    rtcp_sender_.SetSSRC(new_ssrc);
    SetRtcpReceiverSsrcs(new_ssrc);
  }
}

void ModuleRtpRtcpImpl::BitrateSent(uint32_t* total_rate,
                                    uint32_t* video_rate,
                                    uint32_t* fec_rate,
                                    uint32_t* nack_rate) const {
  *total_rate = rtp_sender_.BitrateSent();
  *video_rate = rtp_sender_.VideoBitrateSent();
  *fec_rate = rtp_sender_.FecOverheadRate();
  *nack_rate = rtp_sender_.NackOverheadRate();
}

void ModuleRtpRtcpImpl::OnRequestSendReport() {
  SendRTCP(kRtcpSr);
}

int32_t ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection(
    const uint64_t picture_id) {
  return rtcp_sender_.SendRTCP(
      GetFeedbackState(), kRtcpRpsi, 0, 0, false, picture_id);
}

void ModuleRtpRtcpImpl::OnReceivedNACK(
    const std::list<uint16_t>& nack_sequence_numbers) {
  for (uint16_t nack_sequence_number : nack_sequence_numbers) {
    send_loss_stats_.AddLostPacket(nack_sequence_number);
  }
  if (!rtp_sender_.StorePackets() ||
      nack_sequence_numbers.size() == 0) {
    return;
  }
  // Use RTT from RtcpRttStats class if provided.
  int64_t rtt = rtt_ms();
  if (rtt == 0) {
    rtcp_receiver_.RTT(rtcp_receiver_.RemoteSSRC(), NULL, &rtt, NULL, NULL);
  }
  rtp_sender_.OnReceivedNACK(nack_sequence_numbers, rtt);
}

void ModuleRtpRtcpImpl::OnReceivedRtcpReportBlocks(
    const ReportBlockList& report_blocks) {
  rtp_sender_.OnReceivedRtcpReportBlocks(report_blocks);
}

bool ModuleRtpRtcpImpl::LastReceivedNTP(
    uint32_t* rtcp_arrival_time_secs,  // When we got the last report.
    uint32_t* rtcp_arrival_time_frac,
    uint32_t* remote_sr) const {
  // Remote SR: NTP inside the last received (mid 16 bits from sec and frac).
  uint32_t ntp_secs = 0;
  uint32_t ntp_frac = 0;

  if (!rtcp_receiver_.NTP(&ntp_secs,
                          &ntp_frac,
                          rtcp_arrival_time_secs,
                          rtcp_arrival_time_frac,
                          NULL)) {
    return false;
  }
  *remote_sr =
      ((ntp_secs & 0x0000ffff) << 16) + ((ntp_frac & 0xffff0000) >> 16);
  return true;
}

bool ModuleRtpRtcpImpl::LastReceivedXrReferenceTimeInfo(
    RtcpReceiveTimeInfo* info) const {
  return rtcp_receiver_.LastReceivedXrReferenceTimeInfo(info);
}

bool ModuleRtpRtcpImpl::UpdateRTCPReceiveInformationTimers() {
  // If this returns true this channel has timed out.
  // Periodically check if this is true and if so call UpdateTMMBR.
  return rtcp_receiver_.UpdateRTCPReceiveInformationTimers();
}

// Called from RTCPsender.
int32_t ModuleRtpRtcpImpl::BoundingSet(bool* tmmbr_owner,
                                       TMMBRSet* bounding_set) {
  return rtcp_receiver_.BoundingSet(tmmbr_owner, bounding_set);
}

int64_t ModuleRtpRtcpImpl::RtcpReportInterval() {
  if (audio_)
    return RTCP_INTERVAL_AUDIO_MS;
  else
    return RTCP_INTERVAL_VIDEO_MS;
}

void ModuleRtpRtcpImpl::SetRtcpReceiverSsrcs(uint32_t main_ssrc) {
  std::set<uint32_t> ssrcs;
  ssrcs.insert(main_ssrc);
  if (rtp_sender_.RtxStatus() != kRtxOff)
    ssrcs.insert(rtp_sender_.RtxSsrc());
  rtcp_receiver_.SetSsrcs(main_ssrc, ssrcs);
}

void ModuleRtpRtcpImpl::set_rtt_ms(int64_t rtt_ms) {
  rtc::CritScope cs(&critical_section_rtt_);
  rtt_ms_ = rtt_ms;
}

int64_t ModuleRtpRtcpImpl::rtt_ms() const {
  rtc::CritScope cs(&critical_section_rtt_);
  return rtt_ms_;
}

void ModuleRtpRtcpImpl::RegisterSendChannelRtpStatisticsCallback(
    StreamDataCountersCallback* callback) {
  rtp_sender_.RegisterRtpStatisticsCallback(callback);
}

StreamDataCountersCallback*
    ModuleRtpRtcpImpl::GetSendChannelRtpStatisticsCallback() const {
  return rtp_sender_.GetRtpStatisticsCallback();
}
}  // namespace webrtc
