/*
 *  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;
}

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

namespace webrtc {
using namespace RTCPUtility;

RtpRtcp*
RtpRtcp::CreateRtpRtcp(const WebRtc_Word32 id,
                       const bool audio)
{
    return CreateRtpRtcp(id, audio, ModuleRTPUtility::GetSystemClock());
}

RtpRtcp*
RtpRtcp::CreateRtpRtcp(const WebRtc_Word32 id,
                       const bool audio,
                       RtpRtcpClock* clock)
{
    if(audio)
    {
        WEBRTC_TRACE(kTraceModuleCall,
                     kTraceRtpRtcp,
                     id,
                     "CreateRtpRtcp(audio)");
    } else
    {
        WEBRTC_TRACE(kTraceModuleCall,
                     kTraceRtpRtcp,
                     id,
                     "CreateRtpRtcp(video)");
    }
    return new ModuleRtpRtcpImpl(id, audio, clock);
}

void RtpRtcp::DestroyRtpRtcp(RtpRtcp* module)
{
    if(module)
    {
        WEBRTC_TRACE(kTraceModuleCall,
                     kTraceRtpRtcp,
                     static_cast<ModuleRtpRtcpImpl*>(module)->Id(),
                     "DestroyRtpRtcp()");
        delete static_cast<ModuleRtpRtcpImpl*>(module);
    }
}

ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const WebRtc_Word32 id,
                                     const bool audio,
                                     RtpRtcpClock* clock):
    TMMBRHelp(audio),
    _rtpSender(id, audio, clock),
    _rtpReceiver(id, audio, clock, this),
    _rtcpSender(id, audio, clock, this),
    _rtcpReceiver(id, clock, this),
    _clock(*clock),
    _id(id),
    _audio(audio),
    _collisionDetected(false),
    _lastProcessTime(clock->GetTimeInMS()),
    _lastBitrateProcessTime(clock->GetTimeInMS()),
    _lastPacketTimeoutProcessTime(clock->GetTimeInMS()),

    _packetOverHead(28), // IPV4 UDP
    _criticalSectionModulePtrs(CriticalSectionWrapper::CreateCriticalSection()),
    _criticalSectionModulePtrsFeedback(
        CriticalSectionWrapper::CreateCriticalSection()),
    _defaultModule(NULL),
    _audioModule(NULL),
    _videoModule(NULL),
    _deadOrAliveActive(false),
    _deadOrAliveTimeoutMS(0),
    _deadOrAliveLastTimer(0),
    _bandwidthManagement(id),
    _receivedNTPsecsAudio(0),
    _receivedNTPfracAudio(0),
    _RTCPArrivalTimeSecsAudio(0),
    _RTCPArrivalTimeFracAudio(0),
    _nackMethod(kNackOff),
    _nackLastTimeSent(0),
    _nackLastSeqNumberSent(0),
    _simulcast(false),
    _keyFrameReqMethod(kKeyFrameReqFirRtp)
#ifdef MATLAB
    ,_plot1(NULL)
#endif
{
    _sendVideoCodec.codecType = kVideoCodecUnknown;
    // 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__);

    // make sure to unregister this module from other modules

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

    if(defaultInstance)
    {
        // deregister for the default module
        // will go in to the child modules and remove it self
        std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
        while (it != _childModules.end())
        {
            RtpRtcp* module = *it;
            _childModules.erase(it);
            if(module)
            {
                module->DeRegisterDefaultModule();
            }
            it = _childModules.begin();
        }
    } else
    {
        // deregister for the child modules
        // will go in to the default and remove it self
        DeRegisterDefaultModule();
    }

    if(_audio)
    {
        DeRegisterVideoModule();
    } else
    {
        DeRegisterSyncModule();
    }

#ifdef MATLAB
    if (_plot1)
    {
        eng.DeletePlot(_plot1);
        _plot1 = NULL;
    }
#endif

    delete _criticalSectionModulePtrs;
    delete _criticalSectionModulePtrsFeedback;
}

WebRtc_Word32
ModuleRtpRtcpImpl::ChangeUniqueId(const WebRtc_Word32 id)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "ChangeUniqueId(new id:%d)", id);

    _id = id;

    _rtpReceiver.ChangeUniqueId(id);
    _rtcpReceiver.ChangeUniqueId(id);
    _rtpSender.ChangeUniqueId(id);
    _rtcpSender.ChangeUniqueId(id);
    return 0;
}

// default encoder that we need to multiplex out
WebRtc_Word32 ModuleRtpRtcpImpl::RegisterDefaultModule(RtpRtcp* module)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RegisterDefaultModule(module:0x%x)", module);

    if(module == NULL)
    {
        return -1;
    }
    if(module == this)
    {
       WEBRTC_TRACE(kTraceError,
                    kTraceRtpRtcp,
                    _id,
                    "RegisterDefaultModule can't register self as default");
        return -1;
    }
    CriticalSectionScoped lock(_criticalSectionModulePtrs);

    if(_defaultModule)
    {
        _defaultModule->DeRegisterChildModule(this);
    }
    _defaultModule = (ModuleRtpRtcpImpl*)module;
    _defaultModule->RegisterChildModule(this);
    return 0;
}

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

    CriticalSectionScoped lock(_criticalSectionModulePtrs);
    if(_defaultModule)
    {
        _defaultModule->DeRegisterChildModule(this);
        _defaultModule = NULL;
    }
    return 0;
}

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

    CriticalSectionScoped lock(_criticalSectionModulePtrs);
    if(_defaultModule)
    {
        return true;
    }
    return false;
}

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

    CriticalSectionScoped lock(_criticalSectionModulePtrs);
    CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback);
    // we use two locks for protecting _childModules one 
    // (_criticalSectionModulePtrsFeedback) for incoming  messages
    // (BitrateSent and UpdateTMMBR) and _criticalSectionModulePtrs for
    //  all outgoing messages sending packets etc

    return _childModules.size();
}

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

    CriticalSectionScoped lock(_criticalSectionModulePtrs);

    CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback);
    // we use two locks for protecting _childModules one
    // (_criticalSectionModulePtrsFeedback) for incoming
    // messages (BitrateSent and UpdateTMMBR) 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);

    CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback);

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

// Lip-sync between voice-video engine,
WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSyncModule(RtpRtcp* audioModule)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RegisterSyncModule(module:0x%x)",
                 audioModule);

    if(audioModule == NULL)
    {
        return -1;
    }
    if(_audio)
    {
        return -1;
    }
    CriticalSectionScoped lock(_criticalSectionModulePtrs);
    _audioModule = (ModuleRtpRtcpImpl*)audioModule;
    return _audioModule->RegisterVideoModule(this);
}

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

    CriticalSectionScoped lock(_criticalSectionModulePtrs);
    if(_audioModule)
    {
        ModuleRtpRtcpImpl* audioModule = _audioModule;
        _audioModule = NULL;
        _receivedNTPsecsAudio = 0;
        _receivedNTPfracAudio = 0;
        _RTCPArrivalTimeSecsAudio = 0;
        _RTCPArrivalTimeFracAudio = 0;
        audioModule->DeRegisterVideoModule();
    }
    return 0;
}

WebRtc_Word32
ModuleRtpRtcpImpl::RegisterVideoModule(RtpRtcp* videoModule)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RegisterVideoModule(module:0x%x)",
                 videoModule);

    if(videoModule == NULL)
    {
        return -1;
    }
    if(!_audio)
    {
        return -1;
    }
    CriticalSectionScoped lock(_criticalSectionModulePtrs);
    _videoModule = (ModuleRtpRtcpImpl*)videoModule;
    return 0;
}

void ModuleRtpRtcpImpl::DeRegisterVideoModule()
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "DeRegisterVideoModule()");

    CriticalSectionScoped lock(_criticalSectionModulePtrs);
    if(_videoModule)
    {
        ModuleRtpRtcpImpl* videoModule=_videoModule;
        _videoModule=NULL;
        videoModule->DeRegisterSyncModule();
    }
}

// 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 RTT = 0;
      _rtcpReceiver.RTT(_rtpReceiver.SSRC(), &RTT, NULL, NULL, NULL);
      if (REMB() && _rtcpSender.ValidBitrateEstimate())
      {
        unsigned int target_bitrate =
            _rtcpSender.CalculateNewTargetBitrate(RTT);
        _rtcpSender.UpdateRemoteBitrateEstimate(target_bitrate);
      } else if (TMMBR()) {
          _rtcpSender.CalculateNewTargetBitrate(RTT);
      }
      _rtcpSender.SendRTCP(kRtcpReport, 0, 0, RTT);
  }

  if (_rtpSender.RTPKeepalive()) {
    // check time to send RTP keep alive
    if (_rtpSender.TimeToSendRTPKeepalive()) {
      _rtpSender.SendRTPKeepalivePacket();
    }
  }

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

    /**
    *   Receiver
    */

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

    _packetOverHead = 28; // default is IPV4 UDP
    _receivedNTPsecsAudio = 0;
    _receivedNTPfracAudio = 0;
    _RTCPArrivalTimeSecsAudio = 0;
    _RTCPArrivalTimeFracAudio = 0;

    WebRtc_Word32 ret = _rtpReceiver.Init();
    if (ret < 0)
    {
        return ret;
    }
    _rtpReceiver.SetPacketOverHead(_packetOverHead);
    return ret;
}

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);
    }
}

