rtp_rtcp_impl.cc revision 2f225cadde8627a64d2cede283965bac25a2807c
1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
12
13#include <cassert>
14#include <string.h>
15
16#include "webrtc/common_types.h"
17#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_audio.h"
18#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
19#include "webrtc/system_wrappers/interface/logging.h"
20#include "webrtc/system_wrappers/interface/trace.h"
21
22#ifdef MATLAB
23#include "webrtc/modules/rtp_rtcp/test/BWEStandAlone/MatlabPlot.h"
24extern MatlabEngine eng; // global variable defined elsewhere
25#endif
26
27
28// local for this file
29namespace {
30
31const float FracMS = 4.294967296E6f;
32
33}  // namepace
34
35#ifdef _WIN32
36// disable warning C4355: 'this' : used in base member initializer list
37#pragma warning(disable : 4355)
38#endif
39
40namespace webrtc {
41
42const WebRtc_UWord16 kDefaultRtt = 200;
43
44RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) {
45  if (configuration.clock) {
46    return new ModuleRtpRtcpImpl(configuration);
47  } else {
48    RtpRtcp::Configuration configuration_copy;
49    memcpy(&configuration_copy, &configuration,
50           sizeof(RtpRtcp::Configuration));
51    configuration_copy.clock = ModuleRTPUtility::GetSystemClock();
52    ModuleRtpRtcpImpl* rtp_rtcp_instance =
53        new ModuleRtpRtcpImpl(configuration_copy);
54    rtp_rtcp_instance->OwnsClock();
55    return rtp_rtcp_instance;
56  }
57}
58
59ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
60    : _rtpSender(configuration.id,
61                 configuration.audio,
62                 configuration.clock,
63                 configuration.outgoing_transport,
64                 configuration.audio_messages,
65                 configuration.paced_sender),
66      _rtpReceiver(configuration.id, configuration.audio, configuration.clock,
67                   this, configuration.audio_messages),
68      _rtcpSender(configuration.id, configuration.audio, configuration.clock,
69                  this),
70      _rtcpReceiver(configuration.id, configuration.clock, this),
71      _owns_clock(false),
72      _clock(*configuration.clock),
73      _id(configuration.id),
74      _audio(configuration.audio),
75      _collisionDetected(false),
76      _lastProcessTime(configuration.clock->GetTimeInMS()),
77      _lastBitrateProcessTime(configuration.clock->GetTimeInMS()),
78      _lastPacketTimeoutProcessTime(configuration.clock->GetTimeInMS()),
79      _packetOverHead(28),  // IPV4 UDP
80      _criticalSectionModulePtrs(
81          CriticalSectionWrapper::CreateCriticalSection()),
82      _criticalSectionModulePtrsFeedback(
83          CriticalSectionWrapper::CreateCriticalSection()),
84      _defaultModule(
85          static_cast<ModuleRtpRtcpImpl*>(configuration.default_module)),
86      _deadOrAliveActive(false),
87      _deadOrAliveTimeoutMS(0),
88      _deadOrAliveLastTimer(0),
89      _nackMethod(kNackOff),
90      _nackLastTimeSent(0),
91      _nackLastSeqNumberSent(0),
92      _simulcast(false),
93      _keyFrameReqMethod(kKeyFrameReqFirRtp),
94      remote_bitrate_(configuration.remote_bitrate_estimator),
95      rtt_observer_(configuration.rtt_observer)
96#ifdef MATLAB
97       , _plot1(NULL)
98#endif
99{
100  _sendVideoCodec.codecType = kVideoCodecUnknown;
101
102  if (_defaultModule) {
103    _defaultModule->RegisterChildModule(this);
104  }
105  // TODO(pwestin) move to constructors of each rtp/rtcp sender/receiver object.
106  _rtpReceiver.RegisterIncomingDataCallback(configuration.incoming_data);
107  _rtpReceiver.RegisterIncomingRTPCallback(configuration.incoming_messages);
108  _rtcpReceiver.RegisterRtcpObservers(configuration.intra_frame_callback,
109                                      configuration.bandwidth_callback,
110                                      configuration.rtcp_feedback);
111  _rtcpSender.RegisterSendTransport(configuration.outgoing_transport);
112
113  // make sure that RTCP objects are aware of our SSRC
114  WebRtc_UWord32 SSRC = _rtpSender.SSRC();
115  _rtcpSender.SetSSRC(SSRC);
116  _rtcpReceiver.SetSSRC(SSRC);
117
118  WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s created", __FUNCTION__);
119}
120
121ModuleRtpRtcpImpl::~ModuleRtpRtcpImpl() {
122  WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__);
123
124  // All child modules MUST be deleted before deleting the default.
125  assert(_childModules.empty());
126
127  // Deregister for the child modules
128  // will go in to the default and remove it self
129  if (_defaultModule) {
130    _defaultModule->DeRegisterChildModule(this);
131  }
132#ifdef MATLAB
133  if (_plot1) {
134    eng.DeletePlot(_plot1);
135    _plot1 = NULL;
136  }
137#endif
138  if (_owns_clock) {
139    delete &_clock;
140  }
141}
142
143void ModuleRtpRtcpImpl::RegisterChildModule(RtpRtcp* module) {
144  WEBRTC_TRACE(kTraceModuleCall,
145               kTraceRtpRtcp,
146               _id,
147               "RegisterChildModule(module:0x%x)",
148               module);
149
150  CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
151
152  CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback.get());
153  // we use two locks for protecting _childModules one
154  // (_criticalSectionModulePtrsFeedback) for incoming
155  // messages (BitrateSent) and _criticalSectionModulePtrs
156  //  for all outgoing messages sending packets etc
157  _childModules.push_back((ModuleRtpRtcpImpl*)module);
158}
159
160void ModuleRtpRtcpImpl::DeRegisterChildModule(RtpRtcp* removeModule) {
161  WEBRTC_TRACE(kTraceModuleCall,
162               kTraceRtpRtcp,
163               _id,
164               "DeRegisterChildModule(module:0x%x)", removeModule);
165
166  CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
167
168  CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback.get());
169
170  std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
171  while (it != _childModules.end()) {
172    RtpRtcp* module = *it;
173    if (module == removeModule) {
174      _childModules.erase(it);
175      return;
176    }
177    it++;
178  }
179}
180
181// returns the number of milliseconds until the module want a worker thread
182// to call Process
183WebRtc_Word32 ModuleRtpRtcpImpl::TimeUntilNextProcess() {
184  const WebRtc_Word64 now = _clock.GetTimeInMS();
185  return kRtpRtcpMaxIdleTimeProcess - (now - _lastProcessTime);
186}
187
188// Process any pending tasks such as timeouts
189// non time critical events
190WebRtc_Word32 ModuleRtpRtcpImpl::Process() {
191  const WebRtc_Word64 now = _clock.GetTimeInMS();
192  _lastProcessTime = now;
193
194  if (now >= _lastPacketTimeoutProcessTime +
195      kRtpRtcpPacketTimeoutProcessTimeMs) {
196    _rtpReceiver.PacketTimeout();
197    _rtcpReceiver.PacketTimeout();
198    _lastPacketTimeoutProcessTime = now;
199  }
200
201  if (now >= _lastBitrateProcessTime + kRtpRtcpBitrateProcessTimeMs) {
202    _rtpSender.ProcessBitrate();
203    _rtpReceiver.ProcessBitrate();
204    _lastBitrateProcessTime = now;
205  }
206
207  ProcessDeadOrAliveTimer();
208
209  const bool defaultInstance(_childModules.empty() ? false : true);
210  if (!defaultInstance && _rtcpSender.TimeToSendRTCPReport()) {
211    WebRtc_UWord16 max_rtt = 0;
212    if (_rtcpSender.Sending()) {
213      std::vector<RTCPReportBlock> receive_blocks;
214      _rtcpReceiver.StatisticsReceived(&receive_blocks);
215      for (std::vector<RTCPReportBlock>::iterator it = receive_blocks.begin();
216           it != receive_blocks.end(); ++it) {
217        WebRtc_UWord16 rtt = 0;
218        _rtcpReceiver.RTT(it->remoteSSRC, &rtt, NULL, NULL, NULL);
219        max_rtt = (rtt > max_rtt) ? rtt : max_rtt;
220      }
221      // Report the rtt.
222      if (rtt_observer_ && max_rtt != 0)
223        rtt_observer_->OnRttUpdate(max_rtt);
224    } else {
225      // No valid RTT estimate, probably since this is a receive only channel.
226      // Use an estimate set by a send module.
227      max_rtt = _rtcpReceiver.RTT();
228    }
229    if (max_rtt == 0) {
230      // No own rtt calculation or set rtt, use default value.
231      max_rtt = kDefaultRtt;
232    }
233
234    // Verify receiver reports are delivered and the reported sequence number is
235    // increasing.
236    if (_rtcpSender.Sending()) {
237      int64_t rtcp_interval = RtcpReportInterval();
238      if (_rtcpReceiver.RtcpRrTimeout(rtcp_interval)) {
239        LOG_F(LS_WARNING) << "Timeout: No RTCP RR received.";
240      } else if (_rtcpReceiver.RtcpRrSequenceNumberTimeout(rtcp_interval)) {
241        LOG_F(LS_WARNING) <<
242            "Timeout: No increase in RTCP RR extended highest sequence number.";
243      }
244    }
245
246    if (remote_bitrate_) {
247      // TODO(mflodman) Remove this and let this be propagated by CallStats.
248      remote_bitrate_->SetRtt(max_rtt);
249      remote_bitrate_->UpdateEstimate(_rtpReceiver.SSRC(), now);
250      if (TMMBR()) {
251        unsigned int target_bitrate = 0;
252        std::vector<unsigned int> ssrcs;
253        if (remote_bitrate_->LatestEstimate(&ssrcs, &target_bitrate)) {
254          if (!ssrcs.empty()) {
255            target_bitrate = target_bitrate / ssrcs.size();
256          }
257          _rtcpSender.SetTargetBitrate(target_bitrate);
258        }
259      }
260    }
261    _rtcpSender.SendRTCP(kRtcpReport);
262  }
263
264  if (UpdateRTCPReceiveInformationTimers()) {
265    // a receiver has timed out
266    _rtcpReceiver.UpdateTMMBR();
267  }
268  return 0;
269}
270
271/**
272*   Receiver
273*/
274
275void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer() {
276  if (_deadOrAliveActive) {
277    const WebRtc_Word64 now = _clock.GetTimeInMS();
278    if (now > _deadOrAliveTimeoutMS + _deadOrAliveLastTimer) {
279      // RTCP is alive if we have received a report the last 12 seconds
280      _deadOrAliveLastTimer += _deadOrAliveTimeoutMS;
281
282      bool RTCPalive = false;
283      if (_rtcpReceiver.LastReceived() + 12000 > now) {
284        RTCPalive = true;
285      }
286      _rtpReceiver.ProcessDeadOrAlive(RTCPalive, now);
287    }
288  }
289}
290
291WebRtc_Word32 ModuleRtpRtcpImpl::SetPeriodicDeadOrAliveStatus(
292  const bool enable,
293  const WebRtc_UWord8 sampleTimeSeconds) {
294  if (enable) {
295    WEBRTC_TRACE(kTraceModuleCall,
296                 kTraceRtpRtcp,
297                 _id,
298                 "SetPeriodicDeadOrAliveStatus(enable, %d)",
299                 sampleTimeSeconds);
300  } else {
301    WEBRTC_TRACE(kTraceModuleCall,
302                 kTraceRtpRtcp,
303                 _id,
304                 "SetPeriodicDeadOrAliveStatus(disable)");
305  }
306  if (sampleTimeSeconds == 0) {
307    return -1;
308  }
309  _deadOrAliveActive = enable;
310  _deadOrAliveTimeoutMS = sampleTimeSeconds * 1000;
311  // trigger the first after one period
312  _deadOrAliveLastTimer = _clock.GetTimeInMS();
313  return 0;
314}
315
316WebRtc_Word32 ModuleRtpRtcpImpl::PeriodicDeadOrAliveStatus(
317    bool& enable,
318    WebRtc_UWord8& sampleTimeSeconds) {
319  WEBRTC_TRACE(kTraceModuleCall,
320               kTraceRtpRtcp,
321               _id,
322               "PeriodicDeadOrAliveStatus()");
323
324  enable = _deadOrAliveActive;
325  sampleTimeSeconds = (WebRtc_UWord8)(_deadOrAliveTimeoutMS / 1000);
326  return 0;
327}
328
329WebRtc_Word32 ModuleRtpRtcpImpl::SetPacketTimeout(
330    const WebRtc_UWord32 RTPtimeoutMS,
331    const WebRtc_UWord32 RTCPtimeoutMS) {
332  WEBRTC_TRACE(kTraceModuleCall,
333               kTraceRtpRtcp,
334               _id,
335               "SetPacketTimeout(%u,%u)",
336               RTPtimeoutMS,
337               RTCPtimeoutMS);
338
339  if (_rtpReceiver.SetPacketTimeout(RTPtimeoutMS) == 0) {
340    return _rtcpReceiver.SetPacketTimeout(RTCPtimeoutMS);
341  }
342  return -1;
343}
344
345WebRtc_Word32 ModuleRtpRtcpImpl::RegisterReceivePayload(
346  const CodecInst& voiceCodec) {
347  WEBRTC_TRACE(kTraceModuleCall,
348               kTraceRtpRtcp,
349               _id,
350               "RegisterReceivePayload(voiceCodec)");
351
352  return _rtpReceiver.RegisterReceivePayload(
353           voiceCodec.plname,
354           voiceCodec.pltype,
355           voiceCodec.plfreq,
356           voiceCodec.channels,
357           (voiceCodec.rate < 0) ? 0 : voiceCodec.rate);
358}
359
360WebRtc_Word32 ModuleRtpRtcpImpl::RegisterReceivePayload(
361  const VideoCodec& videoCodec) {
362  WEBRTC_TRACE(kTraceModuleCall,
363               kTraceRtpRtcp,
364               _id,
365               "RegisterReceivePayload(videoCodec)");
366
367  return _rtpReceiver.RegisterReceivePayload(videoCodec.plName,
368                                             videoCodec.plType,
369                                             90000,
370                                             0,
371                                             videoCodec.maxBitrate);
372}
373
374WebRtc_Word32 ModuleRtpRtcpImpl::ReceivePayloadType(
375  const CodecInst& voiceCodec,
376  WebRtc_Word8* plType) {
377  WEBRTC_TRACE(kTraceModuleCall,
378               kTraceRtpRtcp,
379               _id,
380               "ReceivePayloadType(voiceCodec)");
381
382  return _rtpReceiver.ReceivePayloadType(
383           voiceCodec.plname,
384           voiceCodec.plfreq,
385           voiceCodec.channels,
386           (voiceCodec.rate < 0) ? 0 : voiceCodec.rate,
387           plType);
388}
389
390WebRtc_Word32 ModuleRtpRtcpImpl::ReceivePayloadType(
391  const VideoCodec& videoCodec,
392  WebRtc_Word8* plType) {
393  WEBRTC_TRACE(kTraceModuleCall,
394               kTraceRtpRtcp,
395               _id,
396               "ReceivePayloadType(videoCodec)");
397
398  return _rtpReceiver.ReceivePayloadType(videoCodec.plName,
399                                         90000,
400                                         0,
401                                         videoCodec.maxBitrate,
402                                         plType);
403}
404
405WebRtc_Word32 ModuleRtpRtcpImpl::DeRegisterReceivePayload(
406    const WebRtc_Word8 payloadType) {
407  WEBRTC_TRACE(kTraceModuleCall,
408               kTraceRtpRtcp,
409               _id,
410               "DeRegisterReceivePayload(%d)",
411               payloadType);
412
413  return _rtpReceiver.DeRegisterReceivePayload(payloadType);
414}
415
416// get the currently configured SSRC filter
417WebRtc_Word32 ModuleRtpRtcpImpl::SSRCFilter(WebRtc_UWord32& allowedSSRC) const {
418  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SSRCFilter()");
419
420  return _rtpReceiver.SSRCFilter(allowedSSRC);
421}
422
423// set a SSRC to be used as a filter for incoming RTP streams
424WebRtc_Word32 ModuleRtpRtcpImpl::SetSSRCFilter(
425  const bool enable,
426  const WebRtc_UWord32 allowedSSRC) {
427  if (enable) {
428    WEBRTC_TRACE(kTraceModuleCall,
429                 kTraceRtpRtcp,
430                 _id,
431                 "SetSSRCFilter(enable, 0x%x)",
432                 allowedSSRC);
433  } else {
434    WEBRTC_TRACE(kTraceModuleCall,
435                 kTraceRtpRtcp,
436                 _id,
437                 "SetSSRCFilter(disable)");
438  }
439
440  return _rtpReceiver.SetSSRCFilter(enable, allowedSSRC);
441}
442
443// Get last received remote timestamp
444WebRtc_UWord32 ModuleRtpRtcpImpl::RemoteTimestamp() const {
445  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteTimestamp()");
446
447  return _rtpReceiver.TimeStamp();
448}
449
450int64_t ModuleRtpRtcpImpl::LocalTimeOfRemoteTimeStamp() const {
451  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
452               "LocalTimeOfRemoteTimeStamp()");
453
454  return _rtpReceiver.LastReceivedTimeMs();
455}
456
457// Get the current estimated remote timestamp
458WebRtc_Word32 ModuleRtpRtcpImpl::EstimatedRemoteTimeStamp(
459    WebRtc_UWord32& timestamp) const {
460  WEBRTC_TRACE(kTraceModuleCall,
461               kTraceRtpRtcp,
462               _id,
463               "EstimatedRemoteTimeStamp()");
464
465  return _rtpReceiver.EstimatedRemoteTimeStamp(timestamp);
466}
467
468// Get incoming SSRC
469WebRtc_UWord32 ModuleRtpRtcpImpl::RemoteSSRC() const {
470  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteSSRC()");
471
472  return _rtpReceiver.SSRC();
473}
474
475// Get remote CSRC
476WebRtc_Word32 ModuleRtpRtcpImpl::RemoteCSRCs(
477    WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const {
478  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteCSRCs()");
479
480  return _rtpReceiver.CSRCs(arrOfCSRC);
481}
482
483WebRtc_Word32 ModuleRtpRtcpImpl::SetRTXSendStatus(
484  const bool enable,
485  const bool setSSRC,
486  const WebRtc_UWord32 SSRC) {
487  _rtpSender.SetRTXStatus(enable, setSSRC, SSRC);
488  return 0;
489}
490
491WebRtc_Word32 ModuleRtpRtcpImpl::RTXSendStatus(bool* enable,
492                                               WebRtc_UWord32* SSRC) const {
493  _rtpSender.RTXStatus(enable, SSRC);
494  return 0;
495}
496
497WebRtc_Word32 ModuleRtpRtcpImpl::SetRTXReceiveStatus(
498  const bool enable,
499  const WebRtc_UWord32 SSRC) {
500  _rtpReceiver.SetRTXStatus(enable, SSRC);
501  return 0;
502}
503
504WebRtc_Word32 ModuleRtpRtcpImpl::RTXReceiveStatus(bool* enable,
505                                                  WebRtc_UWord32* SSRC) const {
506  _rtpReceiver.RTXStatus(enable, SSRC);
507  return 0;
508}
509
510// called by the network module when we receive a packet
511WebRtc_Word32 ModuleRtpRtcpImpl::IncomingPacket(
512    const WebRtc_UWord8* incomingPacket,
513    const WebRtc_UWord16 incomingPacketLength) {
514  WEBRTC_TRACE(kTraceStream,
515               kTraceRtpRtcp,
516               _id,
517               "IncomingPacket(packetLength:%u)",
518               incomingPacketLength);
519  // minimum RTP is 12 bytes
520  // minimum RTCP is 8 bytes (RTCP BYE)
521  if (incomingPacketLength < 8 || incomingPacket == NULL) {
522    WEBRTC_TRACE(kTraceDebug,
523                 kTraceRtpRtcp,
524                 _id,
525                 "IncomingPacket invalid buffer or length");
526    return -1;
527  }
528  // check RTP version
529  const WebRtc_UWord8  version  = incomingPacket[0] >> 6 ;
530  if (version != 2) {
531    WEBRTC_TRACE(kTraceDebug,
532                 kTraceRtpRtcp,
533                 _id,
534                 "IncomingPacket invalid RTP version");
535    return -1;
536  }
537
538  ModuleRTPUtility::RTPHeaderParser rtpParser(incomingPacket,
539                                              incomingPacketLength);
540
541  if (rtpParser.RTCP()) {
542    // Allow receive of non-compound RTCP packets.
543    RTCPUtility::RTCPParserV2 rtcpParser(incomingPacket,
544                                         incomingPacketLength,
545                                         true);
546
547    const bool validRTCPHeader = rtcpParser.IsValid();
548    if (!validRTCPHeader) {
549      WEBRTC_TRACE(kTraceDebug,
550                   kTraceRtpRtcp,
551                   _id,
552                   "IncomingPacket invalid RTCP packet");
553      return -1;
554    }
555    RTCPHelp::RTCPPacketInformation rtcpPacketInformation;
556    WebRtc_Word32 retVal = _rtcpReceiver.IncomingRTCPPacket(
557                             rtcpPacketInformation,
558                             &rtcpParser);
559    if (retVal == 0) {
560      _rtcpReceiver.TriggerCallbacksFromRTCPPacket(rtcpPacketInformation);
561    }
562    return retVal;
563
564  } else {
565    WebRtcRTPHeader rtpHeader;
566    memset(&rtpHeader, 0, sizeof(rtpHeader));
567
568    RtpHeaderExtensionMap map;
569    _rtpReceiver.GetHeaderExtensionMapCopy(&map);
570
571    const bool validRTPHeader = rtpParser.Parse(rtpHeader, &map);
572    if (!validRTPHeader) {
573      WEBRTC_TRACE(kTraceDebug,
574                   kTraceRtpRtcp,
575                   _id,
576                   "IncomingPacket invalid RTP header");
577      return -1;
578    }
579    return _rtpReceiver.IncomingRTPPacket(&rtpHeader,
580                                          incomingPacket,
581                                          incomingPacketLength);
582  }
583}
584
585/**
586*   Sender
587*/
588
589WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSendPayload(
590  const CodecInst& voiceCodec) {
591  WEBRTC_TRACE(kTraceModuleCall,
592               kTraceRtpRtcp,
593               _id,
594               "RegisterSendPayload(plName:%s plType:%d frequency:%u)",
595               voiceCodec.plname,
596               voiceCodec.pltype,
597               voiceCodec.plfreq);
598
599  return _rtpSender.RegisterPayload(
600           voiceCodec.plname,
601           voiceCodec.pltype,
602           voiceCodec.plfreq,
603           voiceCodec.channels,
604           (voiceCodec.rate < 0) ? 0 : voiceCodec.rate);
605}
606
607WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSendPayload(
608  const VideoCodec& videoCodec) {
609  WEBRTC_TRACE(kTraceModuleCall,
610               kTraceRtpRtcp,
611               _id,
612               "RegisterSendPayload(plName:%s plType:%d)",
613               videoCodec.plName,
614               videoCodec.plType);
615
616  _sendVideoCodec = videoCodec;
617  _simulcast = (videoCodec.numberOfSimulcastStreams > 1) ? true : false;
618  return _rtpSender.RegisterPayload(videoCodec.plName,
619                                    videoCodec.plType,
620                                    90000,
621                                    0,
622                                    videoCodec.maxBitrate);
623}
624
625WebRtc_Word32 ModuleRtpRtcpImpl::DeRegisterSendPayload(
626    const WebRtc_Word8 payloadType) {
627  WEBRTC_TRACE(kTraceModuleCall,
628               kTraceRtpRtcp,
629               _id,
630               "DeRegisterSendPayload(%d)", payloadType);
631
632  return _rtpSender.DeRegisterSendPayload(payloadType);
633}
634
635WebRtc_Word8 ModuleRtpRtcpImpl::SendPayloadType() const {
636  return _rtpSender.SendPayloadType();
637}
638
639WebRtc_UWord32 ModuleRtpRtcpImpl::StartTimestamp() const {
640  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "StartTimestamp()");
641
642  return _rtpSender.StartTimestamp();
643}
644
645// configure start timestamp, default is a random number
646WebRtc_Word32 ModuleRtpRtcpImpl::SetStartTimestamp(
647    const WebRtc_UWord32 timestamp) {
648  WEBRTC_TRACE(kTraceModuleCall,
649               kTraceRtpRtcp,
650               _id,
651               "SetStartTimestamp(%d)",
652               timestamp);
653  _rtcpSender.SetStartTimestamp(timestamp);
654  _rtpSender.SetStartTimestamp(timestamp, true);
655  return 0;  // TODO(pwestin): change to void.
656}
657
658WebRtc_UWord16 ModuleRtpRtcpImpl::SequenceNumber() const {
659  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SequenceNumber()");
660
661  return _rtpSender.SequenceNumber();
662}
663
664// Set SequenceNumber, default is a random number
665WebRtc_Word32 ModuleRtpRtcpImpl::SetSequenceNumber(
666    const WebRtc_UWord16 seqNum) {
667  WEBRTC_TRACE(kTraceModuleCall,
668               kTraceRtpRtcp,
669               _id,
670               "SetSequenceNumber(%d)",
671               seqNum);
672
673  _rtpSender.SetSequenceNumber(seqNum);
674  return 0;  // TODO(pwestin): change to void.
675}
676
677WebRtc_UWord32 ModuleRtpRtcpImpl::SSRC() const {
678  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SSRC()");
679
680  return _rtpSender.SSRC();
681}
682
683// configure SSRC, default is a random number
684WebRtc_Word32 ModuleRtpRtcpImpl::SetSSRC(const WebRtc_UWord32 ssrc) {
685  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetSSRC(%d)", ssrc);
686
687  _rtpSender.SetSSRC(ssrc);
688  _rtcpReceiver.SetSSRC(ssrc);
689  _rtcpSender.SetSSRC(ssrc);
690  return 0;  // TODO(pwestin): change to void.
691}
692
693WebRtc_Word32 ModuleRtpRtcpImpl::SetCSRCStatus(const bool include) {
694  _rtcpSender.SetCSRCStatus(include);
695  _rtpSender.SetCSRCStatus(include);
696  return 0;  // TODO(pwestin): change to void.
697}
698
699WebRtc_Word32 ModuleRtpRtcpImpl::CSRCs(
700    WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const {
701  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "CSRCs()");
702
703  return _rtpSender.CSRCs(arrOfCSRC);
704}
705
706WebRtc_Word32 ModuleRtpRtcpImpl::SetCSRCs(
707    const WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize],
708    const WebRtc_UWord8 arrLength) {
709  WEBRTC_TRACE(kTraceModuleCall,
710               kTraceRtpRtcp,
711               _id,
712               "SetCSRCs(arrLength:%d)",
713               arrLength);
714
715  const bool defaultInstance(_childModules.empty() ? false : true);
716
717  if (defaultInstance) {
718    // for default we need to update all child modules too
719    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
720
721    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
722    while (it != _childModules.end()) {
723      RtpRtcp* module = *it;
724      if (module) {
725        module->SetCSRCs(arrOfCSRC, arrLength);
726      }
727      it++;
728    }
729  } else {
730    for (int i = 0; i < arrLength; i++) {
731      WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "\tidx:%d CSRC:%u", i,
732                   arrOfCSRC[i]);
733    }
734    _rtcpSender.SetCSRCs(arrOfCSRC, arrLength);
735    _rtpSender.SetCSRCs(arrOfCSRC, arrLength);
736  }
737  return 0;  // TODO(pwestin): change to void.
738}
739
740WebRtc_UWord32 ModuleRtpRtcpImpl::PacketCountSent() const {
741  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "PacketCountSent()");
742
743  return _rtpSender.Packets();
744}
745
746WebRtc_UWord32 ModuleRtpRtcpImpl::ByteCountSent() const {
747  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ByteCountSent()");
748
749  return _rtpSender.Bytes();
750}
751
752int ModuleRtpRtcpImpl::CurrentSendFrequencyHz() const {
753  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
754               "CurrentSendFrequencyHz()");
755
756  return _rtpSender.SendPayloadFrequency();
757}
758
759WebRtc_Word32 ModuleRtpRtcpImpl::SetSendingStatus(const bool sending) {
760  if (sending) {
761    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
762                 "SetSendingStatus(sending)");
763  } else {
764    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
765                 "SetSendingStatus(stopped)");
766  }
767  if (_rtcpSender.Sending() != sending) {
768    // sends RTCP BYE when going from true to false
769    if (_rtcpSender.SetSendingStatus(sending) != 0) {
770      WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
771                   "Failed to send RTCP BYE");
772    }
773
774    _collisionDetected = false;
775
776    // generate a new timeStamp if true and not configured via API
777    // generate a new SSRC for the next "call" if false
778    _rtpSender.SetSendingStatus(sending);
779    if (sending) {
780      // Make sure the RTCP sender has the same timestamp offset.
781      _rtcpSender.SetStartTimestamp(_rtpSender.StartTimestamp());
782    }
783
784    // make sure that RTCP objects are aware of our SSRC (it could have changed
785    // due to collision)
786    WebRtc_UWord32 SSRC = _rtpSender.SSRC();
787    _rtcpReceiver.SetSSRC(SSRC);
788    _rtcpSender.SetSSRC(SSRC);
789    return 0;
790  }
791  return 0;
792}
793
794bool ModuleRtpRtcpImpl::Sending() const {
795  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "Sending()");
796
797  return _rtcpSender.Sending();
798}
799
800WebRtc_Word32 ModuleRtpRtcpImpl::SetSendingMediaStatus(const bool sending) {
801  if (sending) {
802    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
803                 "SetSendingMediaStatus(sending)");
804  } else {
805    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
806                 "SetSendingMediaStatus(stopped)");
807  }
808  _rtpSender.SetSendingMediaStatus(sending);
809  return 0;
810}
811
812bool ModuleRtpRtcpImpl::SendingMedia() const {
813  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "Sending()");
814
815  const bool haveChildModules(_childModules.empty() ? false : true);
816  if (!haveChildModules) {
817    return _rtpSender.SendingMedia();
818  }
819
820  CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
821  std::list<ModuleRtpRtcpImpl*>::const_iterator it = _childModules.begin();
822  while (it != _childModules.end()) {
823    RTPSender& rtpSender = (*it)->_rtpSender;
824    if (rtpSender.SendingMedia()) {
825      return true;
826    }
827    it++;
828  }
829  return false;
830}
831
832WebRtc_Word32 ModuleRtpRtcpImpl::SendOutgoingData(
833    FrameType frameType,
834    WebRtc_Word8 payloadType,
835    WebRtc_UWord32 timeStamp,
836    int64_t capture_time_ms,
837    const WebRtc_UWord8* payloadData,
838    WebRtc_UWord32 payloadSize,
839    const RTPFragmentationHeader* fragmentation,
840    const RTPVideoHeader* rtpVideoHdr) {
841  WEBRTC_TRACE(
842      kTraceStream,
843      kTraceRtpRtcp,
844      _id,
845      "SendOutgoingData(frameType:%d payloadType:%d timeStamp:%u size:%u)",
846      frameType, payloadType, timeStamp, payloadSize);
847
848  _rtcpSender.SetLastRtpTime(timeStamp, capture_time_ms);
849
850  const bool haveChildModules(_childModules.empty() ? false : true);
851  if (!haveChildModules) {
852    // Don't sent RTCP from default module
853    if (_rtcpSender.TimeToSendRTCPReport(kVideoFrameKey == frameType)) {
854      _rtcpSender.SendRTCP(kRtcpReport);
855    }
856    return _rtpSender.SendOutgoingData(frameType,
857                                       payloadType,
858                                       timeStamp,
859                                       capture_time_ms,
860                                       payloadData,
861                                       payloadSize,
862                                       fragmentation,
863                                       NULL,
864                                       &(rtpVideoHdr->codecHeader));
865  }
866  WebRtc_Word32 retVal = -1;
867  if (_simulcast) {
868    if (rtpVideoHdr == NULL) {
869      return -1;
870    }
871    int idx = 0;
872    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
873    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
874    for (; idx < rtpVideoHdr->simulcastIdx; ++it) {
875      if (it == _childModules.end()) {
876        return -1;
877      }
878      if ((*it)->SendingMedia()) {
879        ++idx;
880      }
881    }
882    for (; it != _childModules.end(); ++it) {
883      if ((*it)->SendingMedia()) {
884        break;
885      }
886      ++idx;
887    }
888    if (it == _childModules.end()) {
889      return -1;
890    }
891    WEBRTC_TRACE(kTraceModuleCall,
892                 kTraceRtpRtcp,
893                 _id,
894                 "SendOutgoingData(SimulcastIdx:%u size:%u, ssrc:0x%x)",
895                 idx, payloadSize, (*it)->_rtpSender.SSRC());
896    return (*it)->SendOutgoingData(frameType,
897                                   payloadType,
898                                   timeStamp,
899                                   capture_time_ms,
900                                   payloadData,
901                                   payloadSize,
902                                   fragmentation,
903                                   rtpVideoHdr);
904  } else {
905    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
906
907    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
908    if (it != _childModules.end()) {
909      retVal =  (*it)->SendOutgoingData(frameType,
910                                        payloadType,
911                                        timeStamp,
912                                        capture_time_ms,
913                                        payloadData,
914                                        payloadSize,
915                                        fragmentation,
916                                        rtpVideoHdr);
917
918      it++;
919    }
920
921    // send to all remaining "child" modules
922    while (it != _childModules.end()) {
923      retVal = (*it)->SendOutgoingData(frameType,
924                                       payloadType,
925                                       timeStamp,
926                                       capture_time_ms,
927                                       payloadData,
928                                       payloadSize,
929                                       fragmentation,
930                                       rtpVideoHdr);
931
932      it++;
933    }
934  }
935  return retVal;
936}
937
938void ModuleRtpRtcpImpl::TimeToSendPacket(uint32_t ssrc,
939                                         uint16_t sequence_number,
940                                         int64_t capture_time_ms) {
941  WEBRTC_TRACE(
942      kTraceStream,
943      kTraceRtpRtcp,
944      _id,
945      "TimeToSendPacket(ssrc:0x%x sequence_number:%u capture_time_ms:%ll)",
946      ssrc, sequence_number, capture_time_ms);
947
948  if (_simulcast) {
949    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
950    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
951    while (it != _childModules.end()) {
952      if ((*it)->SendingMedia() && ssrc == (*it)->_rtpSender.SSRC()) {
953        (*it)->_rtpSender.TimeToSendPacket(sequence_number, capture_time_ms);
954        return;
955      }
956      it++;
957    }
958  } else {
959    bool have_child_modules(_childModules.empty() ? false : true);
960    if (!have_child_modules) {
961      // Don't send from default module.
962      if (SendingMedia() && ssrc == _rtpSender.SSRC()) {
963        _rtpSender.TimeToSendPacket(sequence_number, capture_time_ms);
964      }
965    }
966  }
967}
968
969WebRtc_UWord16 ModuleRtpRtcpImpl::MaxPayloadLength() const {
970  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "MaxPayloadLength()");
971
972  return _rtpSender.MaxPayloadLength();
973}
974
975WebRtc_UWord16 ModuleRtpRtcpImpl::MaxDataPayloadLength() const {
976  WEBRTC_TRACE(kTraceModuleCall,
977               kTraceRtpRtcp,
978               _id,
979               "MaxDataPayloadLength()");
980
981  WebRtc_UWord16 minDataPayloadLength = IP_PACKET_SIZE - 28; // Assuming IP/UDP
982
983  const bool defaultInstance(_childModules.empty() ? false : true);
984  if (defaultInstance) {
985    // for default we need to update all child modules too
986    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
987    std::list<ModuleRtpRtcpImpl*>::const_iterator it =
988      _childModules.begin();
989    while (it != _childModules.end()) {
990      RtpRtcp* module = *it;
991      if (module) {
992        WebRtc_UWord16 dataPayloadLength =
993          module->MaxDataPayloadLength();
994        if (dataPayloadLength < minDataPayloadLength) {
995          minDataPayloadLength = dataPayloadLength;
996        }
997      }
998      it++;
999    }
1000  }
1001
1002  WebRtc_UWord16 dataPayloadLength = _rtpSender.MaxDataPayloadLength();
1003  if (dataPayloadLength < minDataPayloadLength) {
1004    minDataPayloadLength = dataPayloadLength;
1005  }
1006  return minDataPayloadLength;
1007}
1008
1009WebRtc_Word32 ModuleRtpRtcpImpl::SetTransportOverhead(
1010  const bool TCP,
1011  const bool IPV6,
1012  const WebRtc_UWord8 authenticationOverhead) {
1013  WEBRTC_TRACE(
1014    kTraceModuleCall,
1015    kTraceRtpRtcp,
1016    _id,
1017    "SetTransportOverhead(TCP:%d, IPV6:%d authenticationOverhead:%u)",
1018    TCP, IPV6, authenticationOverhead);
1019
1020  WebRtc_UWord16 packetOverHead = 0;
1021  if (IPV6) {
1022    packetOverHead = 40;
1023  } else {
1024    packetOverHead = 20;
1025  }
1026  if (TCP) {
1027    // TCP
1028    packetOverHead += 20;
1029  } else {
1030    // UDP
1031    packetOverHead += 8;
1032  }
1033  packetOverHead += authenticationOverhead;
1034
1035  if (packetOverHead == _packetOverHead) {
1036    // ok same as before
1037    return 0;
1038  }
1039  // calc diff
1040  WebRtc_Word16 packetOverHeadDiff = packetOverHead - _packetOverHead;
1041
1042  // store new
1043  _packetOverHead = packetOverHead;
1044
1045  WebRtc_UWord16 length = _rtpSender.MaxPayloadLength() - packetOverHeadDiff;
1046  return _rtpSender.SetMaxPayloadLength(length, _packetOverHead);
1047}
1048
1049WebRtc_Word32 ModuleRtpRtcpImpl::SetMaxTransferUnit(const WebRtc_UWord16 MTU) {
1050  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetMaxTransferUnit(%u)",
1051               MTU);
1052
1053  if (MTU > IP_PACKET_SIZE) {
1054    WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1055                 "Invalid in argument to SetMaxTransferUnit(%u)", MTU);
1056    return -1;
1057  }
1058  return _rtpSender.SetMaxPayloadLength(MTU - _packetOverHead,
1059                                        _packetOverHead);
1060}
1061
1062/*
1063*   RTCP
1064*/
1065RTCPMethod ModuleRtpRtcpImpl::RTCP() const {
1066  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RTCP()");
1067
1068  if (_rtcpSender.Status() != kRtcpOff) {
1069    return _rtcpReceiver.Status();
1070  }
1071  return kRtcpOff;
1072}
1073
1074// configure RTCP status i.e on/off
1075WebRtc_Word32 ModuleRtpRtcpImpl::SetRTCPStatus(const RTCPMethod method) {
1076  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetRTCPStatus(%d)",
1077               method);
1078
1079  if (_rtcpSender.SetRTCPStatus(method) == 0) {
1080    return _rtcpReceiver.SetRTCPStatus(method);
1081  }
1082  return -1;
1083}
1084
1085// only for internal test
1086WebRtc_UWord32 ModuleRtpRtcpImpl::LastSendReport(WebRtc_UWord32& lastRTCPTime) {
1087  return _rtcpSender.LastSendReport(lastRTCPTime);
1088}
1089
1090WebRtc_Word32 ModuleRtpRtcpImpl::SetCNAME(const char cName[RTCP_CNAME_SIZE]) {
1091  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetCNAME(%s)", cName);
1092  return _rtcpSender.SetCNAME(cName);
1093}
1094
1095WebRtc_Word32 ModuleRtpRtcpImpl::CNAME(char cName[RTCP_CNAME_SIZE]) {
1096  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "CNAME()");
1097  return _rtcpSender.CNAME(cName);
1098}
1099
1100WebRtc_Word32 ModuleRtpRtcpImpl::AddMixedCNAME(
1101  const WebRtc_UWord32 SSRC,
1102  const char cName[RTCP_CNAME_SIZE]) {
1103  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1104               "AddMixedCNAME(SSRC:%u)", SSRC);
1105
1106  return _rtcpSender.AddMixedCNAME(SSRC, cName);
1107}
1108
1109WebRtc_Word32 ModuleRtpRtcpImpl::RemoveMixedCNAME(const WebRtc_UWord32 SSRC) {
1110  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1111               "RemoveMixedCNAME(SSRC:%u)", SSRC);
1112  return _rtcpSender.RemoveMixedCNAME(SSRC);
1113}
1114
1115WebRtc_Word32 ModuleRtpRtcpImpl::RemoteCNAME(
1116  const WebRtc_UWord32 remoteSSRC,
1117  char cName[RTCP_CNAME_SIZE]) const {
1118  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1119               "RemoteCNAME(SSRC:%u)", remoteSSRC);
1120
1121  return _rtcpReceiver.CNAME(remoteSSRC, cName);
1122}
1123
1124WebRtc_UWord16 ModuleRtpRtcpImpl::RemoteSequenceNumber() const {
1125  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteSequenceNumber()");
1126
1127  return _rtpReceiver.SequenceNumber();
1128}
1129
1130WebRtc_Word32 ModuleRtpRtcpImpl::RemoteNTP(
1131    WebRtc_UWord32* receivedNTPsecs,
1132    WebRtc_UWord32* receivedNTPfrac,
1133    WebRtc_UWord32* RTCPArrivalTimeSecs,
1134    WebRtc_UWord32* RTCPArrivalTimeFrac,
1135    WebRtc_UWord32* rtcp_timestamp) const {
1136  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteNTP()");
1137
1138  return _rtcpReceiver.NTP(receivedNTPsecs,
1139                           receivedNTPfrac,
1140                           RTCPArrivalTimeSecs,
1141                           RTCPArrivalTimeFrac,
1142                           rtcp_timestamp);
1143}
1144
1145// Get RoundTripTime
1146WebRtc_Word32 ModuleRtpRtcpImpl::RTT(const WebRtc_UWord32 remoteSSRC,
1147                                     WebRtc_UWord16* RTT,
1148                                     WebRtc_UWord16* avgRTT,
1149                                     WebRtc_UWord16* minRTT,
1150                                     WebRtc_UWord16* maxRTT) const {
1151  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RTT()");
1152
1153  return _rtcpReceiver.RTT(remoteSSRC, RTT, avgRTT, minRTT, maxRTT);
1154}
1155
1156// Reset RoundTripTime statistics
1157WebRtc_Word32
1158ModuleRtpRtcpImpl::ResetRTT(const WebRtc_UWord32 remoteSSRC) {
1159  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ResetRTT(SSRC:%u)",
1160               remoteSSRC);
1161
1162  return _rtcpReceiver.ResetRTT(remoteSSRC);
1163}
1164
1165void ModuleRtpRtcpImpl:: SetRtt(uint32_t rtt) {
1166  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetRtt(rtt: %u)", rtt);
1167  _rtcpReceiver.SetRTT(static_cast<WebRtc_UWord16>(rtt));
1168}
1169
1170// Reset RTP statistics
1171WebRtc_Word32
1172ModuleRtpRtcpImpl::ResetStatisticsRTP() {
1173  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ResetStatisticsRTP()");
1174
1175  return _rtpReceiver.ResetStatistics();
1176}
1177
1178// Reset RTP data counters for the receiving side
1179WebRtc_Word32 ModuleRtpRtcpImpl::ResetReceiveDataCountersRTP() {
1180  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1181               "ResetReceiveDataCountersRTP()");
1182
1183  return _rtpReceiver.ResetDataCounters();
1184}
1185
1186// Reset RTP data counters for the sending side
1187WebRtc_Word32 ModuleRtpRtcpImpl::ResetSendDataCountersRTP() {
1188  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1189               "ResetSendDataCountersRTP()");
1190
1191  _rtpSender.ResetDataCounters();
1192  return 0;  // TODO(pwestin): change to void.
1193}
1194
1195// Force a send of an RTCP packet
1196// normal SR and RR are triggered via the process function
1197WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCP(WebRtc_UWord32 rtcpPacketType) {
1198  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SendRTCP(0x%x)",
1199               rtcpPacketType);
1200
1201  return  _rtcpSender.SendRTCP(rtcpPacketType);
1202}
1203
1204WebRtc_Word32 ModuleRtpRtcpImpl::SetRTCPApplicationSpecificData(
1205    const WebRtc_UWord8 subType,
1206    const WebRtc_UWord32 name,
1207    const WebRtc_UWord8* data,
1208    const WebRtc_UWord16 length) {
1209  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1210               "SetRTCPApplicationSpecificData(subType:%d name:0x%x)", subType,
1211               name);
1212
1213  return  _rtcpSender.SetApplicationSpecificData(subType, name, data, length);
1214}
1215
1216/*
1217*   (XR) VOIP metric
1218*/
1219WebRtc_Word32 ModuleRtpRtcpImpl::SetRTCPVoIPMetrics(
1220    const RTCPVoIPMetric* VoIPMetric) {
1221  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetRTCPVoIPMetrics()");
1222
1223  return  _rtcpSender.SetRTCPVoIPMetrics(VoIPMetric);
1224}
1225
1226// our localy created statistics of the received RTP stream
1227WebRtc_Word32 ModuleRtpRtcpImpl::StatisticsRTP(
1228    WebRtc_UWord8*  fraction_lost,
1229    WebRtc_UWord32* cum_lost,
1230    WebRtc_UWord32* ext_max,
1231    WebRtc_UWord32* jitter,
1232    WebRtc_UWord32* max_jitter) const {
1233  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "StatisticsRTP()");
1234
1235  WebRtc_UWord32 jitter_transmission_time_offset = 0;
1236
1237  WebRtc_Word32 retVal = _rtpReceiver.Statistics(
1238      fraction_lost,
1239      cum_lost,
1240      ext_max,
1241      jitter,
1242      max_jitter,
1243      &jitter_transmission_time_offset,
1244      (_rtcpSender.Status() == kRtcpOff));
1245  if (retVal == -1) {
1246    WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1247                 "StatisticsRTP() no statisitics availble");
1248  }
1249  return retVal;
1250}
1251
1252WebRtc_Word32 ModuleRtpRtcpImpl::DataCountersRTP(
1253    WebRtc_UWord32* bytesSent,
1254    WebRtc_UWord32* packetsSent,
1255    WebRtc_UWord32* bytesReceived,
1256    WebRtc_UWord32* packetsReceived) const {
1257  WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, "DataCountersRTP()");
1258
1259  if (bytesSent) {
1260    *bytesSent = _rtpSender.Bytes();
1261  }
1262  if (packetsSent) {
1263    *packetsSent = _rtpSender.Packets();
1264  }
1265  return _rtpReceiver.DataCounters(bytesReceived, packetsReceived);
1266}
1267
1268WebRtc_Word32 ModuleRtpRtcpImpl::ReportBlockStatistics(
1269    WebRtc_UWord8* fraction_lost,
1270    WebRtc_UWord32* cum_lost,
1271    WebRtc_UWord32* ext_max,
1272    WebRtc_UWord32* jitter,
1273    WebRtc_UWord32* jitter_transmission_time_offset) {
1274  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ReportBlockStatistics()");
1275  WebRtc_Word32 missing = 0;
1276  WebRtc_Word32 ret = _rtpReceiver.Statistics(fraction_lost,
1277                                              cum_lost,
1278                                              ext_max,
1279                                              jitter,
1280                                              NULL,
1281                                              jitter_transmission_time_offset,
1282                                              &missing,
1283                                              true);
1284
1285#ifdef MATLAB
1286  if (_plot1 == NULL) {
1287    _plot1 = eng.NewPlot(new MatlabPlot());
1288    _plot1->AddTimeLine(30, "b", "lost", _clock.GetTimeInMS());
1289  }
1290  _plot1->Append("lost", missing);
1291  _plot1->Plot();
1292#endif
1293
1294  return ret;
1295}
1296
1297WebRtc_Word32 ModuleRtpRtcpImpl::RemoteRTCPStat(RTCPSenderInfo* senderInfo) {
1298  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteRTCPStat()");
1299
1300  return _rtcpReceiver.SenderInfoReceived(senderInfo);
1301}
1302
1303// received RTCP report
1304WebRtc_Word32 ModuleRtpRtcpImpl::RemoteRTCPStat(
1305  std::vector<RTCPReportBlock>* receiveBlocks) const {
1306  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteRTCPStat()");
1307
1308  return _rtcpReceiver.StatisticsReceived(receiveBlocks);
1309}
1310
1311WebRtc_Word32 ModuleRtpRtcpImpl::AddRTCPReportBlock(
1312    const WebRtc_UWord32 SSRC,
1313    const RTCPReportBlock* reportBlock) {
1314  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "AddRTCPReportBlock()");
1315
1316  return _rtcpSender.AddReportBlock(SSRC, reportBlock);
1317}
1318
1319WebRtc_Word32 ModuleRtpRtcpImpl::RemoveRTCPReportBlock(
1320    const WebRtc_UWord32 SSRC) {
1321  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoveRTCPReportBlock()");
1322
1323  return _rtcpSender.RemoveReportBlock(SSRC);
1324}
1325
1326/*
1327 *  (REMB) Receiver Estimated Max Bitrate
1328 */
1329bool ModuleRtpRtcpImpl::REMB() const {
1330  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "REMB()");
1331
1332  return _rtcpSender.REMB();
1333}
1334
1335WebRtc_Word32 ModuleRtpRtcpImpl::SetREMBStatus(const bool enable) {
1336  if (enable) {
1337    WEBRTC_TRACE(kTraceModuleCall,
1338                 kTraceRtpRtcp,
1339                 _id,
1340                 "SetREMBStatus(enable)");
1341  } else {
1342    WEBRTC_TRACE(kTraceModuleCall,
1343                 kTraceRtpRtcp,
1344                 _id,
1345                 "SetREMBStatus(disable)");
1346  }
1347  return _rtcpSender.SetREMBStatus(enable);
1348}
1349
1350WebRtc_Word32 ModuleRtpRtcpImpl::SetREMBData(const WebRtc_UWord32 bitrate,
1351                                             const WebRtc_UWord8 numberOfSSRC,
1352                                             const WebRtc_UWord32* SSRC) {
1353  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1354               "SetREMBData(bitrate:%d,?,?)", bitrate);
1355  return _rtcpSender.SetREMBData(bitrate, numberOfSSRC, SSRC);
1356}
1357
1358/*
1359 *   (IJ) Extended jitter report.
1360 */
1361bool ModuleRtpRtcpImpl::IJ() const {
1362  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "IJ()");
1363
1364  return _rtcpSender.IJ();
1365}
1366
1367WebRtc_Word32 ModuleRtpRtcpImpl::SetIJStatus(const bool enable) {
1368  WEBRTC_TRACE(kTraceModuleCall,
1369               kTraceRtpRtcp,
1370               _id,
1371               "SetIJStatus(%s)", enable ? "true" : "false");
1372
1373  return _rtcpSender.SetIJStatus(enable);
1374}
1375
1376WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSendRtpHeaderExtension(
1377  const RTPExtensionType type,
1378  const WebRtc_UWord8 id) {
1379  return _rtpSender.RegisterRtpHeaderExtension(type, id);
1380}
1381
1382WebRtc_Word32 ModuleRtpRtcpImpl::DeregisterSendRtpHeaderExtension(
1383  const RTPExtensionType type) {
1384  return _rtpSender.DeregisterRtpHeaderExtension(type);
1385}
1386
1387WebRtc_Word32 ModuleRtpRtcpImpl::RegisterReceiveRtpHeaderExtension(
1388  const RTPExtensionType type,
1389  const WebRtc_UWord8 id) {
1390  return _rtpReceiver.RegisterRtpHeaderExtension(type, id);
1391}
1392
1393WebRtc_Word32 ModuleRtpRtcpImpl::DeregisterReceiveRtpHeaderExtension(
1394  const RTPExtensionType type) {
1395  return _rtpReceiver.DeregisterRtpHeaderExtension(type);
1396}
1397
1398/*
1399*   (TMMBR) Temporary Max Media Bit Rate
1400*/
1401bool ModuleRtpRtcpImpl::TMMBR() const {
1402  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "TMMBR()");
1403
1404  return _rtcpSender.TMMBR();
1405}
1406
1407WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBRStatus(const bool enable) {
1408  if (enable) {
1409    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1410                 "SetTMMBRStatus(enable)");
1411  } else {
1412    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1413                 "SetTMMBRStatus(disable)");
1414  }
1415  return _rtcpSender.SetTMMBRStatus(enable);
1416}
1417
1418WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBN(const TMMBRSet* boundingSet) {
1419  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetTMMBN()");
1420
1421  WebRtc_UWord32 maxBitrateKbit = _rtpSender.MaxConfiguredBitrateVideo() / 1000;
1422  return _rtcpSender.SetTMMBN(boundingSet, maxBitrateKbit);
1423}
1424
1425/*
1426*   (NACK) Negative acknowledgement
1427*/
1428
1429// Is Negative acknowledgement requests on/off?
1430NACKMethod ModuleRtpRtcpImpl::NACK() const {
1431  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "NACK()");
1432
1433  NACKMethod childMethod = kNackOff;
1434  const bool defaultInstance(_childModules.empty() ? false : true);
1435  if (defaultInstance) {
1436    // for default we need to check all child modules too
1437    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1438    std::list<ModuleRtpRtcpImpl*>::const_iterator it =
1439      _childModules.begin();
1440    while (it != _childModules.end()) {
1441      RtpRtcp* module = *it;
1442      if (module) {
1443        NACKMethod nackMethod = module->NACK();
1444        if (nackMethod != kNackOff) {
1445          childMethod = nackMethod;
1446          break;
1447        }
1448      }
1449      it++;
1450    }
1451  }
1452
1453  NACKMethod method = _nackMethod;
1454  if (childMethod != kNackOff) {
1455    method = childMethod;
1456  }
1457  return method;
1458}
1459
1460// Turn negative acknowledgement requests on/off
1461WebRtc_Word32 ModuleRtpRtcpImpl::SetNACKStatus(NACKMethod method) {
1462  WEBRTC_TRACE(kTraceModuleCall,
1463               kTraceRtpRtcp,
1464               _id,
1465               "SetNACKStatus(%u)", method);
1466
1467  _nackMethod = method;
1468  _rtpReceiver.SetNACKStatus(method);
1469  return 0;
1470}
1471
1472// Returns the currently configured retransmission mode.
1473int ModuleRtpRtcpImpl::SelectiveRetransmissions() const {
1474  WEBRTC_TRACE(kTraceModuleCall,
1475               kTraceRtpRtcp,
1476               _id,
1477               "SelectiveRetransmissions()");
1478  return _rtpSender.SelectiveRetransmissions();
1479}
1480
1481// Enable or disable a retransmission mode, which decides which packets will
1482// be retransmitted if NACKed.
1483int ModuleRtpRtcpImpl::SetSelectiveRetransmissions(uint8_t settings) {
1484  WEBRTC_TRACE(kTraceModuleCall,
1485               kTraceRtpRtcp,
1486               _id,
1487               "SetSelectiveRetransmissions(%u)",
1488               settings);
1489  return _rtpSender.SetSelectiveRetransmissions(settings);
1490}
1491
1492// Send a Negative acknowledgement packet
1493WebRtc_Word32 ModuleRtpRtcpImpl::SendNACK(const WebRtc_UWord16* nackList,
1494                                          const WebRtc_UWord16 size) {
1495  WEBRTC_TRACE(kTraceModuleCall,
1496               kTraceRtpRtcp,
1497               _id,
1498               "SendNACK(size:%u)", size);
1499
1500  if (size > NACK_PACKETS_MAX_SIZE) {
1501    RequestKeyFrame();
1502    return -1;
1503  }
1504  WebRtc_UWord16 avgRTT = 0;
1505  _rtcpReceiver.RTT(_rtpReceiver.SSRC(), NULL, &avgRTT, NULL, NULL);
1506
1507  WebRtc_Word64 waitTime = 5 + ((avgRTT * 3) >> 1);  // 5 + RTT*1.5
1508  if (waitTime == 5) {
1509    waitTime = 100;  // During startup we don't have an RTT
1510  }
1511  const WebRtc_Word64 now = _clock.GetTimeInMS();
1512  const WebRtc_Word64 timeLimit = now - waitTime;
1513  WebRtc_UWord16 nackLength = size;
1514  WebRtc_UWord16 startId = 0;
1515
1516  if (_nackLastTimeSent < timeLimit) {
1517    // send list
1518  } else {
1519    // only send if extended list
1520    if (_nackLastSeqNumberSent == nackList[size - 1]) {
1521      // last seq num is the same don't send list
1522      return 0;
1523    } else {
1524      //
1525      // send NACK's only for new sequence numbers to avoid re-sending
1526      // of NACK's for sequences we have already sent
1527      //
1528      for (int i = 0; i < size; i++)  {
1529        if (_nackLastSeqNumberSent == nackList[i]) {
1530          startId = i+1;
1531          break;
1532        }
1533      }
1534      nackLength = size-startId;
1535    }
1536  }
1537  _nackLastTimeSent =  now;
1538  _nackLastSeqNumberSent = nackList[size - 1];
1539
1540  switch (_nackMethod) {
1541    case kNackRtcp:
1542      return _rtcpSender.SendRTCP(kRtcpNack, nackLength, &nackList[startId]);
1543    case kNackOff:
1544      return -1;
1545  };
1546  return -1;
1547}
1548
1549// Store the sent packets, needed to answer to a Negative acknowledgement
1550// requests
1551WebRtc_Word32 ModuleRtpRtcpImpl::SetStorePacketsStatus(
1552  const bool enable,
1553  const WebRtc_UWord16 numberToStore) {
1554  if (enable) {
1555    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1556                 "SetStorePacketsStatus(enable, numberToStore:%d)",
1557                 numberToStore);
1558  } else {
1559    WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1560                 "SetStorePacketsStatus(disable)");
1561  }
1562  _rtpSender.SetStorePacketsStatus(enable, numberToStore);
1563  return 0;  // TODO(pwestin): change to void.
1564}
1565
1566/*
1567*   Audio
1568*/
1569
1570// Outband TelephoneEvent detection
1571WebRtc_Word32 ModuleRtpRtcpImpl::SetTelephoneEventStatus(
1572  const bool enable,
1573  const bool forwardToDecoder,
1574  const bool detectEndOfTone) {
1575  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1576               "SetTelephoneEventStatus(enable:%d forwardToDecoder:%d"
1577               " detectEndOfTone:%d)", enable, forwardToDecoder,
1578               detectEndOfTone);
1579
1580  return _rtpReceiver.GetAudioReceiver()->SetTelephoneEventStatus(
1581      enable, forwardToDecoder, detectEndOfTone);
1582}
1583
1584// Is outband TelephoneEvent turned on/off?
1585bool ModuleRtpRtcpImpl::TelephoneEvent() const {
1586  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "TelephoneEvent()");
1587
1588  return _rtpReceiver.GetAudioReceiver()->TelephoneEvent();
1589}
1590
1591// Is forwarding of outband telephone events turned on/off?
1592bool ModuleRtpRtcpImpl::TelephoneEventForwardToDecoder() const {
1593  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1594               "TelephoneEventForwardToDecoder()");
1595
1596  return _rtpReceiver.GetAudioReceiver()->TelephoneEventForwardToDecoder();
1597}
1598
1599// Send a TelephoneEvent tone using RFC 2833 (4733)
1600WebRtc_Word32 ModuleRtpRtcpImpl::SendTelephoneEventOutband(
1601    const WebRtc_UWord8 key,
1602    const WebRtc_UWord16 timeMs,
1603    const WebRtc_UWord8 level) {
1604  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1605               "SendTelephoneEventOutband(key:%u, timeMs:%u, level:%u)", key,
1606               timeMs, level);
1607
1608  return _rtpSender.SendTelephoneEvent(key, timeMs, level);
1609}
1610
1611bool ModuleRtpRtcpImpl::SendTelephoneEventActive(
1612  WebRtc_Word8& telephoneEvent) const {
1613
1614  WEBRTC_TRACE(kTraceModuleCall,
1615               kTraceRtpRtcp,
1616               _id,
1617               "SendTelephoneEventActive()");
1618
1619  return _rtpSender.SendTelephoneEventActive(telephoneEvent);
1620}
1621
1622// set audio packet size, used to determine when it's time to send a DTMF
1623// packet in silence (CNG)
1624WebRtc_Word32 ModuleRtpRtcpImpl::SetAudioPacketSize(
1625  const WebRtc_UWord16 packetSizeSamples) {
1626
1627  WEBRTC_TRACE(kTraceModuleCall,
1628               kTraceRtpRtcp,
1629               _id,
1630               "SetAudioPacketSize(%u)",
1631               packetSizeSamples);
1632
1633  return _rtpSender.SetAudioPacketSize(packetSizeSamples);
1634}
1635
1636WebRtc_Word32 ModuleRtpRtcpImpl::SetRTPAudioLevelIndicationStatus(
1637  const bool enable,
1638  const WebRtc_UWord8 ID) {
1639
1640  WEBRTC_TRACE(kTraceModuleCall,
1641               kTraceRtpRtcp,
1642               _id,
1643               "SetRTPAudioLevelIndicationStatus(enable=%d, ID=%u)",
1644               enable,
1645               ID);
1646
1647  if (enable) {
1648    _rtpReceiver.RegisterRtpHeaderExtension(kRtpExtensionAudioLevel, ID);
1649  } else {
1650    _rtpReceiver.DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel);
1651  }
1652  return _rtpSender.SetAudioLevelIndicationStatus(enable, ID);
1653}
1654
1655WebRtc_Word32 ModuleRtpRtcpImpl::GetRTPAudioLevelIndicationStatus(
1656  bool& enable,
1657  WebRtc_UWord8& ID) const {
1658
1659  WEBRTC_TRACE(kTraceModuleCall,
1660               kTraceRtpRtcp,
1661               _id,
1662               "GetRTPAudioLevelIndicationStatus()");
1663  return _rtpSender.AudioLevelIndicationStatus(enable, ID);
1664}
1665
1666WebRtc_Word32 ModuleRtpRtcpImpl::SetAudioLevel(const WebRtc_UWord8 level_dBov) {
1667  WEBRTC_TRACE(kTraceModuleCall,
1668               kTraceRtpRtcp,
1669               _id,
1670               "SetAudioLevel(level_dBov:%u)",
1671               level_dBov);
1672  return _rtpSender.SetAudioLevel(level_dBov);
1673}
1674
1675// Set payload type for Redundant Audio Data RFC 2198
1676WebRtc_Word32 ModuleRtpRtcpImpl::SetSendREDPayloadType(
1677  const WebRtc_Word8 payloadType) {
1678  WEBRTC_TRACE(kTraceModuleCall,
1679               kTraceRtpRtcp,
1680               _id,
1681               "SetSendREDPayloadType(%d)",
1682               payloadType);
1683
1684  return _rtpSender.SetRED(payloadType);
1685}
1686
1687// Get payload type for Redundant Audio Data RFC 2198
1688WebRtc_Word32 ModuleRtpRtcpImpl::SendREDPayloadType(
1689    WebRtc_Word8& payloadType) const {
1690  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SendREDPayloadType()");
1691
1692  return _rtpSender.RED(payloadType);
1693}
1694
1695
1696/*
1697*   Video
1698*/
1699RtpVideoCodecTypes ModuleRtpRtcpImpl::ReceivedVideoCodec() const {
1700  return _rtpReceiver.VideoCodecType();
1701}
1702
1703RtpVideoCodecTypes ModuleRtpRtcpImpl::SendVideoCodec() const {
1704  return _rtpSender.VideoCodecType();
1705}
1706
1707void ModuleRtpRtcpImpl::SetTargetSendBitrate(const uint32_t bitrate) {
1708  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1709               "SetTargetSendBitrate: %ubit", bitrate);
1710
1711  const bool haveChildModules(_childModules.empty() ? false : true);
1712  if (haveChildModules) {
1713    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1714    if (_simulcast) {
1715      uint32_t bitrate_remainder = bitrate;
1716      std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1717      for (int i = 0; it != _childModules.end() &&
1718          i < _sendVideoCodec.numberOfSimulcastStreams; ++it) {
1719        if ((*it)->SendingMedia()) {
1720          RTPSender& rtpSender = (*it)->_rtpSender;
1721          if (_sendVideoCodec.simulcastStream[i].maxBitrate * 1000 >
1722              bitrate_remainder) {
1723            rtpSender.SetTargetSendBitrate(bitrate_remainder);
1724            bitrate_remainder = 0;
1725          } else {
1726            rtpSender.SetTargetSendBitrate(
1727                _sendVideoCodec.simulcastStream[i].maxBitrate * 1000);
1728            bitrate_remainder -=
1729                _sendVideoCodec.simulcastStream[i].maxBitrate * 1000;
1730          }
1731          ++i;
1732        }
1733      }
1734    } else {
1735      std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1736      for (; it != _childModules.end(); ++it) {
1737        RTPSender& rtpSender = (*it)->_rtpSender;
1738        rtpSender.SetTargetSendBitrate(bitrate);
1739      }
1740    }
1741  } else {
1742    _rtpSender.SetTargetSendBitrate(bitrate);
1743  }
1744}
1745
1746WebRtc_Word32 ModuleRtpRtcpImpl::SetKeyFrameRequestMethod(
1747  const KeyFrameRequestMethod method) {
1748  WEBRTC_TRACE(kTraceModuleCall,
1749               kTraceRtpRtcp,
1750               _id,
1751               "SetKeyFrameRequestMethod(method:%u)",
1752               method);
1753
1754  _keyFrameReqMethod = method;
1755  return 0;
1756}
1757
1758WebRtc_Word32 ModuleRtpRtcpImpl::RequestKeyFrame() {
1759  WEBRTC_TRACE(kTraceModuleCall,
1760               kTraceRtpRtcp,
1761               _id,
1762               "RequestKeyFrame");
1763
1764  switch (_keyFrameReqMethod) {
1765    case kKeyFrameReqFirRtp:
1766      return _rtpSender.SendRTPIntraRequest();
1767    case kKeyFrameReqPliRtcp:
1768      return _rtcpSender.SendRTCP(kRtcpPli);
1769    case kKeyFrameReqFirRtcp:
1770      return _rtcpSender.SendRTCP(kRtcpFir);
1771  }
1772  return -1;
1773}
1774
1775WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCPSliceLossIndication(
1776  const WebRtc_UWord8 pictureID) {
1777  WEBRTC_TRACE(kTraceModuleCall,
1778               kTraceRtpRtcp,
1779               _id,
1780               "SendRTCPSliceLossIndication (pictureID:%d)",
1781               pictureID);
1782  return _rtcpSender.SendRTCP(kRtcpSli, 0, 0, false, pictureID);
1783}
1784
1785WebRtc_Word32 ModuleRtpRtcpImpl::SetCameraDelay(const WebRtc_Word32 delayMS) {
1786  WEBRTC_TRACE(kTraceModuleCall,
1787               kTraceRtpRtcp,
1788               _id,
1789               "SetCameraDelay(%d)",
1790               delayMS);
1791  const bool defaultInstance(_childModules.empty() ? false : true);
1792
1793  if (defaultInstance) {
1794    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1795
1796    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1797    while (it != _childModules.end()) {
1798      RtpRtcp* module = *it;
1799      if (module) {
1800        module->SetCameraDelay(delayMS);
1801      }
1802      it++;
1803    }
1804    return 0;
1805  }
1806  return _rtcpSender.SetCameraDelay(delayMS);
1807}
1808
1809WebRtc_Word32 ModuleRtpRtcpImpl::SetGenericFECStatus(
1810  const bool enable,
1811  const WebRtc_UWord8 payloadTypeRED,
1812  const WebRtc_UWord8 payloadTypeFEC) {
1813  if (enable) {
1814    WEBRTC_TRACE(kTraceModuleCall,
1815                 kTraceRtpRtcp,
1816                 _id,
1817                 "SetGenericFECStatus(enable, %u)",
1818                 payloadTypeRED);
1819  } else {
1820    WEBRTC_TRACE(kTraceModuleCall,
1821                 kTraceRtpRtcp,
1822                 _id,
1823                 "SetGenericFECStatus(disable)");
1824  }
1825  return _rtpSender.SetGenericFECStatus(enable,
1826                                        payloadTypeRED,
1827                                        payloadTypeFEC);
1828}
1829
1830WebRtc_Word32 ModuleRtpRtcpImpl::GenericFECStatus(
1831  bool& enable,
1832  WebRtc_UWord8& payloadTypeRED,
1833  WebRtc_UWord8& payloadTypeFEC) {
1834
1835  WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "GenericFECStatus()");
1836
1837  bool childEnabled = false;
1838  const bool defaultInstance(_childModules.empty() ? false : true);
1839  if (defaultInstance) {
1840    // for default we need to check all child modules too
1841    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1842    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1843    while (it != _childModules.end()) {
1844      RtpRtcp* module = *it;
1845      if (module)  {
1846        bool enabled = false;
1847        WebRtc_UWord8 dummyPTypeRED = 0;
1848        WebRtc_UWord8 dummyPTypeFEC = 0;
1849        if (module->GenericFECStatus(enabled,
1850                                     dummyPTypeRED,
1851                                     dummyPTypeFEC) == 0 && enabled) {
1852          childEnabled = true;
1853          break;
1854        }
1855      }
1856      it++;
1857    }
1858  }
1859  WebRtc_Word32 retVal = _rtpSender.GenericFECStatus(enable,
1860                                                     payloadTypeRED,
1861                                                     payloadTypeFEC);
1862  if (childEnabled) {
1863    // returns true if enabled for any child module
1864    enable = childEnabled;
1865  }
1866  return retVal;
1867}
1868
1869WebRtc_Word32 ModuleRtpRtcpImpl::SetFecParameters(
1870    const FecProtectionParams* delta_params,
1871    const FecProtectionParams* key_params) {
1872  const bool defaultInstance(_childModules.empty() ? false : true);
1873  if (defaultInstance)  {
1874    // for default we need to update all child modules too
1875    CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1876
1877    std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1878    while (it != _childModules.end()) {
1879      RtpRtcp* module = *it;
1880      if (module) {
1881        module->SetFecParameters(delta_params, key_params);
1882      }
1883      it++;
1884    }
1885    return 0;
1886  }
1887  return _rtpSender.SetFecParameters(delta_params, key_params);
1888}
1889
1890void ModuleRtpRtcpImpl::SetRemoteSSRC(const WebRtc_UWord32 SSRC) {
1891  // inform about the incoming SSRC
1892  _rtcpSender.SetRemoteSSRC(SSRC);
1893  _rtcpReceiver.SetRemoteSSRC(SSRC);
1894
1895  // check for a SSRC collision
1896  if (_rtpSender.SSRC() == SSRC && !_collisionDetected) {
1897    // if we detect a collision change the SSRC but only once
1898    _collisionDetected = true;
1899    WebRtc_UWord32 newSSRC = _rtpSender.GenerateNewSSRC();
1900    if (newSSRC == 0) {
1901      // configured via API ignore
1902      return;
1903    }
1904    if (kRtcpOff != _rtcpSender.Status()) {
1905      // send RTCP bye on the current SSRC
1906      _rtcpSender.SendRTCP(kRtcpBye);
1907    }
1908    // change local SSRC
1909
1910    // inform all objects about the new SSRC
1911    _rtcpSender.SetSSRC(newSSRC);
1912    _rtcpReceiver.SetSSRC(newSSRC);
1913  }
1914}
1915
1916WebRtc_UWord32 ModuleRtpRtcpImpl::BitrateReceivedNow() const {
1917  return _rtpReceiver.BitrateNow();
1918}
1919
1920void ModuleRtpRtcpImpl::BitrateSent(WebRtc_UWord32* totalRate,
1921                                    WebRtc_UWord32* videoRate,
1922                                    WebRtc_UWord32* fecRate,
1923                                    WebRtc_UWord32* nackRate) const {
1924  const bool defaultInstance(_childModules.empty() ? false : true);
1925
1926  if (defaultInstance) {
1927    // for default we need to update the send bitrate
1928    CriticalSectionScoped lock(_criticalSectionModulePtrsFeedback.get());
1929
1930    if (totalRate != NULL)
1931      *totalRate = 0;
1932    if (videoRate != NULL)
1933      *videoRate = 0;
1934    if (fecRate != NULL)
1935      *fecRate = 0;
1936    if (nackRate != NULL)
1937      *nackRate = 0;
1938
1939    std::list<ModuleRtpRtcpImpl*>::const_iterator it =
1940      _childModules.begin();
1941    while (it != _childModules.end()) {
1942      RtpRtcp* module = *it;
1943      if (module) {
1944        WebRtc_UWord32 childTotalRate = 0;
1945        WebRtc_UWord32 childVideoRate = 0;
1946        WebRtc_UWord32 childFecRate = 0;
1947        WebRtc_UWord32 childNackRate = 0;
1948        module->BitrateSent(&childTotalRate,
1949                            &childVideoRate,
1950                            &childFecRate,
1951                            &childNackRate);
1952        if (totalRate != NULL && childTotalRate > *totalRate)
1953          *totalRate = childTotalRate;
1954        if (videoRate != NULL && childVideoRate > *videoRate)
1955          *videoRate = childVideoRate;
1956        if (fecRate != NULL && childFecRate > *fecRate)
1957          *fecRate = childFecRate;
1958        if (nackRate != NULL && childNackRate > *nackRate)
1959          *nackRate = childNackRate;
1960      }
1961      it++;
1962    }
1963    return;
1964  }
1965  if (totalRate != NULL)
1966    *totalRate = _rtpSender.BitrateLast();
1967  if (videoRate != NULL)
1968    *videoRate = _rtpSender.VideoBitrateSent();
1969  if (fecRate != NULL)
1970    *fecRate = _rtpSender.FecOverheadRate();
1971  if (nackRate != NULL)
1972    *nackRate = _rtpSender.NackOverheadRate();
1973}
1974
1975int ModuleRtpRtcpImpl::EstimatedReceiveBandwidth(
1976    WebRtc_UWord32* available_bandwidth) const {
1977  if (remote_bitrate_) {
1978    std::vector<unsigned int> ssrcs;
1979    if (!remote_bitrate_->LatestEstimate(&ssrcs, available_bandwidth)) {
1980      return -1;
1981    }
1982    if (!ssrcs.empty()) {
1983      *available_bandwidth /= ssrcs.size();
1984    }
1985    return 0;
1986  }
1987  // No bandwidth receive-side bandwidth estimation is connected to this module.
1988  return -1;
1989}
1990
1991// bad state of RTP receiver request a keyframe
1992void ModuleRtpRtcpImpl::OnRequestIntraFrame() {
1993  RequestKeyFrame();
1994}
1995
1996void ModuleRtpRtcpImpl::OnRequestSendReport() {
1997  _rtcpSender.SendRTCP(kRtcpSr);
1998}
1999
2000WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection(
2001  const WebRtc_UWord64 pictureID) {
2002  return _rtcpSender.SendRTCP(kRtcpRpsi, 0, 0, false, pictureID);
2003}
2004
2005WebRtc_UWord32 ModuleRtpRtcpImpl::SendTimeOfSendReport(
2006  const WebRtc_UWord32 sendReport) {
2007  return _rtcpSender.SendTimeOfSendReport(sendReport);
2008}
2009
2010void ModuleRtpRtcpImpl::OnReceivedNACK(
2011  const WebRtc_UWord16 nackSequenceNumbersLength,
2012  const WebRtc_UWord16* nackSequenceNumbers) {
2013  if (!_rtpSender.StorePackets() ||
2014      nackSequenceNumbers == NULL ||
2015      nackSequenceNumbersLength == 0) {
2016    return;
2017  }
2018  WebRtc_UWord16 avgRTT = 0;
2019  _rtcpReceiver.RTT(_rtpReceiver.SSRC(), NULL, &avgRTT, NULL, NULL);
2020  _rtpSender.OnReceivedNACK(nackSequenceNumbersLength,
2021                            nackSequenceNumbers,
2022                            avgRTT);
2023}
2024
2025WebRtc_Word32 ModuleRtpRtcpImpl::LastReceivedNTP(
2026  WebRtc_UWord32& RTCPArrivalTimeSecs,  // when we received the last report
2027  WebRtc_UWord32& RTCPArrivalTimeFrac,
2028  WebRtc_UWord32& remoteSR) {
2029  // remote SR: NTP inside the last received (mid 16 bits from sec and frac)
2030  WebRtc_UWord32 NTPsecs = 0;
2031  WebRtc_UWord32 NTPfrac = 0;
2032
2033  if (-1 == _rtcpReceiver.NTP(&NTPsecs,
2034                              &NTPfrac,
2035                              &RTCPArrivalTimeSecs,
2036                              &RTCPArrivalTimeFrac,
2037                              NULL)) {
2038    return -1;
2039  }
2040  remoteSR = ((NTPsecs & 0x0000ffff) << 16) + ((NTPfrac & 0xffff0000) >> 16);
2041  return 0;
2042}
2043
2044bool ModuleRtpRtcpImpl::UpdateRTCPReceiveInformationTimers() {
2045  // if this returns true this channel has timed out
2046  // periodically check if this is true and if so call UpdateTMMBR
2047  return _rtcpReceiver.UpdateRTCPReceiveInformationTimers();
2048}
2049
2050// called from RTCPsender
2051WebRtc_Word32 ModuleRtpRtcpImpl::BoundingSet(bool& tmmbrOwner,
2052                                             TMMBRSet*& boundingSet) {
2053  return _rtcpReceiver.BoundingSet(tmmbrOwner, boundingSet);
2054}
2055
2056int64_t ModuleRtpRtcpImpl::RtcpReportInterval() {
2057  if (_audio)
2058    return RTCP_INTERVAL_AUDIO_MS;
2059  else
2060    return RTCP_INTERVAL_VIDEO_MS;
2061}
2062
2063}  // namespace webrtc
2064