/*
 *  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 "common_types.h"
#include "rtp_rtcp_impl.h"
#include "trace.h"

#ifdef MATLAB
#include "../test/BWEStandAlone/MatlabPlot.h"
extern MatlabEngine eng; // global variable defined elsewhere
#endif

#include <string.h> //memcpy
#include <cassert> //assert

// local for this file
namespace {

const float FracMS = 4.294967296E6f;

}  // namepace

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

namespace webrtc {

const WebRtc_UWord16 kDefaultRtt = 200;

RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) {
  if (configuration.clock) {
    return new ModuleRtpRtcpImpl(configuration);
  } else {
    RtpRtcp::Configuration configuration_copy;
    memcpy(&configuration_copy, &configuration,
           sizeof(RtpRtcp::Configuration));
    configuration_copy.clock = ModuleRTPUtility::GetSystemClock();
    ModuleRtpRtcpImpl* rtp_rtcp_instance =
        new ModuleRtpRtcpImpl(configuration_copy);
    rtp_rtcp_instance->OwnsClock();
    return rtp_rtcp_instance;
  }
}

ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
    : _rtpSender(configuration.id, configuration.audio, configuration.clock),
      _rtpReceiver(configuration.id, configuration.audio, configuration.clock,
                   this),
      _rtcpSender(configuration.id, configuration.audio, configuration.clock,
                  this),
      _rtcpReceiver(configuration.id, configuration.clock, this),
      _owns_clock(false),
      _clock(*configuration.clock),
      _id(configuration.id),
      _audio(configuration.audio),
      _collisionDetected(false),
      _lastProcessTime(configuration.clock->GetTimeInMS()),
      _lastBitrateProcessTime(configuration.clock->GetTimeInMS()),
      _lastPacketTimeoutProcessTime(configuration.clock->GetTimeInMS()),
      _packetOverHead(28),  // IPV4 UDP
      _criticalSectionModulePtrs(
          CriticalSectionWrapper::CreateCriticalSection()),
      _criticalSectionModulePtrsFeedback(
          CriticalSectionWrapper::CreateCriticalSection()),
      _defaultModule(
          static_cast<ModuleRtpRtcpImpl*>(configuration.default_module)),
      _deadOrAliveActive(false),
      _deadOrAliveTimeoutMS(0),
      _deadOrAliveLastTimer(0),
      _nackMethod(kNackOff),
      _nackLastTimeSent(0),
      _nackLastSeqNumberSent(0),
      _simulcast(false),
      _keyFrameReqMethod(kKeyFrameReqFirRtp)
#ifdef MATLAB
       , _plot1(NULL)
#endif
{
  _sendVideoCodec.codecType = kVideoCodecUnknown;

  if (_defaultModule) {
    _defaultModule->RegisterChildModule(this);
  }
  // TODO(pwestin) move to constructors of each rtp/rtcp sender/receiver object.
  _rtpReceiver.RegisterIncomingDataCallback(configuration.incoming_data);
  _rtpReceiver.RegisterIncomingRTPCallback(configuration.incoming_messages);
  _rtcpReceiver.RegisterRtcpObservers(configuration.intra_frame_callback,
                                      configuration.bandwidth_callback,
                                      configuration.rtcp_feedback);
  _rtpSender.RegisterAudioCallback(configuration.audio_messages);
  _rtpReceiver.RegisterIncomingAudioCallback(configuration.audio_messages);

  _rtpSender.RegisterSendTransport(configuration.outgoing_transport);
  _rtcpSender.RegisterSendTransport(configuration.outgoing_transport);

  _rtcpSender.SetRemoteBitrateObserver(configuration.bitrate_observer);

  // make sure that RTCP objects are aware of our SSRC
  WebRtc_UWord32 SSRC = _rtpSender.SSRC();
  _rtcpSender.SetSSRC(SSRC);

  WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s created", __FUNCTION__);
}

ModuleRtpRtcpImpl::~ModuleRtpRtcpImpl() {
  WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__);

  // All child modules MUST be deleted before deleting the default.
  assert(_childModules.empty());

  // Deregister for the child modules
  // will go in to the default and remove it self
  if (_defaultModule) {
    _defaultModule->DeRegisterChildModule(this);
  }
#ifdef MATLAB
  if (_plot1) {
    eng.DeletePlot(_plot1);
    _plot1 = NULL;
  }
#endif
  if (_owns_clock) {
    delete &_clock;
  }
}

void ModuleRtpRtcpImpl::RegisterChildModule(RtpRtcp* module) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "RegisterChildModule(module:0x%x)",
               module);

  CriticalSectionScoped lock(_criticalSectionModulePtrs.get());

  CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback.get());
  // we use two locks for protecting _childModules one
  // (_criticalSectionModulePtrsFeedback) for incoming
  // messages (BitrateSent) and _criticalSectionModulePtrs
  //  for all outgoing messages sending packets etc
  _childModules.push_back((ModuleRtpRtcpImpl*)module);
}

void ModuleRtpRtcpImpl::DeRegisterChildModule(RtpRtcp* removeModule) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "DeRegisterChildModule(module:0x%x)", removeModule);

  CriticalSectionScoped lock(_criticalSectionModulePtrs.get());

  CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback.get());

  std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
  while (it != _childModules.end()) {
    RtpRtcp* module = *it;
    if (module == removeModule) {
      _childModules.erase(it);
      return;
    }
    it++;
  }
}

// returns the number of milliseconds until the module want a worker thread
// to call Process
WebRtc_Word32 ModuleRtpRtcpImpl::TimeUntilNextProcess() {
  const WebRtc_UWord32 now = _clock.GetTimeInMS();
  return kRtpRtcpMaxIdleTimeProcess - (now - _lastProcessTime);
}

// Process any pending tasks such as timeouts
// non time critical events
WebRtc_Word32 ModuleRtpRtcpImpl::Process() {
  const WebRtc_UWord32 now = _clock.GetTimeInMS();
  _lastProcessTime = now;

  _rtpSender.ProcessSendToNetwork();

  if (now >= _lastPacketTimeoutProcessTime +
      kRtpRtcpPacketTimeoutProcessTimeMs) {
    _rtpReceiver.PacketTimeout();
    _rtcpReceiver.PacketTimeout();
    _lastPacketTimeoutProcessTime = now;
  }

  if (now >= _lastBitrateProcessTime + kRtpRtcpBitrateProcessTimeMs) {
    _rtpSender.ProcessBitrate();
    _rtpReceiver.ProcessBitrate();
    _lastBitrateProcessTime = now;
  }

  ProcessDeadOrAliveTimer();

  const bool defaultInstance(_childModules.empty() ? false : true);
  if (!defaultInstance && _rtcpSender.TimeToSendRTCPReport()) {
    WebRtc_UWord16 max_rtt = 0;
    if (_rtcpSender.Sending()) {
      std::vector<RTCPReportBlock> receive_blocks;
      _rtcpReceiver.StatisticsReceived(&receive_blocks);
      for (std::vector<RTCPReportBlock>::iterator it = receive_blocks.begin();
           it != receive_blocks.end(); ++it) {
        WebRtc_UWord16 rtt = 0;
        _rtcpReceiver.RTT(it->remoteSSRC, &max_rtt, NULL, NULL, NULL);
        max_rtt = (rtt > max_rtt) ? rtt : max_rtt;
      }
    } else {
      // We're only receiving, i.e. this module doesn't have its own RTT
      // estimate. Use the RTT set by a sending channel using the same default
      // module.
      max_rtt = _rtcpReceiver.RTT();
    }
    if (max_rtt == 0) {
      // No valid estimate available, i.e. no sending channel using the same
      // default module or no RTCP received yet.
      max_rtt = kDefaultRtt;
    }
    if (_rtcpSender.ValidBitrateEstimate()) {
      if (REMB()) {
        uint32_t target_bitrate =
            _rtcpSender.CalculateNewTargetBitrate(max_rtt);
        _rtcpSender.UpdateRemoteBitrateEstimate(target_bitrate);
      } else if (TMMBR()) {
        _rtcpSender.CalculateNewTargetBitrate(max_rtt);
      }
    }
    _rtcpSender.SendRTCP(kRtcpReport);
  }

  if (UpdateRTCPReceiveInformationTimers()) {
    // a receiver has timed out
    _rtcpReceiver.UpdateTMMBR();
  }
  return 0;
}

/**
*   Receiver
*/