WebRtc_Word32 ModuleRtpRtcpImpl::IncomingAudioNTP(
    const WebRtc_UWord32 audioReceivedNTPsecs,
    const WebRtc_UWord32 audioReceivedNTPfrac,
    const WebRtc_UWord32 audioRTCPArrivalTimeSecs,
    const WebRtc_UWord32 audioRTCPArrivalTimeFrac)
{
    _receivedNTPsecsAudio = audioReceivedNTPsecs;
    _receivedNTPfracAudio = audioReceivedNTPfrac;
    _RTCPArrivalTimeSecsAudio = audioRTCPArrivalTimeSecs;
    _RTCPArrivalTimeFracAudio = audioRTCPArrivalTimeFrac;
    return 0;
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterIncomingDataCallback(
    RtpData* incomingDataCallback)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RegisterIncomingDataCallback(incomingDataCallback:0x%x)",
                 incomingDataCallback);

    return _rtpReceiver.RegisterIncomingDataCallback(incomingDataCallback);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterIncomingRTPCallback(
    RtpFeedback* incomingMessagesCallback)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RegisterIncomingRTPCallback(incomingMessagesCallback:0x%x)",
                 incomingMessagesCallback);

    return _rtpReceiver.RegisterIncomingRTPCallback(incomingMessagesCallback);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterIncomingRTCPCallback(
    RtcpFeedback* incomingMessagesCallback)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RegisterIncomingRTCPCallback(incomingMessagesCallback:0x%x)",
                 incomingMessagesCallback);

    return _rtcpReceiver.RegisterIncomingRTCPCallback(incomingMessagesCallback);
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterIncomingVideoCallback(
    RtpVideoFeedback* incomingMessagesCallback)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RegisterIncomingVideoCallback(incomingMessagesCallback:0x%x)",
                 incomingMessagesCallback);

    if (_rtcpReceiver.RegisterIncomingVideoCallback(incomingMessagesCallback)
        == 0)
    {
        return _rtpReceiver.RegisterIncomingVideoCallback(
            incomingMessagesCallback);
    }
    return -1;
}

