/*
 *  Copyright (c) 2011 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)
{
    if(audio)
    {
        WEBRTC_TRACE(kTraceModuleCall,
                     kTraceRtpRtcp,
                     id,
                     "CreateRtpRtcp(audio)");
    } else
    {
        WEBRTC_TRACE(kTraceModuleCall,
                     kTraceRtpRtcp,
                     id,
                     "CreateRtpRtcp(video)");
    }
    return new ModuleRtpRtcpImpl(id, audio);
}

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):
    TMMBRHelp(audio),
    _rtpSender(id, audio),
    _rtpReceiver(id, audio, this),
    _rtcpSender(id, audio, this),
    _rtcpReceiver(id, this),
    _id(id),
    _audio(audio),
    _collisionDetected(false),
    _lastProcessTime(ModuleRTPUtility::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::Version(WebRtc_Word8*   version,
                           WebRtc_UWord32& remainingBufferInBytes,
                           WebRtc_UWord32& position) const
{
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "Version(bufferLength:%d)",
                 remainingBufferInBytes);
    return GetVersion(version, remainingBufferInBytes, position);
}

WebRtc_Word32 RtpRtcp::GetVersion(WebRtc_Word8*   version,
                                  WebRtc_UWord32& remainingBufferInBytes,
                                  WebRtc_UWord32& position)
{
    if(version == NULL)
    {
        WEBRTC_TRACE(kTraceWarning,
                     kTraceRtpRtcp,
                     -1,
                     "Invalid in argument to Version()");
        return -1;
    }
    WebRtc_Word8 ourVersion[] = "Module RTP RTCP 1.3.0";
    WebRtc_UWord32 ourLength = (WebRtc_UWord32)strlen(ourVersion);
    if(remainingBufferInBytes < ourLength +1)
    {
        return -1;
    }
    memcpy(version, ourVersion, ourLength);
    version[ourLength] = '\0'; // null terminaion
    remainingBufferInBytes -= (ourLength + 1);
    position += (ourLength + 1);
    return 0;
}

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 = ModuleRTPUtility::GetTimeInMS();
    return kRtpRtcpMaxIdleTimeProcess - (now -_lastProcessTime);
}

// Process any pending tasks such as timeouts
// non time critical events
WebRtc_Word32 ModuleRtpRtcpImpl::Process()
{
    _lastProcessTime = ModuleRTPUtility::GetTimeInMS();

    _rtpReceiver.PacketTimeout();
    _rtcpReceiver.PacketTimeout();

    _rtpSender.ProcessBitrate();
    _rtpReceiver.ProcessBitrate();

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

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

        const bool validRTPHeader = rtpParser.Parse(rtpHeader);
        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
        WebRtc_Word32 retVal = _rtcpSender.SetSendingStatus(sending);

        _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 retVal;
    }
    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 WebRtc_Word8 cName[RTCP_CNAME_SIZE])
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetCNAME(%s)", cName);

    return _rtcpSender.SetCNAME(cName);
}

WebRtc_Word32
ModuleRtpRtcpImpl::CNAME(WebRtc_Word8 cName[RTCP_CNAME_SIZE])
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "CNAME()");

    return _rtcpSender.CNAME(cName);
}

WebRtc_Word32
ModuleRtpRtcpImpl::AddMixedCNAME(const WebRtc_UWord32 SSRC,
                                 const WebRtc_Word8 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,
                               WebRtc_Word8 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_Word32 retVal =_rtpReceiver.Statistics(fraction_lost,cum_lost,ext_max,jitter, max_jitter,(_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_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ReportBlockStatistics()");
    WebRtc_Word32 missing = 0;
    WebRtc_Word32 ret = _rtpReceiver.Statistics(fraction_lost,
                                                cum_lost,ext_max,
                                                jitter,
                                                NULL,
                                                &missing,
                                                true);

#ifdef MATLAB
    if (_plot1 == NULL)
    {
        _plot1 = eng.NewPlot(new MatlabPlot());
        _plot1->AddTimeLine(30, "b", "lost", TickTime::MillisecondTimestamp());
    }
    _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(const WebRtc_UWord32 remoteSSRC,
                                  RTCPReportBlock* receiveBlock)
{
    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteRTCPStat()");

    return _rtcpReceiver.StatisticsReceived(remoteSSRC, receiveBlock);
}

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

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

    // 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 = ModuleRTPUtility::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);
    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);

        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 (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 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.
        _rtcpSender.CalculateNewTargetBitrate(RTT);
        _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) {
        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) {
        // might trigger a OnNetworkChanged in video callback
        _rtpReceiver.UpdateBandwidthManagement(newBitrate,
                                               fractionLost,
                                               roundTripTime);
        if (newBitrate <= 0) {
            return;
        }
        const bool defaultInstance = !_childModules.empty();
        if (!defaultInstance) {
            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++;
        }
    }
}

// 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) != 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;
        }
        // No default module check if we should trigger OnNetworkChanged
        // via video callback
        _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) != 0) {
                // ignore this update
                return;
            }
            _rtpSender.SetTargetSendBitrate(newBitrate);
            // check if we should trigger OnNetworkChanged
            // via video callback
            _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,
                                            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.
    // Check if we should trigger OnNetworkChanged via video callback
    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);
}

WebRtc_Word32 ModuleRtpRtcpImpl::SetH263InverseLogic(const bool enable) {
    WEBRTC_TRACE(kTraceModuleCall,
                 kTraceRtpRtcp,
                 _id,
                 "SetH263InverseLogic(%s)",
                 enable ? "true":"false");
    return _rtpReceiver.SetH263InverseLogic(enable);
}

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