void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer() {
  if (_deadOrAliveActive) {
    const WebRtc_UWord32 now = _clock.GetTimeInMS();
    if (now > _deadOrAliveTimeoutMS + _deadOrAliveLastTimer) {
      // RTCP is alive if we have received a report the last 12 seconds
      _deadOrAliveLastTimer += _deadOrAliveTimeoutMS;

      bool RTCPalive = false;
      if (_rtcpReceiver.LastReceived() + 12000 > now) {
        RTCPalive = true;
      }
      _rtpReceiver.ProcessDeadOrAlive(RTCPalive, now);
    }
  }
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetPeriodicDeadOrAliveStatus(
  const bool enable,
  const WebRtc_UWord8 sampleTimeSeconds) {
  if (enable) {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetPeriodicDeadOrAliveStatus(enable, %d)",
                 sampleTimeSeconds);
  } else {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetPeriodicDeadOrAliveStatus(disable)");
  }
  if (sampleTimeSeconds == 0) {
    return -1;
  }
  _deadOrAliveActive = enable;
  _deadOrAliveTimeoutMS = sampleTimeSeconds * 1000;
  // trigger the first after one period
  _deadOrAliveLastTimer = _clock.GetTimeInMS();
  return 0;
}

WebRtc_Word32 ModuleRtpRtcpImpl::PeriodicDeadOrAliveStatus(
    bool& enable,
    WebRtc_UWord8& sampleTimeSeconds) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "PeriodicDeadOrAliveStatus()");

  enable = _deadOrAliveActive;
  sampleTimeSeconds = (WebRtc_UWord8)(_deadOrAliveTimeoutMS / 1000);
  return 0;
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetPacketTimeout(
    const WebRtc_UWord32 RTPtimeoutMS,
    const WebRtc_UWord32 RTCPtimeoutMS) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetPacketTimeout(%u,%u)",
               RTPtimeoutMS,
               RTCPtimeoutMS);

  if (_rtpReceiver.SetPacketTimeout(RTPtimeoutMS) == 0) {
    return _rtcpReceiver.SetPacketTimeout(RTCPtimeoutMS);
  }
  return -1;
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterReceivePayload(
  const CodecInst& voiceCodec) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "RegisterReceivePayload(voiceCodec)");

  return _rtpReceiver.RegisterReceivePayload(
           voiceCodec.plname,
           voiceCodec.pltype,
           voiceCodec.plfreq,
           voiceCodec.channels,
           (voiceCodec.rate < 0) ? 0 : voiceCodec.rate);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterReceivePayload(
  const VideoCodec& videoCodec) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "RegisterReceivePayload(videoCodec)");

  return _rtpReceiver.RegisterReceivePayload(videoCodec.plName,
                                             videoCodec.plType,
                                             90000,
                                             0,
                                             videoCodec.maxBitrate);
}

WebRtc_Word32 ModuleRtpRtcpImpl::ReceivePayloadType(
  const CodecInst& voiceCodec,
  WebRtc_Word8* plType) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "ReceivePayloadType(voiceCodec)");

  return _rtpReceiver.ReceivePayloadType(
           voiceCodec.plname,
           voiceCodec.plfreq,
           voiceCodec.channels,
           (voiceCodec.rate < 0) ? 0 : voiceCodec.rate,
           plType);
}

WebRtc_Word32 ModuleRtpRtcpImpl::ReceivePayloadType(
  const VideoCodec& videoCodec,
  WebRtc_Word8* plType) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "ReceivePayloadType(videoCodec)");

  return _rtpReceiver.ReceivePayloadType(videoCodec.plName,
                                         90000,
                                         0,
                                         videoCodec.maxBitrate,
                                         plType);
}

WebRtc_Word32 ModuleRtpRtcpImpl::DeRegisterReceivePayload(
    const WebRtc_Word8 payloadType) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "DeRegisterReceivePayload(%d)",
               payloadType);

  return _rtpReceiver.DeRegisterReceivePayload(payloadType);
}

// get the currently configured SSRC filter
WebRtc_Word32 ModuleRtpRtcpImpl::SSRCFilter(WebRtc_UWord32& allowedSSRC) const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SSRCFilter()");

  return _rtpReceiver.SSRCFilter(allowedSSRC);
}

// set a SSRC to be used as a filter for incoming RTP streams
WebRtc_Word32 ModuleRtpRtcpImpl::SetSSRCFilter(
  const bool enable,
  const WebRtc_UWord32 allowedSSRC) {
  if (enable) {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetSSRCFilter(enable, 0x%x)",
                 allowedSSRC);
  } else {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetSSRCFilter(disable)");
  }

  return _rtpReceiver.SetSSRCFilter(enable, allowedSSRC);
}

// Get last received remote timestamp
WebRtc_UWord32 ModuleRtpRtcpImpl::RemoteTimestamp() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteTimestamp()");

  return _rtpReceiver.TimeStamp();
}

// Get the current estimated remote timestamp
WebRtc_Word32 ModuleRtpRtcpImpl::EstimatedRemoteTimeStamp(
    WebRtc_UWord32& timestamp) const {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "EstimatedRemoteTimeStamp()");

  return _rtpReceiver.EstimatedRemoteTimeStamp(timestamp);
}

// Get incoming SSRC
WebRtc_UWord32 ModuleRtpRtcpImpl::RemoteSSRC() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteSSRC()");

  return _rtpReceiver.SSRC();
}

