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