WebRtc_Word32 ModuleRtpRtcpImpl::RegisterAudioCallback(
    RtpAudioFeedback* messagesCallback)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RegisterAudioCallback(messagesCallback:0x%x)",
                 messagesCallback);

    if (_rtpSender.RegisterAudioCallback(messagesCallback) == 0)
    {
        return _rtpReceiver.RegisterIncomingAudioCallback(messagesCallback);
    }
    return -1;
}

    /**
    *   Sender
    */

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

    _collisionDetected = false;

    // if we are already receiving inform our sender to avoid collision
    if(_rtpSender.Init(_rtpReceiver.SSRC()) != 0)
    {
        return -1;
    }
    WebRtc_Word32 retVal = _rtcpSender.Init();

    // 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 retVal;
}

bool ModuleRtpRtcpImpl::RTPKeepalive() const
{
    WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, "RTPKeepalive()");

    return _rtpSender.RTPKeepalive();
}

WebRtc_Word32
ModuleRtpRtcpImpl::RTPKeepaliveStatus(bool* enable,
                                      WebRtc_Word8* unknownPayloadType,
                                      WebRtc_UWord16* deltaTransmitTimeMS) const
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RTPKeepaliveStatus()");

    return _rtpSender.RTPKeepaliveStatus(enable,
                                         unknownPayloadType,
                                         deltaTransmitTimeMS);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetRTPKeepaliveStatus(
    bool enable,
    WebRtc_Word8 unknownPayloadType,
    WebRtc_UWord16 deltaTransmitTimeMS)
{
    if (enable)
    {
        WEBRTC_TRACE(
            kTraceModuleCall,
            kTraceRtpRtcp,
            _id,
            "SetRTPKeepaliveStatus(true, plType:%d deltaTransmitTimeMS:%u)",
            unknownPayloadType,
           deltaTransmitTimeMS);

        // check the transmit keepalive delta time [1,60]
        if (deltaTransmitTimeMS < 1000 || deltaTransmitTimeMS > 60000)
        {
            WEBRTC_TRACE(kTraceError,
                         kTraceRtpRtcp,
                         _id,
                         "\tinvalid deltaTransmitTimeSeconds (%d)",
                         deltaTransmitTimeMS);
            return -1;
        }

        // check the payload time [0,127]
        if (unknownPayloadType < 0 )
        {
            WEBRTC_TRACE(kTraceError,
                         kTraceRtpRtcp,
                         _id,
                         "\tinvalid unknownPayloadType (%d)",
                         unknownPayloadType);
            return -1;
        }
        // enable RTP keepalive mechanism
        return _rtpSender.EnableRTPKeepalive(unknownPayloadType,
                                             deltaTransmitTimeMS);
    }else
    {
        WEBRTC_TRACE(kTraceModuleCall,
                     kTraceRtpRtcp,
                     _id,
                     "SetRTPKeepaliveStatus(disable)");
        return _rtpSender.DisableRTPKeepalive();
    }
}

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);

        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
    {
        if(_rtpSender.RTPKeepalive())
        {
            WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "Can't SetSendingStatus(stopped) when RTP Keepalive is active");
            return -1;
        }
        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);
    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::RegisterSendTransport(
    Transport* outgoingTransport)
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RegisterSendTransport(0x%x)", outgoingTransport);

    if(_rtpSender.RegisterSendTransport(outgoingTransport) == 0)
    {
        return _rtcpSender.RegisterSendTransport(outgoingTransport);
    }
    return -1;
}