// Get remote CSRC
WebRtc_Word32 ModuleRtpRtcpImpl::RemoteCSRCs(
    WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteCSRCs()");

  return _rtpReceiver.CSRCs(arrOfCSRC);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetRTXSendStatus(
  const bool enable,
  const bool setSSRC,
  const WebRtc_UWord32 SSRC) {
  _rtpSender.SetRTXStatus(enable, setSSRC, SSRC);
  return 0;
}

WebRtc_Word32 ModuleRtpRtcpImpl::RTXSendStatus(bool* enable,
                                               WebRtc_UWord32* SSRC) const {
  _rtpSender.RTXStatus(enable, SSRC);
  return 0;
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetRTXReceiveStatus(
  const bool enable,
  const WebRtc_UWord32 SSRC) {
  _rtpReceiver.SetRTXStatus(enable, SSRC);
  return 0;
}

WebRtc_Word32 ModuleRtpRtcpImpl::RTXReceiveStatus(bool* enable,
                                                  WebRtc_UWord32* SSRC) const {
  _rtpReceiver.RTXStatus(enable, SSRC);
  return 0;
}

// called by the network module when we receive a packet
WebRtc_Word32 ModuleRtpRtcpImpl::IncomingPacket(
    const WebRtc_UWord8* incomingPacket,
    const WebRtc_UWord16 incomingPacketLength) {
  WEBRTC_TRACE(kTraceStream,
               kTraceRtpRtcp,
               _id,
               "IncomingPacket(packetLength:%u)",
               incomingPacketLength);
  // minimum RTP is 12 bytes
  // minimum RTCP is 8 bytes (RTCP BYE)
  if (incomingPacketLength < 8 || incomingPacket == NULL) {
    WEBRTC_TRACE(kTraceDebug,
                 kTraceRtpRtcp,
                 _id,
                 "IncomingPacket invalid buffer or length");
    return -1;
  }
  // check RTP version
  const WebRtc_UWord8  version  = incomingPacket[0] >> 6 ;
  if (version != 2) {
    WEBRTC_TRACE(kTraceDebug,
                 kTraceRtpRtcp,
                 _id,
                 "IncomingPacket invalid RTP version");
    return -1;
  }

  ModuleRTPUtility::RTPHeaderParser rtpParser(incomingPacket,
                                              incomingPacketLength);

  if (rtpParser.RTCP()) {
    // Allow receive of non-compound RTCP packets.
    RTCPUtility::RTCPParserV2 rtcpParser(incomingPacket,
                                         incomingPacketLength,
                                         true);

    const bool validRTCPHeader = rtcpParser.IsValid();
    if (!validRTCPHeader) {
      WEBRTC_TRACE(kTraceDebug,
                   kTraceRtpRtcp,
                   _id,
                   "IncomingPacket invalid RTCP packet");
      return -1;
    }
    RTCPHelp::RTCPPacketInformation rtcpPacketInformation;
    WebRtc_Word32 retVal = _rtcpReceiver.IncomingRTCPPacket(
                             rtcpPacketInformation,
                             &rtcpParser);
    if (retVal == 0) {
      _rtcpReceiver.TriggerCallbacksFromRTCPPacket(rtcpPacketInformation);
    }
    return retVal;

  } else {
    WebRtcRTPHeader rtpHeader;
    memset(&rtpHeader, 0, sizeof(rtpHeader));

    RtpHeaderExtensionMap map;
    _rtpReceiver.GetHeaderExtensionMapCopy(&map);

    const bool validRTPHeader = rtpParser.Parse(rtpHeader, &map);
    if (!validRTPHeader) {
      WEBRTC_TRACE(kTraceDebug,
                   kTraceRtpRtcp,
                   _id,
                   "IncomingPacket invalid RTP header");
      return -1;
    }
    return _rtpReceiver.IncomingRTPPacket(&rtpHeader,
                                          incomingPacket,
                                          incomingPacketLength);
  }
}

/**
*   Sender
*/

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSendPayload(
  const CodecInst& voiceCodec) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "RegisterSendPayload(plName:%s plType:%d frequency:%u)",
               voiceCodec.plname,
               voiceCodec.pltype,
               voiceCodec.plfreq);

  return _rtpSender.RegisterPayload(
           voiceCodec.plname,
           voiceCodec.pltype,
           voiceCodec.plfreq,
           voiceCodec.channels,
           (voiceCodec.rate < 0) ? 0 : voiceCodec.rate);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSendPayload(
  const VideoCodec& videoCodec) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "RegisterSendPayload(plName:%s plType:%d)",
               videoCodec.plName,
               videoCodec.plType);

  _sendVideoCodec = videoCodec;
  _simulcast = (videoCodec.numberOfSimulcastStreams > 1) ? true : false;
  return _rtpSender.RegisterPayload(videoCodec.plName,
                                    videoCodec.plType,
                                    90000,
                                    0,
                                    videoCodec.maxBitrate);
}

WebRtc_Word32 ModuleRtpRtcpImpl::DeRegisterSendPayload(
    const WebRtc_Word8 payloadType) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "DeRegisterSendPayload(%d)", payloadType);

  return _rtpSender.DeRegisterSendPayload(payloadType);
}

WebRtc_Word8 ModuleRtpRtcpImpl::SendPayloadType() const {
  return _rtpSender.SendPayloadType();
}

WebRtc_UWord32 ModuleRtpRtcpImpl::StartTimestamp() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "StartTimestamp()");

  return _rtpSender.StartTimestamp();
}

// configure start timestamp, default is a random number
WebRtc_Word32 ModuleRtpRtcpImpl::SetStartTimestamp(
    const WebRtc_UWord32 timestamp) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetStartTimestamp(%d)",
               timestamp);

  return _rtpSender.SetStartTimestamp(timestamp, true);
}

WebRtc_UWord16 ModuleRtpRtcpImpl::SequenceNumber() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SequenceNumber()");

  return _rtpSender.SequenceNumber();
}

// Set SequenceNumber, default is a random number
WebRtc_Word32 ModuleRtpRtcpImpl::SetSequenceNumber(
    const WebRtc_UWord16 seqNum) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetSequenceNumber(%d)",
               seqNum);

  return _rtpSender.SetSequenceNumber(seqNum);
}

WebRtc_UWord32 ModuleRtpRtcpImpl::SSRC() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SSRC()");

  return _rtpSender.SSRC();
}

// configure SSRC, default is a random number
WebRtc_Word32 ModuleRtpRtcpImpl::SetSSRC(const WebRtc_UWord32 ssrc) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetSSRC(%d)", ssrc);

  if (_rtpSender.SetSSRC(ssrc) == 0) {
    _rtcpReceiver.SetSSRC(ssrc);
    _rtcpSender.SetSSRC(ssrc);
    return 0;
  }
  return -1;
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetCSRCStatus(const bool include) {
  _rtcpSender.SetCSRCStatus(include);
  return _rtpSender.SetCSRCStatus(include);
}

WebRtc_Word32 ModuleRtpRtcpImpl::CSRCs(
    WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "CSRCs()");

  return _rtpSender.CSRCs(arrOfCSRC);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetCSRCs(
    const WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize],
    const WebRtc_UWord8 arrLength) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetCSRCs(arrLength:%d)",
               arrLength);

  const bool defaultInstance(_childModules.empty() ? false : true);

  if (defaultInstance) {
    // for default we need to update all child modules too
    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());

    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
    while (it != _childModules.end()) {
      RtpRtcp* module = *it;
      if (module) {
        module->SetCSRCs(arrOfCSRC, arrLength);
      }
      it++;
    }
    return 0;

  } else {
    for (int i = 0; i < arrLength; i++) {
      WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "\tidx:%d CSRC:%u", i,
                   arrOfCSRC[i]);
    }
    _rtcpSender.SetCSRCs(arrOfCSRC, arrLength);
    return _rtpSender.SetCSRCs(arrOfCSRC, arrLength);
  }
}

WebRtc_UWord32 ModuleRtpRtcpImpl::PacketCountSent() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "PacketCountSent()");

  return _rtpSender.Packets();
}

WebRtc_UWord32 ModuleRtpRtcpImpl::ByteCountSent() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ByteCountSent()");

  return _rtpSender.Bytes();
}

int ModuleRtpRtcpImpl::CurrentSendFrequencyHz() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "CurrentSendFrequencyHz()");

  return _rtpSender.SendPayloadFrequency();
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetSendingStatus(const bool sending) {
  if (sending) {
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
                 "SetSendingStatus(sending)");
  } else {
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
                 "SetSendingStatus(stopped)");
  }
  if (_rtcpSender.Sending() != sending) {
    // sends RTCP BYE when going from true to false
    if (_rtcpSender.SetSendingStatus(sending) != 0) {
      WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
                   "Failed to send RTCP BYE");
    }

    _collisionDetected = false;

    // generate a new timeStamp if true and not configured via API
    // generate a new SSRC for the next "call" if false
    _rtpSender.SetSendingStatus(sending);

    // make sure that RTCP objects are aware of our SSRC (it could have changed
    // due to collision)
    WebRtc_UWord32 SSRC = _rtpSender.SSRC();
    _rtcpReceiver.SetSSRC(SSRC);
    _rtcpSender.SetSSRC(SSRC);
    return 0;
  }
  return 0;
}

bool ModuleRtpRtcpImpl::Sending() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "Sending()");

  return _rtcpSender.Sending();
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetSendingMediaStatus(const bool sending) {
  if (sending) {
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
                 "SetSendingMediaStatus(sending)");
  } else {
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
                 "SetSendingMediaStatus(stopped)");
  }
  _rtpSender.SetSendingMediaStatus(sending);
  return 0;
}

bool ModuleRtpRtcpImpl::SendingMedia() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "Sending()");

  const bool haveChildModules(_childModules.empty() ? false : true);
  if (!haveChildModules) {
    return _rtpSender.SendingMedia();
  }

  CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
  std::list<ModuleRtpRtcpImpl*>::const_iterator it = _childModules.begin();
  while (it != _childModules.end()) {
    RTPSender& rtpSender = (*it)->_rtpSender;
    if (rtpSender.SendingMedia()) {
      return true;
    }
    it++;
  }
  return false;
}

WebRtc_Word32 ModuleRtpRtcpImpl::SendOutgoingData(
    FrameType frameType,
    WebRtc_Word8 payloadType,
    WebRtc_UWord32 timeStamp,
    const WebRtc_UWord8* payloadData,
    WebRtc_UWord32 payloadSize,
    const RTPFragmentationHeader* fragmentation,
    const RTPVideoHeader* rtpVideoHdr) {
  WEBRTC_TRACE(
    kTraceStream,
    kTraceRtpRtcp,
    _id,
    "SendOutgoingData(frameType:%d payloadType:%d timeStamp:%u size:%u)",
    frameType, payloadType, timeStamp, payloadSize);

  const bool haveChildModules(_childModules.empty() ? false : true);
  if (!haveChildModules) {
    // Don't sent RTCP from default module
    if (_rtcpSender.TimeToSendRTCPReport(kVideoFrameKey == frameType)) {
      _rtcpSender.SendRTCP(kRtcpReport);
    }
    return _rtpSender.SendOutgoingData(frameType,
                                       payloadType,
                                       timeStamp,
                                       payloadData,
                                       payloadSize,
                                       fragmentation,
                                       NULL,
                                       &(rtpVideoHdr->codecHeader));
  }
  WebRtc_Word32 retVal = -1;
  if (_simulcast) {
    if (rtpVideoHdr == NULL) {
      return -1;
    }
    int idx = 0;
    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
    for (; idx < rtpVideoHdr->simulcastIdx; idx++) {
      it++;
      if (it == _childModules.end()) {
        return -1;
      }
    }
    RTPSender& rtpSender = (*it)->_rtpSender;
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SendOutgoingData(SimulcastIdx:%u size:%u, ssrc:0x%x)",
                 idx, payloadSize, rtpSender.SSRC());
    return rtpSender.SendOutgoingData(frameType,
                                      payloadType,
                                      timeStamp,
                                      payloadData,
                                      payloadSize,
                                      fragmentation,
                                      NULL,
                                      &(rtpVideoHdr->codecHeader));
  } else {
    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
    // TODO(pwestin) remove codecInfo from SendOutgoingData
    VideoCodecInformation* codecInfo = NULL;

    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
    if (it != _childModules.end()) {
      RTPSender& rtpSender = (*it)->_rtpSender;
      retVal = rtpSender.SendOutgoingData(frameType,
                                          payloadType,
                                          timeStamp,
                                          payloadData,
                                          payloadSize,
                                          fragmentation,
                                          NULL,
                                          &(rtpVideoHdr->codecHeader));

      it++;
    }

    // send to all remaining "child" modules
    while (it != _childModules.end()) {
      RTPSender& rtpSender = (*it)->_rtpSender;
      retVal = rtpSender.SendOutgoingData(frameType,
                                          payloadType,
                                          timeStamp,
                                          payloadData,
                                          payloadSize,
                                          fragmentation,
                                          codecInfo,
                                          &(rtpVideoHdr->codecHeader));

      it++;
    }
  }
  return retVal;
}

WebRtc_UWord16 ModuleRtpRtcpImpl::MaxPayloadLength() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "MaxPayloadLength()");

  return _rtpSender.MaxPayloadLength();
}

WebRtc_UWord16 ModuleRtpRtcpImpl::MaxDataPayloadLength() const {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "MaxDataPayloadLength()");

  WebRtc_UWord16 minDataPayloadLength = IP_PACKET_SIZE - 28; // Assuming IP/UDP

  const bool defaultInstance(_childModules.empty() ? false : true);
  if (defaultInstance) {
    // for default we need to update all child modules too
    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
    std::list<ModuleRtpRtcpImpl*>::const_iterator it =
      _childModules.begin();
    while (it != _childModules.end()) {
      RtpRtcp* module = *it;
      if (module) {
        WebRtc_UWord16 dataPayloadLength =
          module->MaxDataPayloadLength();
        if (dataPayloadLength < minDataPayloadLength) {
          minDataPayloadLength = dataPayloadLength;
        }
      }
      it++;
    }
  }

  WebRtc_UWord16 dataPayloadLength = _rtpSender.MaxDataPayloadLength();
  if (dataPayloadLength < minDataPayloadLength) {
    minDataPayloadLength = dataPayloadLength;
  }
  return minDataPayloadLength;
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetTransportOverhead(
  const bool TCP,
  const bool IPV6,
  const WebRtc_UWord8 authenticationOverhead) {
  WEBRTC_TRACE(
    kTraceModuleCall,
    kTraceRtpRtcp,
    _id,
    "SetTransportOverhead(TCP:%d, IPV6:%d authenticationOverhead:%u)",
    TCP, IPV6, authenticationOverhead);

  WebRtc_UWord16 packetOverHead = 0;
  if (IPV6) {
    packetOverHead = 40;
  } else {
    packetOverHead = 20;
  }
  if (TCP) {
    // TCP
    packetOverHead += 20;
  } else {
    // UDP
    packetOverHead += 8;
  }
  packetOverHead += authenticationOverhead;

  if (packetOverHead == _packetOverHead) {
    // ok same as before
    return 0;
  }
  // calc diff
  WebRtc_Word16 packetOverHeadDiff = packetOverHead - _packetOverHead;

  // store new
  _packetOverHead = packetOverHead;

  _rtpReceiver.SetPacketOverHead(_packetOverHead);
  WebRtc_UWord16 length = _rtpSender.MaxPayloadLength() - packetOverHeadDiff;
  return _rtpSender.SetMaxPayloadLength(length, _packetOverHead);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetMaxTransferUnit(const WebRtc_UWord16 MTU) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetMaxTransferUnit(%u)",
               MTU);

  if (MTU > IP_PACKET_SIZE) {
    WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
                 "Invalid in argument to SetMaxTransferUnit(%u)", MTU);
    return -1;
  }
  return _rtpSender.SetMaxPayloadLength(MTU - _packetOverHead,
                                        _packetOverHead);
}

/*
*   RTCP
*/
RTCPMethod ModuleRtpRtcpImpl::RTCP() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RTCP()");

  if (_rtcpSender.Status() != kRtcpOff) {
    return _rtcpReceiver.Status();
  }
  return kRtcpOff;
}

// configure RTCP status i.e on/off
WebRtc_Word32 ModuleRtpRtcpImpl::SetRTCPStatus(const RTCPMethod method) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetRTCPStatus(%d)",
               method);

  if (_rtcpSender.SetRTCPStatus(method) == 0) {
    return _rtcpReceiver.SetRTCPStatus(method);
  }
  return -1;
}