WebRtc_Word32
ModuleRtpRtcpImpl::SendOutgoingData(const FrameType frameType,
                                    const WebRtc_Word8 payloadType,
                                    const WebRtc_UWord32 timeStamp,
                                    const WebRtc_UWord8* payloadData,
                                    const 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))
        {
            WebRtc_UWord16 RTT = 0;
            _rtcpReceiver.RTT(_rtpReceiver.SSRC(), &RTT, NULL, NULL, NULL);
            _rtcpSender.SendRTCP(kRtcpReport, 0, 0, RTT);
        }
        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);
        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);
        // 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);
        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);
}

bool ModuleRtpRtcpImpl::SetRemoteBitrateObserver(
    RtpRemoteBitrateObserver* observer) {
  return _rtcpSender.SetRemoteBitrateObserver(observer);
}

/*
 *   (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::TMMBRReceived(const WebRtc_UWord32 size,
                                 const WebRtc_UWord32 accNumCandidates,
                                 TMMBRSet* candidateSet) const
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "TMMBRReceived()");

    return _rtcpReceiver.TMMBRReceived(size, accNumCandidates, candidateSet);
}

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

    return _rtcpSender.SetTMMBN(boundingSet, maxBitrateKbit);
}

WebRtc_Word32
ModuleRtpRtcpImpl::RequestTMMBR(const WebRtc_UWord32 estimatedBW,
                                const WebRtc_UWord32 packetOH)
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RequestTMMBR()");

    return _rtcpSender.RequestTMMBR(estimatedBW, packetOH);
}

    /*
    *   (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);
        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(kVideoFrameKey);
        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;
    default:
        assert(false);
    };
    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();
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetSendBitrate(
    const WebRtc_UWord32 startBitrate,
    const WebRtc_UWord16 minBitrateKbit,
    const WebRtc_UWord16 maxBitrateKbit) {

    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetSendBitrate start:%ubit/s min:%uKbit/s max:%uKbit/s",
                 startBitrate, minBitrateKbit, maxBitrateKbit);

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

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

        std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
        while (it != _childModules.end()) {
            RtpRtcp* module = *it;
            if (module) {
                module->SetSendBitrate(startBitrate,
                                       minBitrateKbit,
                                       maxBitrateKbit);
            }
            it++;
        }
    }
    _rtpSender.SetTargetSendBitrate(startBitrate);

    return _bandwidthManagement.SetSendBitrate(startBitrate,
                                               minBitrateKbit,
                                               maxBitrateKbit);
}

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

    _keyFrameReqMethod = method;
    return 0;
}

WebRtc_Word32 ModuleRtpRtcpImpl::RequestKeyFrame(const FrameType frameType) {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "RequestKeyFrame(frameType:%d)",
                 frameType);

    switch (_keyFrameReqMethod) {
    case kKeyFrameReqFirRtp:
        return _rtpSender.SendRTPIntraRequest();

    case kKeyFrameReqPliRtcp:
        return _rtcpSender.SendRTCP(kRtcpPli);

    case kKeyFrameReqFirRtcp: {
            // conference scenario
            WebRtc_UWord16 RTT = 0;
            _rtcpReceiver.RTT(_rtpReceiver.SSRC(), &RTT, NULL, NULL, NULL);
            return _rtcpSender.SendRTCP(kRtcpFir, 0, NULL, RTT);
        }
    default:
        assert(false);
        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, 0, 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);

        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);
        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::SetFECCodeRate(
    const WebRtc_UWord8 keyFrameCodeRate,
    const WebRtc_UWord8 deltaFrameCodeRate) {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetFECCodeRate(%u, %u)",
                 keyFrameCodeRate,
                 deltaFrameCodeRate);

    const bool defaultInstance(_childModules.empty() ? false : true);
    if (defaultInstance)  {
        // for default we need to update all child modules too
        CriticalSectionScoped lock(_criticalSectionModulePtrs);

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

WebRtc_Word32 ModuleRtpRtcpImpl::SetFECUepProtection(
    const bool keyUseUepProtection,
    const bool deltaUseUepProtection) {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp, _id,
                 "SetFECUepProtection(%d, %d)",
                  keyUseUepProtection,
                  deltaUseUepProtection);

    const bool defaultInstance(_childModules.empty()?false:true);
    if (defaultInstance)  {
        // for default we need to update all child modules too
        CriticalSectionScoped lock(_criticalSectionModulePtrs);

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

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);

        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();
}

// for lip sync
void ModuleRtpRtcpImpl::OnReceivedNTP() {
    // don't do anything if we are the audio module
    // video module is responsible for sync
    if (!_audio) {
        WebRtc_Word32 diff = 0;
        WebRtc_UWord32 receivedNTPsecs = 0;
        WebRtc_UWord32 receivedNTPfrac= 0;
        WebRtc_UWord32 RTCPArrivalTimeSecs= 0;
        WebRtc_UWord32 RTCPArrivalTimeFrac= 0;

        if (0 == _rtcpReceiver.NTP(&receivedNTPsecs,
                                   &receivedNTPfrac,
                                   &RTCPArrivalTimeSecs,
                                   &RTCPArrivalTimeFrac)) {
            CriticalSectionScoped lock(_criticalSectionModulePtrs);

            if (_audioModule) {
                if (0 != _audioModule->RemoteNTP(&_receivedNTPsecsAudio,
                                                 &_receivedNTPfracAudio,
                                                 &_RTCPArrivalTimeSecsAudio,
                                                 &_RTCPArrivalTimeFracAudio)) {
                    // failed ot get audio NTP
                    return;
                }
            }
            if (_receivedNTPfracAudio != 0) {
                // ReceivedNTPxxx is NTP at sender side when sent.
                // RTCPArrivalTimexxx is NTP at receiver side when received.
                // can't use ConvertNTPTimeToMS since calculation can be
                //  negative

                WebRtc_Word32 NTPdiff = (WebRtc_Word32)
                     ((_receivedNTPsecsAudio - receivedNTPsecs)*1000);  // ms
                NTPdiff += (WebRtc_Word32)
                    (_receivedNTPfracAudio/FracMS - receivedNTPfrac/FracMS);

                WebRtc_Word32 RTCPdiff = (WebRtc_Word32)
                    ((_RTCPArrivalTimeSecsAudio - RTCPArrivalTimeSecs)*1000);
                RTCPdiff += (WebRtc_Word32)
                    (_RTCPArrivalTimeFracAudio/FracMS -
                     RTCPArrivalTimeFrac/FracMS);

                diff = NTPdiff - RTCPdiff;
                // if diff is + video is behind
                if (diff < -1000 || diff > 1000) {
                    // unresonable ignore value.
                    diff = 0;
                    return;
                }
            }
        }
        // export via callback
        // after release of critsect
        _rtcpReceiver.UpdateLipSync(diff);
    }
}

// our local BW estimate is updated
void ModuleRtpRtcpImpl::OnBandwidthEstimateUpdate(
    WebRtc_UWord16 bandWidthKbit) {

    WebRtc_UWord32 maxBitrateKbit = _rtpReceiver.MaxConfiguredBitrate()/1000;
    if (maxBitrateKbit) {
        // the app has set a max bitrate
        if (maxBitrateKbit < bandWidthKbit) {
            // cap TMMBR at max configured bitrate
            bandWidthKbit = (WebRtc_UWord16)maxBitrateKbit;
        }
    }
    if (_rtcpSender.TMMBR()) {
        /* Maximum total media bit rate:
            The upper limit on total media bit rate for a given media
            stream at a particular receiver and for its selected protocol
            layer.  Note that this value cannot be measured on the
            received media stream.  Instead, it needs to be calculated or
            determined through other means, such as quality of service
            (QoS) negotiations or local resource limitations.  Also note
            that this value is an average (on a timescale that is
            reasonable for the application) and that it may be different
            from the instantaneous bit rate seen by packets in the media
            stream.
        */
        /* Overhead:
            All protocol header information required to convey a packet
            with media data from sender to receiver, from the application
            layer down to a pre-defined protocol level (for example, down
            to, and including, the IP header).  Overhead may include, for
            example, IP, UDP, and RTP headers, any layer 2 headers, any
            Contributing Sources (CSRCs), RTP padding, and RTP header
            extensions.  Overhead excludes any RTP payload headers and the
            payload itself.
        */
        _rtpReceiver.PacketOHReceived();

        // call RequestTMMBR when our localy created estimate changes
        _rtcpSender.RequestTMMBR(bandWidthKbit, 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(const FrameType frameType) {
    RequestKeyFrame(frameType);
}

void ModuleRtpRtcpImpl::OnReceivedIntraFrameRequest(const RtpRtcp* caller) {
    if (_defaultModule) {
        CriticalSectionScoped lock(_criticalSectionModulePtrs);
        if (_defaultModule) {
            // if we use a default module pass this info to the default module
            _defaultModule->OnReceivedIntraFrameRequest(caller);
            return;
        }
    }

    WebRtc_UWord8 streamIdx = 0;
    FrameType frameType = kVideoFrameKey;
    if (_simulcast) {
        CriticalSectionScoped lock(_criticalSectionModulePtrs);
        // loop though child modules and count idx
        std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
        while (it != _childModules.end()) {
            ModuleRtpRtcpImpl* childModule = *it;
            if (childModule == caller) {
                break;
            }
            streamIdx++;
            it++;
        }
    }
    _rtcpReceiver.OnReceivedIntraFrameRequest(frameType, streamIdx);
}

void ModuleRtpRtcpImpl::OnReceivedEstimatedMaxBitrate(
    const WebRtc_UWord32 maxBitrate) {

  // We received a REMB.
  if (_defaultModule) {
    // Let the default module handle this.
    CriticalSectionScoped lock(_criticalSectionModulePtrs);
    if (_defaultModule) {
      // if we use a default module pass this info to the default module
      _defaultModule->OnReceivedEstimatedMaxBitrate(maxBitrate);
      return;
    }
  }
  WebRtc_UWord32 newBitrate = 0;
  WebRtc_UWord8 fractionLost = 0;
  WebRtc_UWord16 roundTripTime = 0;
  WebRtc_UWord16 bwEstimateKbit = WebRtc_UWord16(maxBitrate / 1000);
  if (_bandwidthManagement.UpdateBandwidthEstimate(bwEstimateKbit,
                                                   &newBitrate,
                                                   &fractionLost,
                                                   &roundTripTime) == 0) {
    // TODO(mflodman) When encoding two streams, we need to split the
    // bitrate between REMB sending channels.
    _rtpReceiver.UpdateBandwidthManagement(newBitrate,
                                           fractionLost,
                                           roundTripTime);

    // We've received a new bandwidth estimate lower than the current send
    // bitrate. For simulcast we need to update the sending bitrate for all
    // streams.
    if (_simulcast) {
      CriticalSectionScoped lock(_criticalSectionModulePtrsFeedback);
      WebRtc_UWord8 idx = 0;
      for (std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
           it != _childModules.end(); ++it) {
        // sanity
        if (idx >= (_sendVideoCodec.numberOfSimulcastStreams - 1)) {
          return;
        }
        ModuleRtpRtcpImpl* module = *it;
        if (newBitrate >= _sendVideoCodec.simulcastStream[idx].maxBitrate) {
          module->_bandwidthManagement.SetSendBitrate(
              _sendVideoCodec.simulcastStream[idx].maxBitrate, 0, 0);
          module->_rtpSender.SetTargetSendBitrate(
              _sendVideoCodec.simulcastStream[idx].maxBitrate);

          newBitrate -= _sendVideoCodec.simulcastStream[idx].maxBitrate;
        } else {
          module->_bandwidthManagement.SetSendBitrate(newBitrate, 0, 0);
          module->_rtpSender.SetTargetSendBitrate(newBitrate);
          newBitrate -= newBitrate;
        }
        idx++;
      }
    }
  }
  // For non-simulcast, update all child modules with the new bandwidth estimate
  // regardless of the new estimate.
  if (!_simulcast) {
    // Update all child modules with the new max bitrate before exiting.
    CriticalSectionScoped lock(_criticalSectionModulePtrsFeedback);
    for (std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
        it != _childModules.end(); ++it) {
      // Update all child modules with the maximum bitrate estimate.
      ModuleRtpRtcpImpl* module = *it;
      WebRtc_UWord32 ignoreBitrate = 0;
      WebRtc_UWord8 ignoreFractionLost = 0;
      WebRtc_UWord16 ignoreRoundTripTime = 0;
      module->_bandwidthManagement.UpdateBandwidthEstimate(
          bwEstimateKbit,
          &ignoreBitrate,
          &ignoreFractionLost,
          &ignoreRoundTripTime);
      // We don't need to take care of a possible lowered bitrate, that is
      // handled earlier in this function for the default module.
    }
  }
}

// received a request for a new SLI
void ModuleRtpRtcpImpl::OnReceivedSliceLossIndication(
    const WebRtc_UWord8 pictureID) {

    if (_defaultModule) {
        CriticalSectionScoped lock(_criticalSectionModulePtrs);
        if (_defaultModule) {
            // if we use a default module pass this info to the default module
            _defaultModule->OnReceivedSliceLossIndication(pictureID);
            return;
        }
    }
    _rtcpReceiver.OnReceivedSliceLossIndication(pictureID);
}

// received a new refereence frame
void ModuleRtpRtcpImpl::OnReceivedReferencePictureSelectionIndication(
    const WebRtc_UWord64 pictureID) {

    if (_defaultModule) {
        CriticalSectionScoped lock(_criticalSectionModulePtrs);
        if (_defaultModule) {
            // if we use a default module pass this info to the default module
            _defaultModule->OnReceivedReferencePictureSelectionIndication(
                pictureID);
            return;
        }
    }
    _rtcpReceiver.OnReceivedReferencePictureSelectionIndication(pictureID);
}

void ModuleRtpRtcpImpl::OnReceivedBandwidthEstimateUpdate(
     const WebRtc_UWord16 bwEstimateKbit) {

    // We received a TMMBR
    const bool defaultInstance(_childModules.empty() ? false : true);
    if (defaultInstance) {
        ProcessDefaultModuleBandwidth();
        return;
    }
    if (_audio) {
        _rtcpReceiver.UpdateBandwidthEstimate(bwEstimateKbit);
    } else {
        WebRtc_UWord32 newBitrate = 0;
        WebRtc_UWord8 fractionLost = 0;
        WebRtc_UWord16 roundTripTime = 0;
        if (_bandwidthManagement.UpdateBandwidthEstimate(bwEstimateKbit,
                                                         &newBitrate,
                                                         &fractionLost,
                                                         &roundTripTime) == 0) {
            if (!_defaultModule) {
                // No default module check if we should trigger OnNetworkChanged
                // via video callback
                _rtpReceiver.UpdateBandwidthManagement(newBitrate,
                                                       fractionLost,
                                                       roundTripTime);
            }
            if (newBitrate > 0) {
                // update bitrate
                _rtpSender.SetTargetSendBitrate(newBitrate);
            }
        }
    }
    if (_defaultModule) {
        CriticalSectionScoped lock(_criticalSectionModulePtrs);
        if (_defaultModule) {
            // if we use a default module pass this info to the default module
            _defaultModule->OnReceivedBandwidthEstimateUpdate(bwEstimateKbit);
            return;
        }
    }
}

// bw estimation
// We received a RTCP report block
void ModuleRtpRtcpImpl::OnPacketLossStatisticsUpdate(
    const WebRtc_UWord8 fractionLost,
    const WebRtc_UWord16 roundTripTime,
    const WebRtc_UWord32 lastReceivedExtendedHighSeqNum) {

    const bool defaultInstance(_childModules.empty() ? false : true);
    if (!defaultInstance) {
        WebRtc_UWord32 newBitrate = 0;
        WebRtc_UWord8 loss = fractionLost;  // local copy since it can change
        WebRtc_UWord32 videoRate = 0;
        WebRtc_UWord32 fecRate = 0;
        WebRtc_UWord32 nackRate = 0;
        BitrateSent(NULL, &videoRate, &fecRate, &nackRate);
        if (_bandwidthManagement.UpdatePacketLoss(
            lastReceivedExtendedHighSeqNum,
            videoRate + fecRate + nackRate,
            roundTripTime,
            &loss,
            &newBitrate,
            _clock.GetTimeInMS()) != 0) {
            // ignore this update
            return;
        }
        // We need to do update RTP sender before calling default module in
        // case we'll strip any layers.
        if (!_simulcast) {
            // the default module will inform all child modules about
            //  their bitrate
            _rtpSender.SetTargetSendBitrate(newBitrate);
        }
        if (_defaultModule) {
            // if we have a default module update it
            CriticalSectionScoped lock(_criticalSectionModulePtrs);
            if (_defaultModule) {  // we need to check again inside the critsect
                // if we use a default module pass this info to the
                // default module
                _defaultModule->OnPacketLossStatisticsUpdate(
                        loss,  // send in the filtered loss
                        roundTripTime,
                        lastReceivedExtendedHighSeqNum);
            }
            return;
        }
        _rtpReceiver.UpdateBandwidthManagement(newBitrate,
                                               fractionLost,
                                               roundTripTime);
    } else {
        if (!_simulcast) {
            ProcessDefaultModuleBandwidth();
        } else {
            // default and simulcast
            WebRtc_UWord32 newBitrate = 0;
            WebRtc_UWord8 loss = fractionLost;  // local copy
            WebRtc_UWord32 videoRate = 0;
            WebRtc_UWord32 fecRate = 0;
            WebRtc_UWord32 nackRate = 0;
            BitrateSent(NULL, &videoRate, &fecRate, &nackRate);
            if (_bandwidthManagement.UpdatePacketLoss(0,  // we can't use this
                                             videoRate + fecRate + nackRate,
                                             roundTripTime,
                                             &loss,
                                             &newBitrate,
                                             _clock.GetTimeInMS()) != 0) {
                // ignore this update
                return;
            }
            _rtpSender.SetTargetSendBitrate(newBitrate);
            _rtpReceiver.UpdateBandwidthManagement(newBitrate,
                                                   loss,
                                                   roundTripTime);
            // sanity
            if (_sendVideoCodec.codecType == kVideoCodecUnknown) {
                return;
            }
            CriticalSectionScoped lock(_criticalSectionModulePtrsFeedback);
            std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
            WebRtc_UWord8 idx = 0;
            while (it != _childModules.end()) {
                // sanity
                if (idx >= (_sendVideoCodec.numberOfSimulcastStreams - 1)) {
                    return;
                }
                ModuleRtpRtcpImpl* module = *it;
                // update all child modules
                if (newBitrate >=
                    _sendVideoCodec.simulcastStream[idx].maxBitrate) {
                    module->_bandwidthManagement.SetSendBitrate(
                        _sendVideoCodec.simulcastStream[idx].maxBitrate, 0, 0);
                    module->_rtpSender.SetTargetSendBitrate(
                        _sendVideoCodec.simulcastStream[idx].maxBitrate);

                    newBitrate -=
                        _sendVideoCodec.simulcastStream[idx].maxBitrate;
                } else {
                    module->_bandwidthManagement.SetSendBitrate(newBitrate,
                                                                0,
                                                                0);
                    module->_rtpSender.SetTargetSendBitrate(newBitrate);
                    newBitrate -= newBitrate;
                }
                idx++;
            }
        }
    }
}

void ModuleRtpRtcpImpl::ProcessDefaultModuleBandwidth() {

    WebRtc_UWord32 minBitrateBps = 0xffffffff;
    WebRtc_UWord32 maxBitrateBps = 0;
    WebRtc_UWord32 count = 0;
    WebRtc_UWord32 fractionLostAcc = 0;
    WebRtc_UWord16 maxRoundTripTime = 0;
    {
        // get min and max for the sending channels
        CriticalSectionScoped lock(_criticalSectionModulePtrs);

        std::list<ModuleRtpRtcpImpl*>::iterator it =
            _childModules.begin();
        while (it != _childModules.end()) {
            // Get child RTP sender and ask for bitrate estimate
            ModuleRtpRtcpImpl* childModule = *it;
            if (childModule->Sending()) {
                count++;
                RTPSender& childRtpSender = (*it)->_rtpSender;
                const WebRtc_UWord32 childEstimateBps =
                    1000 * childRtpSender.TargetSendBitrateKbit();
                if (childEstimateBps < minBitrateBps) {
                    minBitrateBps = childEstimateBps;
                }
                if (childEstimateBps > maxBitrateBps) {
                    maxBitrateBps = childEstimateBps;
                }
                WebRtc_UWord16 RTT = 0;
                WebRtc_UWord8 fractionLost = 0;
                RTPReceiver& childRtpReceiver = (*it)->_rtpReceiver;
                RTCPReceiver& childRtcpReceiver = (*it)->_rtcpReceiver;
                childRtpReceiver.Statistics(&fractionLost,
                                            NULL,
                                            NULL,
                                            NULL,
                                            NULL,
                                            NULL,
                                            false);
                fractionLostAcc += fractionLost;
                childRtcpReceiver.RTT(childRtpReceiver.SSRC(),
                                      &RTT,
                                      NULL,
                                      NULL,
                                      NULL);
                maxRoundTripTime =
                    (RTT > maxRoundTripTime) ? RTT : maxRoundTripTime;
            }
            it++;
        }
    }  // end critsect

    if (count == 0) {
        // No sending modules and no bitrate estimate.
        return;
    }
    _bandwidthManagement.SetSendBitrate(minBitrateBps, 0, 0);

    // Update default module bitrate. Don't care about min max.
    WebRtc_UWord8 fractionLostAvg = WebRtc_UWord8(fractionLostAcc / count);
    _rtpReceiver.UpdateBandwidthManagement(minBitrateBps,
                                           fractionLostAvg ,
                                           maxRoundTripTime);
}

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

WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection(
    const WebRtc_UWord64 pictureID) {
    return _rtcpSender.SendRTCP(kRtcpRpsi, 0, 0, 0, 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;
}

void
ModuleRtpRtcpImpl::OnReceivedTMMBR() {
    // we received a TMMBR in a RTCP packet
    // answer with a TMMBN
    UpdateTMMBR();
}

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();
}

WebRtc_Word32 ModuleRtpRtcpImpl::UpdateTMMBR() {
    WebRtc_Word32 numBoundingSet = 0;
    WebRtc_Word32 newBitrates = 0;
    WebRtc_UWord32 minBitrateKbit = 0;
    WebRtc_UWord32 maxBitrateKbit = 0;
    WebRtc_UWord32 accNumCandidates = 0;

    if (!_childModules.empty()) {
        // Default module should not handle this
        return -1;
    }

    WebRtc_Word32 size = _rtcpReceiver.TMMBRReceived(0, 0, NULL);
    if (size > 0) {
        TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
        // get candidate set from receiver
        accNumCandidates = _rtcpReceiver.TMMBRReceived(size,
                                                       accNumCandidates,
                                                       candidateSet);
    } else {
        // candidate set empty
        VerifyAndAllocateCandidateSet(0);  // resets candidate set
    }
    // Find bounding set
    TMMBRSet* boundingSet = NULL;
    numBoundingSet = FindTMMBRBoundingSet(boundingSet);
    if (numBoundingSet == -1) {
        WEBRTC_TRACE(kTraceWarning,
                     kTraceRtpRtcp,
                     _id,
                     "Failed to find TMMBR bounding set.");
        return -1;
    }
    // Set bounding set
    // Inform remote clients about the new bandwidth
    // inform the remote client
    _rtcpSender.SetTMMBN(boundingSet,
                        _rtpSender.MaxConfiguredBitrateVideo()/1000);
    // might trigger a TMMBN
    if (numBoundingSet == 0) {
        // owner of max bitrate request has timed out
        // empty bounding set has been sent
        return 0;
    }
    // Get net bitrate from bounding set depending on sent packet rate
    newBitrates = CalcMinMaxBitRate(_rtpSender.PacketRate(),
                                    (WebRtc_UWord32)numBoundingSet,
                                    minBitrateKbit,
                                    maxBitrateKbit);

    // no critsect when calling out to "unknown" code
    if (newBitrates == 0) {
        // we have new bitrate
        // Set new max bitrate
        // we have a new bandwidth estimate on this channel
        OnReceivedBandwidthEstimateUpdate((WebRtc_UWord16)minBitrateKbit);
        WEBRTC_TRACE(kTraceStream,
                     kTraceRtpRtcp,
                     _id,
                     "Set TMMBR request min:%d kbps max:%d kbps, channel: %d",
                     minBitrateKbit, maxBitrateKbit, _id);
    }
    return 0;
}

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

void ModuleRtpRtcpImpl::SendKeyFrame() {
    WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, "SendKeyFrame()");
    OnReceivedIntraFrameRequest(0);
}
}  // namespace webrtc