// only for internal test
WebRtc_UWord32 ModuleRtpRtcpImpl::LastSendReport(WebRtc_UWord32& lastRTCPTime) {
  return _rtcpSender.LastSendReport(lastRTCPTime);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetCNAME(const char cName[RTCP_CNAME_SIZE]) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetCNAME(%s)", cName);
  return _rtcpSender.SetCNAME(cName);
}

WebRtc_Word32 ModuleRtpRtcpImpl::CNAME(char cName[RTCP_CNAME_SIZE]) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "CNAME()");
  return _rtcpSender.CNAME(cName);
}

WebRtc_Word32 ModuleRtpRtcpImpl::AddMixedCNAME(
  const WebRtc_UWord32 SSRC,
  const char cName[RTCP_CNAME_SIZE]) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "AddMixedCNAME(SSRC:%u)", SSRC);

  return _rtcpSender.AddMixedCNAME(SSRC, cName);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RemoveMixedCNAME(const WebRtc_UWord32 SSRC) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "RemoveMixedCNAME(SSRC:%u)", SSRC);
  return _rtcpSender.RemoveMixedCNAME(SSRC);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RemoteCNAME(
  const WebRtc_UWord32 remoteSSRC,
  char cName[RTCP_CNAME_SIZE]) const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "RemoteCNAME(SSRC:%u)", remoteSSRC);

  return _rtcpReceiver.CNAME(remoteSSRC, cName);
}

WebRtc_UWord16 ModuleRtpRtcpImpl::RemoteSequenceNumber() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteSequenceNumber()");

  return _rtpReceiver.SequenceNumber();
}

WebRtc_Word32 ModuleRtpRtcpImpl::RemoteNTP(
    WebRtc_UWord32* receivedNTPsecs,
    WebRtc_UWord32* receivedNTPfrac,
    WebRtc_UWord32* RTCPArrivalTimeSecs,
    WebRtc_UWord32* RTCPArrivalTimeFrac) const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteNTP()");

  return _rtcpReceiver.NTP(receivedNTPsecs,
                           receivedNTPfrac,
                           RTCPArrivalTimeSecs,
                           RTCPArrivalTimeFrac);
}

// Get RoundTripTime
WebRtc_Word32 ModuleRtpRtcpImpl::RTT(const WebRtc_UWord32 remoteSSRC,
                                     WebRtc_UWord16* RTT,
                                     WebRtc_UWord16* avgRTT,
                                     WebRtc_UWord16* minRTT,
                                     WebRtc_UWord16* maxRTT) const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RTT()");

  return _rtcpReceiver.RTT(remoteSSRC, RTT, avgRTT, minRTT, maxRTT);
}

// Reset RoundTripTime statistics
WebRtc_Word32
ModuleRtpRtcpImpl::ResetRTT(const WebRtc_UWord32 remoteSSRC) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ResetRTT(SSRC:%u)",
               remoteSSRC);

  return _rtcpReceiver.ResetRTT(remoteSSRC);
}

// Reset RTP statistics
WebRtc_Word32
ModuleRtpRtcpImpl::ResetStatisticsRTP() {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ResetStatisticsRTP()");

  return _rtpReceiver.ResetStatistics();
}

// Reset RTP data counters for the receiving side
WebRtc_Word32 ModuleRtpRtcpImpl::ResetReceiveDataCountersRTP() {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "ResetReceiveDataCountersRTP()");

  return _rtpReceiver.ResetDataCounters();
}

// Reset RTP data counters for the sending side
WebRtc_Word32 ModuleRtpRtcpImpl::ResetSendDataCountersRTP() {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "ResetSendDataCountersRTP()");

  return _rtpSender.ResetDataCounters();
}

// Force a send of an RTCP packet
// normal SR and RR are triggered via the process function
WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCP(WebRtc_UWord32 rtcpPacketType) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SendRTCP(0x%x)",
               rtcpPacketType);

  return  _rtcpSender.SendRTCP(rtcpPacketType);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetRTCPApplicationSpecificData(
    const WebRtc_UWord8 subType,
    const WebRtc_UWord32 name,
    const WebRtc_UWord8* data,
    const WebRtc_UWord16 length) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "SetRTCPApplicationSpecificData(subType:%d name:0x%x)", subType,
               name);

  return  _rtcpSender.SetApplicationSpecificData(subType, name, data, length);
}

/*
*   (XR) VOIP metric
*/
WebRtc_Word32 ModuleRtpRtcpImpl::SetRTCPVoIPMetrics(
    const RTCPVoIPMetric* VoIPMetric) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetRTCPVoIPMetrics()");

  return  _rtcpSender.SetRTCPVoIPMetrics(VoIPMetric);
}

// our localy created statistics of the received RTP stream
WebRtc_Word32 ModuleRtpRtcpImpl::StatisticsRTP(
    WebRtc_UWord8*  fraction_lost,
    WebRtc_UWord32* cum_lost,
    WebRtc_UWord32* ext_max,
    WebRtc_UWord32* jitter,
    WebRtc_UWord32* max_jitter) const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "StatisticsRTP()");

  WebRtc_UWord32 jitter_transmission_time_offset = 0;

  WebRtc_Word32 retVal = _rtpReceiver.Statistics(
      fraction_lost,
      cum_lost,
      ext_max,
      jitter,
      max_jitter,
      &jitter_transmission_time_offset,
      (_rtcpSender.Status() == kRtcpOff));
  if (retVal == -1) {
    WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
                 "StatisticsRTP() no statisitics availble");
  }
  return retVal;
}

WebRtc_Word32 ModuleRtpRtcpImpl::DataCountersRTP(
    WebRtc_UWord32* bytesSent,
    WebRtc_UWord32* packetsSent,
    WebRtc_UWord32* bytesReceived,
    WebRtc_UWord32* packetsReceived) const {
  WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, "DataCountersRTP()");

  if (bytesSent) {
    *bytesSent = _rtpSender.Bytes();
  }
  if (packetsSent) {
    *packetsSent = _rtpSender.Packets();
  }
  return _rtpReceiver.DataCounters(bytesReceived, packetsReceived);
}

WebRtc_Word32 ModuleRtpRtcpImpl::ReportBlockStatistics(
    WebRtc_UWord8* fraction_lost,
    WebRtc_UWord32* cum_lost,
    WebRtc_UWord32* ext_max,
    WebRtc_UWord32* jitter,
    WebRtc_UWord32* jitter_transmission_time_offset) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ReportBlockStatistics()");
  WebRtc_Word32 missing = 0;
  WebRtc_Word32 ret = _rtpReceiver.Statistics(fraction_lost,
                                              cum_lost,
                                              ext_max,
                                              jitter,
                                              NULL,
                                              jitter_transmission_time_offset,
                                              &missing,
                                              true);

#ifdef MATLAB
  if (_plot1 == NULL) {
    _plot1 = eng.NewPlot(new MatlabPlot());
    _plot1->AddTimeLine(30, "b", "lost", _clock.GetTimeInMS());
  }
  _plot1->Append("lost", missing);
  _plot1->Plot();
#endif

  return ret;
}

WebRtc_Word32 ModuleRtpRtcpImpl::RemoteRTCPStat(RTCPSenderInfo* senderInfo) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteRTCPStat()");

  return _rtcpReceiver.SenderInfoReceived(senderInfo);
}

// received RTCP report
WebRtc_Word32 ModuleRtpRtcpImpl::RemoteRTCPStat(
  std::vector<RTCPReportBlock>* receiveBlocks) const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteRTCPStat()");

  return _rtcpReceiver.StatisticsReceived(receiveBlocks);
}

WebRtc_Word32 ModuleRtpRtcpImpl::AddRTCPReportBlock(
    const WebRtc_UWord32 SSRC,
    const RTCPReportBlock* reportBlock) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "AddRTCPReportBlock()");

  return _rtcpSender.AddReportBlock(SSRC, reportBlock);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RemoveRTCPReportBlock(
    const WebRtc_UWord32 SSRC) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoveRTCPReportBlock()");

  return _rtcpSender.RemoveReportBlock(SSRC);
}

/*
 *  (REMB) Receiver Estimated Max Bitrate
 */
bool ModuleRtpRtcpImpl::REMB() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "REMB()");

  return _rtcpSender.REMB();
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetREMBStatus(const bool enable) {
  if (enable) {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetREMBStatus(enable)");
  } else {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetREMBStatus(disable)");
  }
  return _rtcpSender.SetREMBStatus(enable);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetREMBData(const WebRtc_UWord32 bitrate,
                                             const WebRtc_UWord8 numberOfSSRC,
                                             const WebRtc_UWord32* SSRC) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "SetREMBData(bitrate:%d,?,?)", bitrate);
  return _rtcpSender.SetREMBData(bitrate, numberOfSSRC, SSRC);
}

/*
 *   (IJ) Extended jitter report.
 */
bool ModuleRtpRtcpImpl::IJ() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "IJ()");

  return _rtcpSender.IJ();
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetIJStatus(const bool enable) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetIJStatus(%s)", enable ? "true" : "false");

  return _rtcpSender.SetIJStatus(enable);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSendRtpHeaderExtension(
  const RTPExtensionType type,
  const WebRtc_UWord8 id) {
  return _rtpSender.RegisterRtpHeaderExtension(type, id);
}

WebRtc_Word32 ModuleRtpRtcpImpl::DeregisterSendRtpHeaderExtension(
  const RTPExtensionType type) {
  return _rtpSender.DeregisterRtpHeaderExtension(type);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterReceiveRtpHeaderExtension(
  const RTPExtensionType type,
  const WebRtc_UWord8 id) {
  return _rtpReceiver.RegisterRtpHeaderExtension(type, id);
}

WebRtc_Word32 ModuleRtpRtcpImpl::DeregisterReceiveRtpHeaderExtension(
  const RTPExtensionType type) {
  return _rtpReceiver.DeregisterRtpHeaderExtension(type);
}

void ModuleRtpRtcpImpl::SetTransmissionSmoothingStatus(const bool enable) {
  _rtpSender.SetTransmissionSmoothingStatus(enable);
}

bool ModuleRtpRtcpImpl::TransmissionSmoothingStatus() const {
  return _rtpSender.TransmissionSmoothingStatus();
}

/*
*   (TMMBR) Temporary Max Media Bit Rate
*/
bool ModuleRtpRtcpImpl::TMMBR() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "TMMBR()");

  return _rtcpSender.TMMBR();
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBRStatus(const bool enable) {
  if (enable) {
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
                 "SetTMMBRStatus(enable)");
  } else {
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
                 "SetTMMBRStatus(disable)");
  }
  return _rtcpSender.SetTMMBRStatus(enable);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBN(const TMMBRSet* boundingSet) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetTMMBN()");

  WebRtc_UWord32 maxBitrateKbit = _rtpSender.MaxConfiguredBitrateVideo() / 1000;
  return _rtcpSender.SetTMMBN(boundingSet, maxBitrateKbit);
}

/*
*   (NACK) Negative acknowledgement
*/

// Is Negative acknowledgement requests on/off?
NACKMethod ModuleRtpRtcpImpl::NACK() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "NACK()");

  NACKMethod childMethod = kNackOff;
  const bool defaultInstance(_childModules.empty() ? false : true);
  if (defaultInstance) {
    // for default we need to check all child modules too
    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
    std::list<ModuleRtpRtcpImpl*>::const_iterator it =
      _childModules.begin();
    while (it != _childModules.end()) {
      RtpRtcp* module = *it;
      if (module) {
        NACKMethod nackMethod = module->NACK();
        if (nackMethod != kNackOff) {
          childMethod = nackMethod;
          break;
        }
      }
      it++;
    }
  }

  NACKMethod method = _nackMethod;
  if (childMethod != kNackOff) {
    method = childMethod;
  }
  return method;
}

// Turn negative acknowledgement requests on/off
WebRtc_Word32 ModuleRtpRtcpImpl::SetNACKStatus(NACKMethod method) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetNACKStatus(%u)", method);

  _nackMethod = method;
  _rtpReceiver.SetNACKStatus(method);
  return 0;
}

// Returns the currently configured retransmission mode.
int ModuleRtpRtcpImpl::SelectiveRetransmissions() const {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SelectiveRetransmissions()");
  return _rtpSender.SelectiveRetransmissions();
}

// Enable or disable a retransmission mode, which decides which packets will
// be retransmitted if NACKed.
int ModuleRtpRtcpImpl::SetSelectiveRetransmissions(uint8_t settings) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetSelectiveRetransmissions(%u)",
               settings);
  return _rtpSender.SetSelectiveRetransmissions(settings);
}

// Send a Negative acknowledgement packet
WebRtc_Word32 ModuleRtpRtcpImpl::SendNACK(const WebRtc_UWord16* nackList,
                                          const WebRtc_UWord16 size) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SendNACK(size:%u)", size);

  if (size > NACK_PACKETS_MAX_SIZE) {
    RequestKeyFrame();
    return -1;
  }
  WebRtc_UWord16 avgRTT = 0;
  _rtcpReceiver.RTT(_rtpReceiver.SSRC(), NULL, &avgRTT, NULL, NULL);

  WebRtc_UWord32 waitTime = 5 + ((avgRTT * 3) >> 1); // 5 + RTT*1.5
  if (waitTime == 5) {
    waitTime = 100; //During startup we don't have an RTT
  }
  const WebRtc_UWord32 now = _clock.GetTimeInMS();
  const WebRtc_UWord32 timeLimit = now - waitTime;

  if (_nackLastTimeSent < timeLimit) {
    // send list
  } else {
    // only send if extended list
    if (_nackLastSeqNumberSent == nackList[size - 1]) {
      // last seq num is the same don't send list
      return 0;
    } else {
      // send list
    }
  }
  _nackLastTimeSent =  now;
  _nackLastSeqNumberSent = nackList[size - 1];

  switch (_nackMethod) {
    case kNackRtcp:
      return _rtcpSender.SendRTCP(kRtcpNack, size, nackList);
    case kNackOff:
      return -1;
  };
  return -1;
}

// Store the sent packets, needed to answer to a Negative acknowledgement
// requests
WebRtc_Word32 ModuleRtpRtcpImpl::SetStorePacketsStatus(
  const bool enable,
  const WebRtc_UWord16 numberToStore) {
  if (enable) {
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
                 "SetStorePacketsStatus(enable, numberToStore:%d)",
                 numberToStore);
  } else {
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
                 "SetStorePacketsStatus(disable)");
  }
  return _rtpSender.SetStorePacketsStatus(enable, numberToStore);
}

/*
*   Audio
*/

// Outband TelephoneEvent detection
WebRtc_Word32 ModuleRtpRtcpImpl::SetTelephoneEventStatus(
  const bool enable,
  const bool forwardToDecoder,
  const bool detectEndOfTone) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "SetTelephoneEventStatus(enable:%d forwardToDecoder:%d"
               " detectEndOfTone:%d)", enable, forwardToDecoder,
               detectEndOfTone);

  return _rtpReceiver.SetTelephoneEventStatus(enable, forwardToDecoder,
                                              detectEndOfTone);
}

// Is outband TelephoneEvent turned on/off?
bool ModuleRtpRtcpImpl::TelephoneEvent() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "TelephoneEvent()");

  return _rtpReceiver.TelephoneEvent();
}

// Is forwarding of outband telephone events turned on/off?
bool ModuleRtpRtcpImpl::TelephoneEventForwardToDecoder() const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "TelephoneEventForwardToDecoder()");

  return _rtpReceiver.TelephoneEventForwardToDecoder();
}

// Send a TelephoneEvent tone using RFC 2833 (4733)
WebRtc_Word32 ModuleRtpRtcpImpl::SendTelephoneEventOutband(
    const WebRtc_UWord8 key,
    const WebRtc_UWord16 timeMs,
    const WebRtc_UWord8 level) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "SendTelephoneEventOutband(key:%u, timeMs:%u, level:%u)", key,
               timeMs, level);

  return _rtpSender.SendTelephoneEvent(key, timeMs, level);
}

bool ModuleRtpRtcpImpl::SendTelephoneEventActive(
  WebRtc_Word8& telephoneEvent) const {

  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SendTelephoneEventActive()");

  return _rtpSender.SendTelephoneEventActive(telephoneEvent);
}

// set audio packet size, used to determine when it's time to send a DTMF
// packet in silence (CNG)
WebRtc_Word32 ModuleRtpRtcpImpl::SetAudioPacketSize(
  const WebRtc_UWord16 packetSizeSamples) {

  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetAudioPacketSize(%u)",
               packetSizeSamples);

  return _rtpSender.SetAudioPacketSize(packetSizeSamples);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetRTPAudioLevelIndicationStatus(
  const bool enable,
  const WebRtc_UWord8 ID) {

  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetRTPAudioLevelIndicationStatus(enable=%d, ID=%u)",
               enable,
               ID);

  if (enable) {
    _rtpReceiver.RegisterRtpHeaderExtension(kRtpExtensionAudioLevel, ID);
  } else {
    _rtpReceiver.DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel);
  }
  return _rtpSender.SetAudioLevelIndicationStatus(enable, ID);
}

WebRtc_Word32 ModuleRtpRtcpImpl::GetRTPAudioLevelIndicationStatus(
  bool& enable,
  WebRtc_UWord8& ID) const {

  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "GetRTPAudioLevelIndicationStatus()");
  return _rtpSender.AudioLevelIndicationStatus(enable, ID);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetAudioLevel(const WebRtc_UWord8 level_dBov) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetAudioLevel(level_dBov:%u)",
               level_dBov);
  return _rtpSender.SetAudioLevel(level_dBov);
}

// Set payload type for Redundant Audio Data RFC 2198
WebRtc_Word32 ModuleRtpRtcpImpl::SetSendREDPayloadType(
  const WebRtc_Word8 payloadType) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetSendREDPayloadType(%d)",
               payloadType);

  return _rtpSender.SetRED(payloadType);
}

// Get payload type for Redundant Audio Data RFC 2198
WebRtc_Word32 ModuleRtpRtcpImpl::SendREDPayloadType(
    WebRtc_Word8& payloadType) const {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SendREDPayloadType()");

  return _rtpSender.RED(payloadType);
}


/*
*   Video
*/
RtpVideoCodecTypes ModuleRtpRtcpImpl::ReceivedVideoCodec() const {
  return _rtpReceiver.VideoCodecType();
}

RtpVideoCodecTypes ModuleRtpRtcpImpl::SendVideoCodec() const {
  return _rtpSender.VideoCodecType();
}

void ModuleRtpRtcpImpl::SetTargetSendBitrate(const uint32_t bitrate) {
  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
               "SetTargetSendBitrate: %ubit", bitrate);

  const bool haveChildModules(_childModules.empty() ? false : true);
  if (haveChildModules) {
    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
    if (_simulcast) {
      uint32_t bitrate_remainder = bitrate;
      std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
      for (int i = 0; it != _childModules.end() &&
          i < _sendVideoCodec.numberOfSimulcastStreams; ++it, ++i) {
        RTPSender& rtpSender = (*it)->_rtpSender;
        if (_sendVideoCodec.simulcastStream[i].maxBitrate * 1000 >
            bitrate_remainder) {
          rtpSender.SetTargetSendBitrate(bitrate_remainder);
          bitrate_remainder = 0;
        } else {
          rtpSender.SetTargetSendBitrate(
              _sendVideoCodec.simulcastStream[i].maxBitrate * 1000);
          bitrate_remainder -=
              _sendVideoCodec.simulcastStream[i].maxBitrate * 1000;
        }
      }
    } else {
      std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
      for (; it != _childModules.end(); ++it) {
        RTPSender& rtpSender = (*it)->_rtpSender;
        rtpSender.SetTargetSendBitrate(bitrate);
      }
    }
  } else {
    _rtpSender.SetTargetSendBitrate(bitrate);
  }
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetKeyFrameRequestMethod(
  const KeyFrameRequestMethod method) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetKeyFrameRequestMethod(method:%u)",
               method);

  _keyFrameReqMethod = method;
  return 0;
}

WebRtc_Word32 ModuleRtpRtcpImpl::RequestKeyFrame() {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "RequestKeyFrame");

  switch (_keyFrameReqMethod) {
    case kKeyFrameReqFirRtp:
      return _rtpSender.SendRTPIntraRequest();
    case kKeyFrameReqPliRtcp:
      return _rtcpSender.SendRTCP(kRtcpPli);
    case kKeyFrameReqFirRtcp:
      return _rtcpSender.SendRTCP(kRtcpFir);
  }
  return -1;
}

WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCPSliceLossIndication(
  const WebRtc_UWord8 pictureID) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SendRTCPSliceLossIndication (pictureID:%d)",
               pictureID);
  return _rtcpSender.SendRTCP(kRtcpSli, 0, 0, false, pictureID);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetCameraDelay(const WebRtc_Word32 delayMS) {
  WEBRTC_TRACE(kTraceModuleCall,
               kTraceRtpRtcp,
               _id,
               "SetCameraDelay(%d)",
               delayMS);
  const bool defaultInstance(_childModules.empty() ? false : true);

  if (defaultInstance) {
    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());

    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
    while (it != _childModules.end()) {
      RtpRtcp* module = *it;
      if (module) {
        module->SetCameraDelay(delayMS);
      }
      it++;
    }
    return 0;
  }
  return _rtcpSender.SetCameraDelay(delayMS);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetGenericFECStatus(
  const bool enable,
  const WebRtc_UWord8 payloadTypeRED,
  const WebRtc_UWord8 payloadTypeFEC) {
  if (enable) {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetGenericFECStatus(enable, %u)",
                 payloadTypeRED);
  } else {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetGenericFECStatus(disable)");
  }
  return _rtpSender.SetGenericFECStatus(enable,
                                        payloadTypeRED,
                                        payloadTypeFEC);
}

WebRtc_Word32 ModuleRtpRtcpImpl::GenericFECStatus(
  bool& enable,
  WebRtc_UWord8& payloadTypeRED,
  WebRtc_UWord8& payloadTypeFEC) {

  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "GenericFECStatus()");

  bool childEnabled = false;
  const bool defaultInstance(_childModules.empty() ? false : true);
  if (defaultInstance) {
    // for default we need to check all child modules too
    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
    while (it != _childModules.end()) {
      RtpRtcp* module = *it;
      if (module)  {
        bool enabled = false;
        WebRtc_UWord8 dummyPTypeRED = 0;
        WebRtc_UWord8 dummyPTypeFEC = 0;
        if (module->GenericFECStatus(enabled,
                                     dummyPTypeRED,
                                     dummyPTypeFEC) == 0 && enabled) {
          childEnabled = true;
          break;
        }
      }
      it++;
    }
  }
  WebRtc_Word32 retVal = _rtpSender.GenericFECStatus(enable,
                                                     payloadTypeRED,
                                                     payloadTypeFEC);
  if (childEnabled) {
    // returns true if enabled for any child module
    enable = childEnabled;
  }
  return retVal;
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetFecParameters(
    const FecProtectionParams* delta_params,
    const FecProtectionParams* key_params) {
  const bool defaultInstance(_childModules.empty() ? false : true);
  if (defaultInstance)  {
    // for default we need to update all child modules too
    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());

    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
    while (it != _childModules.end()) {
      RtpRtcp* module = *it;
      if (module) {
        module->SetFecParameters(delta_params, key_params);
      }
      it++;
    }
    return 0;
  }
  return _rtpSender.SetFecParameters(delta_params, key_params);
}

void ModuleRtpRtcpImpl::SetRemoteSSRC(const WebRtc_UWord32 SSRC) {
  // inform about the incoming SSRC
  _rtcpSender.SetRemoteSSRC(SSRC);
  _rtcpReceiver.SetRemoteSSRC(SSRC);

  // check for a SSRC collision
  if (_rtpSender.SSRC() == SSRC && !_collisionDetected) {
    // if we detect a collision change the SSRC but only once
    _collisionDetected = true;
    WebRtc_UWord32 newSSRC = _rtpSender.GenerateNewSSRC();
    if (newSSRC == 0) {
      // configured via API ignore
      return;
    }
    if (kRtcpOff != _rtcpSender.Status()) {
      // send RTCP bye on the current SSRC
      _rtcpSender.SendRTCP(kRtcpBye);
    }
    // change local SSRC

    // inform all objects about the new SSRC
    _rtcpSender.SetSSRC(newSSRC);
    _rtcpReceiver.SetSSRC(newSSRC);
  }
}

WebRtc_UWord32 ModuleRtpRtcpImpl::BitrateReceivedNow() const {
  return _rtpReceiver.BitrateNow();
}

void ModuleRtpRtcpImpl::BitrateSent(WebRtc_UWord32* totalRate,
                                    WebRtc_UWord32* videoRate,
                                    WebRtc_UWord32* fecRate,
                                    WebRtc_UWord32* nackRate) const {
  const bool defaultInstance(_childModules.empty() ? false : true);

  if (defaultInstance) {
    // for default we need to update the send bitrate
    CriticalSectionScoped lock(_criticalSectionModulePtrsFeedback.get());

    if (totalRate != NULL)
      *totalRate = 0;
    if (videoRate != NULL)
      *videoRate = 0;
    if (fecRate != NULL)
      *fecRate = 0;
    if (nackRate != NULL)
      *nackRate = 0;

    std::list<ModuleRtpRtcpImpl*>::const_iterator it =
      _childModules.begin();
    while (it != _childModules.end()) {
      RtpRtcp* module = *it;
      if (module) {
        WebRtc_UWord32 childTotalRate = 0;
        WebRtc_UWord32 childVideoRate = 0;
        WebRtc_UWord32 childFecRate = 0;
        WebRtc_UWord32 childNackRate = 0;
        module->BitrateSent(&childTotalRate,
                            &childVideoRate,
                            &childFecRate,
                            &childNackRate);
        if (totalRate != NULL && childTotalRate > *totalRate)
          *totalRate = childTotalRate;
        if (videoRate != NULL && childVideoRate > *videoRate)
          *videoRate = childVideoRate;
        if (fecRate != NULL && childFecRate > *fecRate)
          *fecRate = childFecRate;
        if (nackRate != NULL && childNackRate > *nackRate)
          *nackRate = childNackRate;
      }
      it++;
    }
    return;
  }
  if (totalRate != NULL)
    *totalRate = _rtpSender.BitrateLast();
  if (videoRate != NULL)
    *videoRate = _rtpSender.VideoBitrateSent();
  if (fecRate != NULL)
    *fecRate = _rtpSender.FecOverheadRate();
  if (nackRate != NULL)
    *nackRate = _rtpSender.NackOverheadRate();
}

int ModuleRtpRtcpImpl::EstimatedReceiveBandwidth(
    WebRtc_UWord32* available_bandwidth) const {
  if (!_rtcpSender.ValidBitrateEstimate())
    return -1;
  *available_bandwidth = _rtcpSender.LatestBandwidthEstimate();
  return 0;
}

RateControlRegion ModuleRtpRtcpImpl::OnOverUseStateUpdate(
  const RateControlInput& rateControlInput) {

  bool firstOverUse = false;
  RateControlRegion region = _rtcpSender.UpdateOverUseState(rateControlInput,
                                                            firstOverUse);
  if (firstOverUse) {
    // Send TMMBR or REMB immediately.
    WebRtc_UWord16 RTT = 0;
    _rtcpReceiver.RTT(_rtpReceiver.SSRC(), &RTT, NULL, NULL, NULL);
    // About to send TMMBR, first run remote rate control
    // to get a target bit rate.
    unsigned int target_bitrate =
      _rtcpSender.CalculateNewTargetBitrate(RTT);
    if (REMB()) {
      _rtcpSender.UpdateRemoteBitrateEstimate(target_bitrate);
    } else if (TMMBR()) {
      _rtcpSender.SendRTCP(kRtcpTmmbr);
    }
  }
  return region;
}

// bad state of RTP receiver request a keyframe
void ModuleRtpRtcpImpl::OnRequestIntraFrame() {
  RequestKeyFrame();
}

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

WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection(
  const WebRtc_UWord64 pictureID) {
  return _rtcpSender.SendRTCP(kRtcpRpsi, 0, 0, false, pictureID);
}

WebRtc_UWord32 ModuleRtpRtcpImpl::SendTimeOfSendReport(
  const WebRtc_UWord32 sendReport) {
  return _rtcpSender.SendTimeOfSendReport(sendReport);
}

void ModuleRtpRtcpImpl::OnReceivedNACK(
  const WebRtc_UWord16 nackSequenceNumbersLength,
  const WebRtc_UWord16* nackSequenceNumbers) {
  if (!_rtpSender.StorePackets() ||
      nackSequenceNumbers == NULL ||
      nackSequenceNumbersLength == 0) {
    return;
  }
  WebRtc_UWord16 avgRTT = 0;
  _rtcpReceiver.RTT(_rtpReceiver.SSRC(), NULL, &avgRTT, NULL, NULL);
  _rtpSender.OnReceivedNACK(nackSequenceNumbersLength,
                            nackSequenceNumbers,
                            avgRTT);
}

WebRtc_Word32 ModuleRtpRtcpImpl::LastReceivedNTP(
  WebRtc_UWord32& RTCPArrivalTimeSecs,  // when we received the last report
  WebRtc_UWord32& RTCPArrivalTimeFrac,
  WebRtc_UWord32& remoteSR) {
  // remote SR: NTP inside the last received (mid 16 bits from sec and frac)
  WebRtc_UWord32 NTPsecs = 0;
  WebRtc_UWord32 NTPfrac = 0;

  if (-1 == _rtcpReceiver.NTP(&NTPsecs,
                              &NTPfrac,
                              &RTCPArrivalTimeSecs,
                              &RTCPArrivalTimeFrac)) {
    return -1;
  }
  remoteSR = ((NTPsecs & 0x0000ffff) << 16) + ((NTPfrac & 0xffff0000) >> 16);
  return 0;
}

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

// called from RTCPsender
WebRtc_Word32 ModuleRtpRtcpImpl::BoundingSet(bool& tmmbrOwner,
                                             TMMBRSet*& boundingSet) {
  return _rtcpReceiver.BoundingSet(tmmbrOwner, boundingSet);
}
}  // namespace webrtc
