Bug 797671: Import Webrtc.org code from stable branch 3.12 (rev 2820) rs=jesup
[gecko.git] / media / webrtc / trunk / src / modules / rtp_rtcp / source / rtp_rtcp_impl.cc
blob8f00ea32d5aa17f52e96685890af7287109de42c
1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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 */
11 #include "common_types.h"
12 #include "rtp_rtcp_impl.h"
13 #include "trace.h"
15 #ifdef MATLAB
16 #include "../test/BWEStandAlone/MatlabPlot.h"
17 extern MatlabEngine eng; // global variable defined elsewhere
18 #endif
20 #include <string.h> //memcpy
21 #include <cassert> //assert
23 // local for this file
24 namespace {
26 const float FracMS = 4.294967296E6f;
28 } // namepace
30 #ifdef _WIN32
31 // disable warning C4355: 'this' : used in base member initializer list
32 #pragma warning(disable : 4355)
33 #endif
35 namespace webrtc {
37 const WebRtc_UWord16 kDefaultRtt = 200;
39 RtpRtcp* RtpRtcp::CreateRtpRtcp(const RtpRtcp::Configuration& configuration) {
40 if (configuration.clock) {
41 return new ModuleRtpRtcpImpl(configuration);
42 } else {
43 RtpRtcp::Configuration configuration_copy;
44 memcpy(&configuration_copy, &configuration,
45 sizeof(RtpRtcp::Configuration));
46 configuration_copy.clock = ModuleRTPUtility::GetSystemClock();
47 ModuleRtpRtcpImpl* rtp_rtcp_instance =
48 new ModuleRtpRtcpImpl(configuration_copy);
49 rtp_rtcp_instance->OwnsClock();
50 return rtp_rtcp_instance;
54 ModuleRtpRtcpImpl::ModuleRtpRtcpImpl(const Configuration& configuration)
55 : _rtpSender(configuration.id, configuration.audio, configuration.clock),
56 _rtpReceiver(configuration.id, configuration.audio, configuration.clock,
57 configuration.remote_bitrate_estimator, this),
58 _rtcpSender(configuration.id, configuration.audio, configuration.clock,
59 this),
60 _rtcpReceiver(configuration.id, configuration.clock, this),
61 _owns_clock(false),
62 _clock(*configuration.clock),
63 _id(configuration.id),
64 _audio(configuration.audio),
65 _collisionDetected(false),
66 _lastProcessTime(configuration.clock->GetTimeInMS()),
67 _lastBitrateProcessTime(configuration.clock->GetTimeInMS()),
68 _lastPacketTimeoutProcessTime(configuration.clock->GetTimeInMS()),
69 _packetOverHead(28), // IPV4 UDP
70 _criticalSectionModulePtrs(
71 CriticalSectionWrapper::CreateCriticalSection()),
72 _criticalSectionModulePtrsFeedback(
73 CriticalSectionWrapper::CreateCriticalSection()),
74 _defaultModule(
75 static_cast<ModuleRtpRtcpImpl*>(configuration.default_module)),
76 _deadOrAliveActive(false),
77 _deadOrAliveTimeoutMS(0),
78 _deadOrAliveLastTimer(0),
79 _nackMethod(kNackOff),
80 _nackLastTimeSent(0),
81 _nackLastSeqNumberSent(0),
82 _simulcast(false),
83 _keyFrameReqMethod(kKeyFrameReqFirRtp),
84 remote_bitrate_(configuration.remote_bitrate_estimator)
85 #ifdef MATLAB
86 , _plot1(NULL)
87 #endif
89 _sendVideoCodec.codecType = kVideoCodecUnknown;
91 if (_defaultModule) {
92 _defaultModule->RegisterChildModule(this);
94 // TODO(pwestin) move to constructors of each rtp/rtcp sender/receiver object.
95 _rtpReceiver.RegisterIncomingDataCallback(configuration.incoming_data);
96 _rtpReceiver.RegisterIncomingRTPCallback(configuration.incoming_messages);
97 _rtcpReceiver.RegisterRtcpObservers(configuration.intra_frame_callback,
98 configuration.bandwidth_callback,
99 configuration.rtcp_feedback);
100 _rtpSender.RegisterAudioCallback(configuration.audio_messages);
101 _rtpReceiver.RegisterIncomingAudioCallback(configuration.audio_messages);
103 _rtpSender.RegisterSendTransport(configuration.outgoing_transport);
104 _rtcpSender.RegisterSendTransport(configuration.outgoing_transport);
106 // make sure that RTCP objects are aware of our SSRC
107 WebRtc_UWord32 SSRC = _rtpSender.SSRC();
108 _rtcpSender.SetSSRC(SSRC);
110 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s created", __FUNCTION__);
113 ModuleRtpRtcpImpl::~ModuleRtpRtcpImpl() {
114 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__);
116 // All child modules MUST be deleted before deleting the default.
117 assert(_childModules.empty());
119 // Deregister for the child modules
120 // will go in to the default and remove it self
121 if (_defaultModule) {
122 _defaultModule->DeRegisterChildModule(this);
124 #ifdef MATLAB
125 if (_plot1) {
126 eng.DeletePlot(_plot1);
127 _plot1 = NULL;
129 #endif
130 if (_owns_clock) {
131 delete &_clock;
135 void ModuleRtpRtcpImpl::RegisterChildModule(RtpRtcp* module) {
136 WEBRTC_TRACE(kTraceModuleCall,
137 kTraceRtpRtcp,
138 _id,
139 "RegisterChildModule(module:0x%x)",
140 module);
142 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
144 CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback.get());
145 // we use two locks for protecting _childModules one
146 // (_criticalSectionModulePtrsFeedback) for incoming
147 // messages (BitrateSent) and _criticalSectionModulePtrs
148 // for all outgoing messages sending packets etc
149 _childModules.push_back((ModuleRtpRtcpImpl*)module);
152 void ModuleRtpRtcpImpl::DeRegisterChildModule(RtpRtcp* removeModule) {
153 WEBRTC_TRACE(kTraceModuleCall,
154 kTraceRtpRtcp,
155 _id,
156 "DeRegisterChildModule(module:0x%x)", removeModule);
158 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
160 CriticalSectionScoped doubleLock(_criticalSectionModulePtrsFeedback.get());
162 std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
163 while (it != _childModules.end()) {
164 RtpRtcp* module = *it;
165 if (module == removeModule) {
166 _childModules.erase(it);
167 return;
169 it++;
173 // returns the number of milliseconds until the module want a worker thread
174 // to call Process
175 WebRtc_Word32 ModuleRtpRtcpImpl::TimeUntilNextProcess() {
176 const WebRtc_Word64 now = _clock.GetTimeInMS();
177 return kRtpRtcpMaxIdleTimeProcess - (now - _lastProcessTime);
180 // Process any pending tasks such as timeouts
181 // non time critical events
182 WebRtc_Word32 ModuleRtpRtcpImpl::Process() {
183 const WebRtc_Word64 now = _clock.GetTimeInMS();
184 _lastProcessTime = now;
186 _rtpSender.ProcessSendToNetwork();
188 if (now >= _lastPacketTimeoutProcessTime +
189 kRtpRtcpPacketTimeoutProcessTimeMs) {
190 _rtpReceiver.PacketTimeout();
191 _rtcpReceiver.PacketTimeout();
192 _lastPacketTimeoutProcessTime = now;
195 if (now >= _lastBitrateProcessTime + kRtpRtcpBitrateProcessTimeMs) {
196 _rtpSender.ProcessBitrate();
197 _rtpReceiver.ProcessBitrate();
198 _lastBitrateProcessTime = now;
201 ProcessDeadOrAliveTimer();
203 const bool defaultInstance(_childModules.empty() ? false : true);
204 if (!defaultInstance && _rtcpSender.TimeToSendRTCPReport()) {
205 WebRtc_UWord16 max_rtt = 0;
206 if (_rtcpSender.Sending()) {
207 std::vector<RTCPReportBlock> receive_blocks;
208 _rtcpReceiver.StatisticsReceived(&receive_blocks);
209 for (std::vector<RTCPReportBlock>::iterator it = receive_blocks.begin();
210 it != receive_blocks.end(); ++it) {
211 WebRtc_UWord16 rtt = 0;
212 _rtcpReceiver.RTT(it->remoteSSRC, &max_rtt, NULL, NULL, NULL);
213 max_rtt = (rtt > max_rtt) ? rtt : max_rtt;
215 } else {
216 // We're only receiving, i.e. this module doesn't have its own RTT
217 // estimate. Use the RTT set by a sending channel using the same default
218 // module.
219 max_rtt = _rtcpReceiver.RTT();
221 if (max_rtt == 0) {
222 // No valid estimate available, i.e. no sending channel using the same
223 // default module or no RTCP received yet.
224 max_rtt = kDefaultRtt;
226 if (remote_bitrate_) {
227 remote_bitrate_->SetRtt(max_rtt);
228 remote_bitrate_->UpdateEstimate(_rtpReceiver.SSRC(), now);
229 if (TMMBR()) {
230 unsigned int target_bitrate = 0;
231 if (remote_bitrate_->LatestEstimate(_rtpReceiver.SSRC(),
232 &target_bitrate)) {
233 _rtcpSender.SetTargetBitrate(target_bitrate);
237 _rtcpSender.SendRTCP(kRtcpReport);
240 if (UpdateRTCPReceiveInformationTimers()) {
241 // a receiver has timed out
242 _rtcpReceiver.UpdateTMMBR();
244 return 0;
248 * Receiver
251 void ModuleRtpRtcpImpl::ProcessDeadOrAliveTimer() {
252 if (_deadOrAliveActive) {
253 const WebRtc_Word64 now = _clock.GetTimeInMS();
254 if (now > _deadOrAliveTimeoutMS + _deadOrAliveLastTimer) {
255 // RTCP is alive if we have received a report the last 12 seconds
256 _deadOrAliveLastTimer += _deadOrAliveTimeoutMS;
258 bool RTCPalive = false;
259 if (_rtcpReceiver.LastReceived() + 12000 > now) {
260 RTCPalive = true;
262 _rtpReceiver.ProcessDeadOrAlive(RTCPalive, now);
267 WebRtc_Word32 ModuleRtpRtcpImpl::SetPeriodicDeadOrAliveStatus(
268 const bool enable,
269 const WebRtc_UWord8 sampleTimeSeconds) {
270 if (enable) {
271 WEBRTC_TRACE(kTraceModuleCall,
272 kTraceRtpRtcp,
273 _id,
274 "SetPeriodicDeadOrAliveStatus(enable, %d)",
275 sampleTimeSeconds);
276 } else {
277 WEBRTC_TRACE(kTraceModuleCall,
278 kTraceRtpRtcp,
279 _id,
280 "SetPeriodicDeadOrAliveStatus(disable)");
282 if (sampleTimeSeconds == 0) {
283 return -1;
285 _deadOrAliveActive = enable;
286 _deadOrAliveTimeoutMS = sampleTimeSeconds * 1000;
287 // trigger the first after one period
288 _deadOrAliveLastTimer = _clock.GetTimeInMS();
289 return 0;
292 WebRtc_Word32 ModuleRtpRtcpImpl::PeriodicDeadOrAliveStatus(
293 bool& enable,
294 WebRtc_UWord8& sampleTimeSeconds) {
295 WEBRTC_TRACE(kTraceModuleCall,
296 kTraceRtpRtcp,
297 _id,
298 "PeriodicDeadOrAliveStatus()");
300 enable = _deadOrAliveActive;
301 sampleTimeSeconds = (WebRtc_UWord8)(_deadOrAliveTimeoutMS / 1000);
302 return 0;
305 WebRtc_Word32 ModuleRtpRtcpImpl::SetPacketTimeout(
306 const WebRtc_UWord32 RTPtimeoutMS,
307 const WebRtc_UWord32 RTCPtimeoutMS) {
308 WEBRTC_TRACE(kTraceModuleCall,
309 kTraceRtpRtcp,
310 _id,
311 "SetPacketTimeout(%u,%u)",
312 RTPtimeoutMS,
313 RTCPtimeoutMS);
315 if (_rtpReceiver.SetPacketTimeout(RTPtimeoutMS) == 0) {
316 return _rtcpReceiver.SetPacketTimeout(RTCPtimeoutMS);
318 return -1;
321 WebRtc_Word32 ModuleRtpRtcpImpl::RegisterReceivePayload(
322 const CodecInst& voiceCodec) {
323 WEBRTC_TRACE(kTraceModuleCall,
324 kTraceRtpRtcp,
325 _id,
326 "RegisterReceivePayload(voiceCodec)");
328 return _rtpReceiver.RegisterReceivePayload(
329 voiceCodec.plname,
330 voiceCodec.pltype,
331 voiceCodec.plfreq,
332 voiceCodec.channels,
333 (voiceCodec.rate < 0) ? 0 : voiceCodec.rate);
336 WebRtc_Word32 ModuleRtpRtcpImpl::RegisterReceivePayload(
337 const VideoCodec& videoCodec) {
338 WEBRTC_TRACE(kTraceModuleCall,
339 kTraceRtpRtcp,
340 _id,
341 "RegisterReceivePayload(videoCodec)");
343 return _rtpReceiver.RegisterReceivePayload(videoCodec.plName,
344 videoCodec.plType,
345 90000,
347 videoCodec.maxBitrate);
350 WebRtc_Word32 ModuleRtpRtcpImpl::ReceivePayloadType(
351 const CodecInst& voiceCodec,
352 WebRtc_Word8* plType) {
353 WEBRTC_TRACE(kTraceModuleCall,
354 kTraceRtpRtcp,
355 _id,
356 "ReceivePayloadType(voiceCodec)");
358 return _rtpReceiver.ReceivePayloadType(
359 voiceCodec.plname,
360 voiceCodec.plfreq,
361 voiceCodec.channels,
362 (voiceCodec.rate < 0) ? 0 : voiceCodec.rate,
363 plType);
366 WebRtc_Word32 ModuleRtpRtcpImpl::ReceivePayloadType(
367 const VideoCodec& videoCodec,
368 WebRtc_Word8* plType) {
369 WEBRTC_TRACE(kTraceModuleCall,
370 kTraceRtpRtcp,
371 _id,
372 "ReceivePayloadType(videoCodec)");
374 return _rtpReceiver.ReceivePayloadType(videoCodec.plName,
375 90000,
377 videoCodec.maxBitrate,
378 plType);
381 WebRtc_Word32 ModuleRtpRtcpImpl::DeRegisterReceivePayload(
382 const WebRtc_Word8 payloadType) {
383 WEBRTC_TRACE(kTraceModuleCall,
384 kTraceRtpRtcp,
385 _id,
386 "DeRegisterReceivePayload(%d)",
387 payloadType);
389 return _rtpReceiver.DeRegisterReceivePayload(payloadType);
392 // get the currently configured SSRC filter
393 WebRtc_Word32 ModuleRtpRtcpImpl::SSRCFilter(WebRtc_UWord32& allowedSSRC) const {
394 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SSRCFilter()");
396 return _rtpReceiver.SSRCFilter(allowedSSRC);
399 // set a SSRC to be used as a filter for incoming RTP streams
400 WebRtc_Word32 ModuleRtpRtcpImpl::SetSSRCFilter(
401 const bool enable,
402 const WebRtc_UWord32 allowedSSRC) {
403 if (enable) {
404 WEBRTC_TRACE(kTraceModuleCall,
405 kTraceRtpRtcp,
406 _id,
407 "SetSSRCFilter(enable, 0x%x)",
408 allowedSSRC);
409 } else {
410 WEBRTC_TRACE(kTraceModuleCall,
411 kTraceRtpRtcp,
412 _id,
413 "SetSSRCFilter(disable)");
416 return _rtpReceiver.SetSSRCFilter(enable, allowedSSRC);
419 // Get last received remote timestamp
420 WebRtc_UWord32 ModuleRtpRtcpImpl::RemoteTimestamp() const {
421 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteTimestamp()");
423 return _rtpReceiver.TimeStamp();
426 // Get the current estimated remote timestamp
427 WebRtc_Word32 ModuleRtpRtcpImpl::EstimatedRemoteTimeStamp(
428 WebRtc_UWord32& timestamp) const {
429 WEBRTC_TRACE(kTraceModuleCall,
430 kTraceRtpRtcp,
431 _id,
432 "EstimatedRemoteTimeStamp()");
434 return _rtpReceiver.EstimatedRemoteTimeStamp(timestamp);
437 // Get incoming SSRC
438 WebRtc_UWord32 ModuleRtpRtcpImpl::RemoteSSRC() const {
439 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteSSRC()");
441 return _rtpReceiver.SSRC();
444 // Get remote CSRC
445 WebRtc_Word32 ModuleRtpRtcpImpl::RemoteCSRCs(
446 WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const {
447 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteCSRCs()");
449 return _rtpReceiver.CSRCs(arrOfCSRC);
452 WebRtc_Word32 ModuleRtpRtcpImpl::SetRTXSendStatus(
453 const bool enable,
454 const bool setSSRC,
455 const WebRtc_UWord32 SSRC) {
456 _rtpSender.SetRTXStatus(enable, setSSRC, SSRC);
457 return 0;
460 WebRtc_Word32 ModuleRtpRtcpImpl::RTXSendStatus(bool* enable,
461 WebRtc_UWord32* SSRC) const {
462 _rtpSender.RTXStatus(enable, SSRC);
463 return 0;
466 WebRtc_Word32 ModuleRtpRtcpImpl::SetRTXReceiveStatus(
467 const bool enable,
468 const WebRtc_UWord32 SSRC) {
469 _rtpReceiver.SetRTXStatus(enable, SSRC);
470 return 0;
473 WebRtc_Word32 ModuleRtpRtcpImpl::RTXReceiveStatus(bool* enable,
474 WebRtc_UWord32* SSRC) const {
475 _rtpReceiver.RTXStatus(enable, SSRC);
476 return 0;
479 // called by the network module when we receive a packet
480 WebRtc_Word32 ModuleRtpRtcpImpl::IncomingPacket(
481 const WebRtc_UWord8* incomingPacket,
482 const WebRtc_UWord16 incomingPacketLength) {
483 WEBRTC_TRACE(kTraceStream,
484 kTraceRtpRtcp,
485 _id,
486 "IncomingPacket(packetLength:%u)",
487 incomingPacketLength);
488 // minimum RTP is 12 bytes
489 // minimum RTCP is 8 bytes (RTCP BYE)
490 if (incomingPacketLength < 8 || incomingPacket == NULL) {
491 WEBRTC_TRACE(kTraceDebug,
492 kTraceRtpRtcp,
493 _id,
494 "IncomingPacket invalid buffer or length");
495 return -1;
497 // check RTP version
498 const WebRtc_UWord8 version = incomingPacket[0] >> 6 ;
499 if (version != 2) {
500 WEBRTC_TRACE(kTraceDebug,
501 kTraceRtpRtcp,
502 _id,
503 "IncomingPacket invalid RTP version");
504 return -1;
507 ModuleRTPUtility::RTPHeaderParser rtpParser(incomingPacket,
508 incomingPacketLength);
510 if (rtpParser.RTCP()) {
511 // Allow receive of non-compound RTCP packets.
512 RTCPUtility::RTCPParserV2 rtcpParser(incomingPacket,
513 incomingPacketLength,
514 true);
516 const bool validRTCPHeader = rtcpParser.IsValid();
517 if (!validRTCPHeader) {
518 WEBRTC_TRACE(kTraceDebug,
519 kTraceRtpRtcp,
520 _id,
521 "IncomingPacket invalid RTCP packet");
522 return -1;
524 RTCPHelp::RTCPPacketInformation rtcpPacketInformation;
525 WebRtc_Word32 retVal = _rtcpReceiver.IncomingRTCPPacket(
526 rtcpPacketInformation,
527 &rtcpParser);
528 if (retVal == 0) {
529 _rtcpReceiver.TriggerCallbacksFromRTCPPacket(rtcpPacketInformation);
531 return retVal;
533 } else {
534 WebRtcRTPHeader rtpHeader;
535 memset(&rtpHeader, 0, sizeof(rtpHeader));
537 RtpHeaderExtensionMap map;
538 _rtpReceiver.GetHeaderExtensionMapCopy(&map);
540 const bool validRTPHeader = rtpParser.Parse(rtpHeader, &map);
541 if (!validRTPHeader) {
542 WEBRTC_TRACE(kTraceDebug,
543 kTraceRtpRtcp,
544 _id,
545 "IncomingPacket invalid RTP header");
546 return -1;
548 return _rtpReceiver.IncomingRTPPacket(&rtpHeader,
549 incomingPacket,
550 incomingPacketLength);
555 * Sender
558 WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSendPayload(
559 const CodecInst& voiceCodec) {
560 WEBRTC_TRACE(kTraceModuleCall,
561 kTraceRtpRtcp,
562 _id,
563 "RegisterSendPayload(plName:%s plType:%d frequency:%u)",
564 voiceCodec.plname,
565 voiceCodec.pltype,
566 voiceCodec.plfreq);
568 return _rtpSender.RegisterPayload(
569 voiceCodec.plname,
570 voiceCodec.pltype,
571 voiceCodec.plfreq,
572 voiceCodec.channels,
573 (voiceCodec.rate < 0) ? 0 : voiceCodec.rate);
576 WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSendPayload(
577 const VideoCodec& videoCodec) {
578 WEBRTC_TRACE(kTraceModuleCall,
579 kTraceRtpRtcp,
580 _id,
581 "RegisterSendPayload(plName:%s plType:%d)",
582 videoCodec.plName,
583 videoCodec.plType);
585 _sendVideoCodec = videoCodec;
586 _simulcast = (videoCodec.numberOfSimulcastStreams > 1) ? true : false;
587 return _rtpSender.RegisterPayload(videoCodec.plName,
588 videoCodec.plType,
589 90000,
591 videoCodec.maxBitrate);
594 WebRtc_Word32 ModuleRtpRtcpImpl::DeRegisterSendPayload(
595 const WebRtc_Word8 payloadType) {
596 WEBRTC_TRACE(kTraceModuleCall,
597 kTraceRtpRtcp,
598 _id,
599 "DeRegisterSendPayload(%d)", payloadType);
601 return _rtpSender.DeRegisterSendPayload(payloadType);
604 WebRtc_Word8 ModuleRtpRtcpImpl::SendPayloadType() const {
605 return _rtpSender.SendPayloadType();
608 WebRtc_UWord32 ModuleRtpRtcpImpl::StartTimestamp() const {
609 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "StartTimestamp()");
611 return _rtpSender.StartTimestamp();
614 // configure start timestamp, default is a random number
615 WebRtc_Word32 ModuleRtpRtcpImpl::SetStartTimestamp(
616 const WebRtc_UWord32 timestamp) {
617 WEBRTC_TRACE(kTraceModuleCall,
618 kTraceRtpRtcp,
619 _id,
620 "SetStartTimestamp(%d)",
621 timestamp);
623 return _rtpSender.SetStartTimestamp(timestamp, true);
626 WebRtc_UWord16 ModuleRtpRtcpImpl::SequenceNumber() const {
627 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SequenceNumber()");
629 return _rtpSender.SequenceNumber();
632 // Set SequenceNumber, default is a random number
633 WebRtc_Word32 ModuleRtpRtcpImpl::SetSequenceNumber(
634 const WebRtc_UWord16 seqNum) {
635 WEBRTC_TRACE(kTraceModuleCall,
636 kTraceRtpRtcp,
637 _id,
638 "SetSequenceNumber(%d)",
639 seqNum);
641 return _rtpSender.SetSequenceNumber(seqNum);
644 WebRtc_UWord32 ModuleRtpRtcpImpl::SSRC() const {
645 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SSRC()");
647 return _rtpSender.SSRC();
650 // configure SSRC, default is a random number
651 WebRtc_Word32 ModuleRtpRtcpImpl::SetSSRC(const WebRtc_UWord32 ssrc) {
652 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetSSRC(%d)", ssrc);
654 if (_rtpSender.SetSSRC(ssrc) == 0) {
655 _rtcpReceiver.SetSSRC(ssrc);
656 _rtcpSender.SetSSRC(ssrc);
657 return 0;
659 return -1;
662 WebRtc_Word32 ModuleRtpRtcpImpl::SetCSRCStatus(const bool include) {
663 _rtcpSender.SetCSRCStatus(include);
664 return _rtpSender.SetCSRCStatus(include);
667 WebRtc_Word32 ModuleRtpRtcpImpl::CSRCs(
668 WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize]) const {
669 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "CSRCs()");
671 return _rtpSender.CSRCs(arrOfCSRC);
674 WebRtc_Word32 ModuleRtpRtcpImpl::SetCSRCs(
675 const WebRtc_UWord32 arrOfCSRC[kRtpCsrcSize],
676 const WebRtc_UWord8 arrLength) {
677 WEBRTC_TRACE(kTraceModuleCall,
678 kTraceRtpRtcp,
679 _id,
680 "SetCSRCs(arrLength:%d)",
681 arrLength);
683 const bool defaultInstance(_childModules.empty() ? false : true);
685 if (defaultInstance) {
686 // for default we need to update all child modules too
687 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
689 std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
690 while (it != _childModules.end()) {
691 RtpRtcp* module = *it;
692 if (module) {
693 module->SetCSRCs(arrOfCSRC, arrLength);
695 it++;
697 return 0;
699 } else {
700 for (int i = 0; i < arrLength; i++) {
701 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "\tidx:%d CSRC:%u", i,
702 arrOfCSRC[i]);
704 _rtcpSender.SetCSRCs(arrOfCSRC, arrLength);
705 return _rtpSender.SetCSRCs(arrOfCSRC, arrLength);
709 WebRtc_UWord32 ModuleRtpRtcpImpl::PacketCountSent() const {
710 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "PacketCountSent()");
712 return _rtpSender.Packets();
715 WebRtc_UWord32 ModuleRtpRtcpImpl::ByteCountSent() const {
716 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ByteCountSent()");
718 return _rtpSender.Bytes();
721 int ModuleRtpRtcpImpl::CurrentSendFrequencyHz() const {
722 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
723 "CurrentSendFrequencyHz()");
725 return _rtpSender.SendPayloadFrequency();
728 WebRtc_Word32 ModuleRtpRtcpImpl::SetSendingStatus(const bool sending) {
729 if (sending) {
730 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
731 "SetSendingStatus(sending)");
732 } else {
733 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
734 "SetSendingStatus(stopped)");
736 if (_rtcpSender.Sending() != sending) {
737 // sends RTCP BYE when going from true to false
738 if (_rtcpSender.SetSendingStatus(sending) != 0) {
739 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
740 "Failed to send RTCP BYE");
743 _collisionDetected = false;
745 // generate a new timeStamp if true and not configured via API
746 // generate a new SSRC for the next "call" if false
747 _rtpSender.SetSendingStatus(sending);
749 // make sure that RTCP objects are aware of our SSRC (it could have changed
750 // due to collision)
751 WebRtc_UWord32 SSRC = _rtpSender.SSRC();
752 _rtcpReceiver.SetSSRC(SSRC);
753 _rtcpSender.SetSSRC(SSRC);
754 return 0;
756 return 0;
759 bool ModuleRtpRtcpImpl::Sending() const {
760 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "Sending()");
762 return _rtcpSender.Sending();
765 WebRtc_Word32 ModuleRtpRtcpImpl::SetSendingMediaStatus(const bool sending) {
766 if (sending) {
767 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
768 "SetSendingMediaStatus(sending)");
769 } else {
770 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
771 "SetSendingMediaStatus(stopped)");
773 _rtpSender.SetSendingMediaStatus(sending);
774 return 0;
777 bool ModuleRtpRtcpImpl::SendingMedia() const {
778 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "Sending()");
780 const bool haveChildModules(_childModules.empty() ? false : true);
781 if (!haveChildModules) {
782 return _rtpSender.SendingMedia();
785 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
786 std::list<ModuleRtpRtcpImpl*>::const_iterator it = _childModules.begin();
787 while (it != _childModules.end()) {
788 RTPSender& rtpSender = (*it)->_rtpSender;
789 if (rtpSender.SendingMedia()) {
790 return true;
792 it++;
794 return false;
797 WebRtc_Word32 ModuleRtpRtcpImpl::SendOutgoingData(
798 FrameType frameType,
799 WebRtc_Word8 payloadType,
800 WebRtc_UWord32 timeStamp,
801 int64_t capture_time_ms,
802 const WebRtc_UWord8* payloadData,
803 WebRtc_UWord32 payloadSize,
804 const RTPFragmentationHeader* fragmentation,
805 const RTPVideoHeader* rtpVideoHdr) {
806 WEBRTC_TRACE(
807 kTraceStream,
808 kTraceRtpRtcp,
809 _id,
810 "SendOutgoingData(frameType:%d payloadType:%d timeStamp:%u size:%u)",
811 frameType, payloadType, timeStamp, payloadSize);
813 const bool haveChildModules(_childModules.empty() ? false : true);
814 if (!haveChildModules) {
815 // Don't sent RTCP from default module
816 if (_rtcpSender.TimeToSendRTCPReport(kVideoFrameKey == frameType)) {
817 _rtcpSender.SendRTCP(kRtcpReport);
819 return _rtpSender.SendOutgoingData(frameType,
820 payloadType,
821 timeStamp,
822 capture_time_ms,
823 payloadData,
824 payloadSize,
825 fragmentation,
826 NULL,
827 &(rtpVideoHdr->codecHeader));
829 WebRtc_Word32 retVal = -1;
830 if (_simulcast) {
831 if (rtpVideoHdr == NULL) {
832 return -1;
834 int idx = 0;
835 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
836 std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
837 for (; idx < rtpVideoHdr->simulcastIdx; ++it) {
838 if (it == _childModules.end()) {
839 return -1;
841 if ((*it)->SendingMedia()) {
842 ++idx;
845 for (; it != _childModules.end(); ++it) {
846 if ((*it)->SendingMedia()) {
847 break;
849 ++idx;
851 if (it == _childModules.end()) {
852 return -1;
854 RTPSender& rtpSender = (*it)->_rtpSender;
855 WEBRTC_TRACE(kTraceModuleCall,
856 kTraceRtpRtcp,
857 _id,
858 "SendOutgoingData(SimulcastIdx:%u size:%u, ssrc:0x%x)",
859 idx, payloadSize, rtpSender.SSRC());
860 return rtpSender.SendOutgoingData(frameType,
861 payloadType,
862 timeStamp,
863 capture_time_ms,
864 payloadData,
865 payloadSize,
866 fragmentation,
867 NULL,
868 &(rtpVideoHdr->codecHeader));
869 } else {
870 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
871 // TODO(pwestin) remove codecInfo from SendOutgoingData
872 VideoCodecInformation* codecInfo = NULL;
874 std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
875 if (it != _childModules.end()) {
876 RTPSender& rtpSender = (*it)->_rtpSender;
877 retVal = rtpSender.SendOutgoingData(frameType,
878 payloadType,
879 timeStamp,
880 capture_time_ms,
881 payloadData,
882 payloadSize,
883 fragmentation,
884 NULL,
885 &(rtpVideoHdr->codecHeader));
887 it++;
890 // send to all remaining "child" modules
891 while (it != _childModules.end()) {
892 RTPSender& rtpSender = (*it)->_rtpSender;
893 retVal = rtpSender.SendOutgoingData(frameType,
894 payloadType,
895 timeStamp,
896 capture_time_ms,
897 payloadData,
898 payloadSize,
899 fragmentation,
900 codecInfo,
901 &(rtpVideoHdr->codecHeader));
903 it++;
906 return retVal;
909 WebRtc_UWord16 ModuleRtpRtcpImpl::MaxPayloadLength() const {
910 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "MaxPayloadLength()");
912 return _rtpSender.MaxPayloadLength();
915 WebRtc_UWord16 ModuleRtpRtcpImpl::MaxDataPayloadLength() const {
916 WEBRTC_TRACE(kTraceModuleCall,
917 kTraceRtpRtcp,
918 _id,
919 "MaxDataPayloadLength()");
921 WebRtc_UWord16 minDataPayloadLength = IP_PACKET_SIZE - 28; // Assuming IP/UDP
923 const bool defaultInstance(_childModules.empty() ? false : true);
924 if (defaultInstance) {
925 // for default we need to update all child modules too
926 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
927 std::list<ModuleRtpRtcpImpl*>::const_iterator it =
928 _childModules.begin();
929 while (it != _childModules.end()) {
930 RtpRtcp* module = *it;
931 if (module) {
932 WebRtc_UWord16 dataPayloadLength =
933 module->MaxDataPayloadLength();
934 if (dataPayloadLength < minDataPayloadLength) {
935 minDataPayloadLength = dataPayloadLength;
938 it++;
942 WebRtc_UWord16 dataPayloadLength = _rtpSender.MaxDataPayloadLength();
943 if (dataPayloadLength < minDataPayloadLength) {
944 minDataPayloadLength = dataPayloadLength;
946 return minDataPayloadLength;
949 WebRtc_Word32 ModuleRtpRtcpImpl::SetTransportOverhead(
950 const bool TCP,
951 const bool IPV6,
952 const WebRtc_UWord8 authenticationOverhead) {
953 WEBRTC_TRACE(
954 kTraceModuleCall,
955 kTraceRtpRtcp,
956 _id,
957 "SetTransportOverhead(TCP:%d, IPV6:%d authenticationOverhead:%u)",
958 TCP, IPV6, authenticationOverhead);
960 WebRtc_UWord16 packetOverHead = 0;
961 if (IPV6) {
962 packetOverHead = 40;
963 } else {
964 packetOverHead = 20;
966 if (TCP) {
967 // TCP
968 packetOverHead += 20;
969 } else {
970 // UDP
971 packetOverHead += 8;
973 packetOverHead += authenticationOverhead;
975 if (packetOverHead == _packetOverHead) {
976 // ok same as before
977 return 0;
979 // calc diff
980 WebRtc_Word16 packetOverHeadDiff = packetOverHead - _packetOverHead;
982 // store new
983 _packetOverHead = packetOverHead;
985 _rtpReceiver.SetPacketOverHead(_packetOverHead);
986 WebRtc_UWord16 length = _rtpSender.MaxPayloadLength() - packetOverHeadDiff;
987 return _rtpSender.SetMaxPayloadLength(length, _packetOverHead);
990 WebRtc_Word32 ModuleRtpRtcpImpl::SetMaxTransferUnit(const WebRtc_UWord16 MTU) {
991 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetMaxTransferUnit(%u)",
992 MTU);
994 if (MTU > IP_PACKET_SIZE) {
995 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
996 "Invalid in argument to SetMaxTransferUnit(%u)", MTU);
997 return -1;
999 return _rtpSender.SetMaxPayloadLength(MTU - _packetOverHead,
1000 _packetOverHead);
1004 * RTCP
1006 RTCPMethod ModuleRtpRtcpImpl::RTCP() const {
1007 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RTCP()");
1009 if (_rtcpSender.Status() != kRtcpOff) {
1010 return _rtcpReceiver.Status();
1012 return kRtcpOff;
1015 // configure RTCP status i.e on/off
1016 WebRtc_Word32 ModuleRtpRtcpImpl::SetRTCPStatus(const RTCPMethod method) {
1017 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetRTCPStatus(%d)",
1018 method);
1020 if (_rtcpSender.SetRTCPStatus(method) == 0) {
1021 return _rtcpReceiver.SetRTCPStatus(method);
1023 return -1;
1026 // only for internal test
1027 WebRtc_UWord32 ModuleRtpRtcpImpl::LastSendReport(WebRtc_UWord32& lastRTCPTime) {
1028 return _rtcpSender.LastSendReport(lastRTCPTime);
1031 WebRtc_Word32 ModuleRtpRtcpImpl::SetCNAME(const char cName[RTCP_CNAME_SIZE]) {
1032 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetCNAME(%s)", cName);
1033 return _rtcpSender.SetCNAME(cName);
1036 WebRtc_Word32 ModuleRtpRtcpImpl::CNAME(char cName[RTCP_CNAME_SIZE]) {
1037 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "CNAME()");
1038 return _rtcpSender.CNAME(cName);
1041 WebRtc_Word32 ModuleRtpRtcpImpl::AddMixedCNAME(
1042 const WebRtc_UWord32 SSRC,
1043 const char cName[RTCP_CNAME_SIZE]) {
1044 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1045 "AddMixedCNAME(SSRC:%u)", SSRC);
1047 return _rtcpSender.AddMixedCNAME(SSRC, cName);
1050 WebRtc_Word32 ModuleRtpRtcpImpl::RemoveMixedCNAME(const WebRtc_UWord32 SSRC) {
1051 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1052 "RemoveMixedCNAME(SSRC:%u)", SSRC);
1053 return _rtcpSender.RemoveMixedCNAME(SSRC);
1056 WebRtc_Word32 ModuleRtpRtcpImpl::RemoteCNAME(
1057 const WebRtc_UWord32 remoteSSRC,
1058 char cName[RTCP_CNAME_SIZE]) const {
1059 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1060 "RemoteCNAME(SSRC:%u)", remoteSSRC);
1062 return _rtcpReceiver.CNAME(remoteSSRC, cName);
1065 WebRtc_UWord16 ModuleRtpRtcpImpl::RemoteSequenceNumber() const {
1066 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteSequenceNumber()");
1068 return _rtpReceiver.SequenceNumber();
1071 WebRtc_Word32 ModuleRtpRtcpImpl::RemoteNTP(
1072 WebRtc_UWord32* receivedNTPsecs,
1073 WebRtc_UWord32* receivedNTPfrac,
1074 WebRtc_UWord32* RTCPArrivalTimeSecs,
1075 WebRtc_UWord32* RTCPArrivalTimeFrac) const {
1076 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteNTP()");
1078 return _rtcpReceiver.NTP(receivedNTPsecs,
1079 receivedNTPfrac,
1080 RTCPArrivalTimeSecs,
1081 RTCPArrivalTimeFrac);
1084 // Get RoundTripTime
1085 WebRtc_Word32 ModuleRtpRtcpImpl::RTT(const WebRtc_UWord32 remoteSSRC,
1086 WebRtc_UWord16* RTT,
1087 WebRtc_UWord16* avgRTT,
1088 WebRtc_UWord16* minRTT,
1089 WebRtc_UWord16* maxRTT) const {
1090 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RTT()");
1092 return _rtcpReceiver.RTT(remoteSSRC, RTT, avgRTT, minRTT, maxRTT);
1095 // Reset RoundTripTime statistics
1096 WebRtc_Word32
1097 ModuleRtpRtcpImpl::ResetRTT(const WebRtc_UWord32 remoteSSRC) {
1098 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ResetRTT(SSRC:%u)",
1099 remoteSSRC);
1101 return _rtcpReceiver.ResetRTT(remoteSSRC);
1104 // Reset RTP statistics
1105 WebRtc_Word32
1106 ModuleRtpRtcpImpl::ResetStatisticsRTP() {
1107 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ResetStatisticsRTP()");
1109 return _rtpReceiver.ResetStatistics();
1112 // Reset RTP data counters for the receiving side
1113 WebRtc_Word32 ModuleRtpRtcpImpl::ResetReceiveDataCountersRTP() {
1114 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1115 "ResetReceiveDataCountersRTP()");
1117 return _rtpReceiver.ResetDataCounters();
1120 // Reset RTP data counters for the sending side
1121 WebRtc_Word32 ModuleRtpRtcpImpl::ResetSendDataCountersRTP() {
1122 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1123 "ResetSendDataCountersRTP()");
1125 return _rtpSender.ResetDataCounters();
1128 // Force a send of an RTCP packet
1129 // normal SR and RR are triggered via the process function
1130 WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCP(WebRtc_UWord32 rtcpPacketType) {
1131 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SendRTCP(0x%x)",
1132 rtcpPacketType);
1134 return _rtcpSender.SendRTCP(rtcpPacketType);
1137 WebRtc_Word32 ModuleRtpRtcpImpl::SetRTCPApplicationSpecificData(
1138 const WebRtc_UWord8 subType,
1139 const WebRtc_UWord32 name,
1140 const WebRtc_UWord8* data,
1141 const WebRtc_UWord16 length) {
1142 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1143 "SetRTCPApplicationSpecificData(subType:%d name:0x%x)", subType,
1144 name);
1146 return _rtcpSender.SetApplicationSpecificData(subType, name, data, length);
1150 * (XR) VOIP metric
1152 WebRtc_Word32 ModuleRtpRtcpImpl::SetRTCPVoIPMetrics(
1153 const RTCPVoIPMetric* VoIPMetric) {
1154 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetRTCPVoIPMetrics()");
1156 return _rtcpSender.SetRTCPVoIPMetrics(VoIPMetric);
1159 // our localy created statistics of the received RTP stream
1160 WebRtc_Word32 ModuleRtpRtcpImpl::StatisticsRTP(
1161 WebRtc_UWord8* fraction_lost,
1162 WebRtc_UWord32* cum_lost,
1163 WebRtc_UWord32* ext_max,
1164 WebRtc_UWord32* jitter,
1165 WebRtc_UWord32* max_jitter) const {
1166 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "StatisticsRTP()");
1168 WebRtc_UWord32 jitter_transmission_time_offset = 0;
1170 WebRtc_Word32 retVal = _rtpReceiver.Statistics(
1171 fraction_lost,
1172 cum_lost,
1173 ext_max,
1174 jitter,
1175 max_jitter,
1176 &jitter_transmission_time_offset,
1177 (_rtcpSender.Status() == kRtcpOff));
1178 if (retVal == -1) {
1179 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1180 "StatisticsRTP() no statisitics availble");
1182 return retVal;
1185 WebRtc_Word32 ModuleRtpRtcpImpl::DataCountersRTP(
1186 WebRtc_UWord32* bytesSent,
1187 WebRtc_UWord32* packetsSent,
1188 WebRtc_UWord32* bytesReceived,
1189 WebRtc_UWord32* packetsReceived) const {
1190 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id, "DataCountersRTP()");
1192 if (bytesSent) {
1193 *bytesSent = _rtpSender.Bytes();
1195 if (packetsSent) {
1196 *packetsSent = _rtpSender.Packets();
1198 return _rtpReceiver.DataCounters(bytesReceived, packetsReceived);
1201 WebRtc_Word32 ModuleRtpRtcpImpl::ReportBlockStatistics(
1202 WebRtc_UWord8* fraction_lost,
1203 WebRtc_UWord32* cum_lost,
1204 WebRtc_UWord32* ext_max,
1205 WebRtc_UWord32* jitter,
1206 WebRtc_UWord32* jitter_transmission_time_offset) {
1207 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "ReportBlockStatistics()");
1208 WebRtc_Word32 missing = 0;
1209 WebRtc_Word32 ret = _rtpReceiver.Statistics(fraction_lost,
1210 cum_lost,
1211 ext_max,
1212 jitter,
1213 NULL,
1214 jitter_transmission_time_offset,
1215 &missing,
1216 true);
1218 #ifdef MATLAB
1219 if (_plot1 == NULL) {
1220 _plot1 = eng.NewPlot(new MatlabPlot());
1221 _plot1->AddTimeLine(30, "b", "lost", _clock.GetTimeInMS());
1223 _plot1->Append("lost", missing);
1224 _plot1->Plot();
1225 #endif
1227 return ret;
1230 WebRtc_Word32 ModuleRtpRtcpImpl::RemoteRTCPStat(RTCPSenderInfo* senderInfo) {
1231 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteRTCPStat()");
1233 return _rtcpReceiver.SenderInfoReceived(senderInfo);
1236 // received RTCP report
1237 WebRtc_Word32 ModuleRtpRtcpImpl::RemoteRTCPStat(
1238 std::vector<RTCPReportBlock>* receiveBlocks) const {
1239 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoteRTCPStat()");
1241 return _rtcpReceiver.StatisticsReceived(receiveBlocks);
1244 WebRtc_Word32 ModuleRtpRtcpImpl::AddRTCPReportBlock(
1245 const WebRtc_UWord32 SSRC,
1246 const RTCPReportBlock* reportBlock) {
1247 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "AddRTCPReportBlock()");
1249 return _rtcpSender.AddReportBlock(SSRC, reportBlock);
1252 WebRtc_Word32 ModuleRtpRtcpImpl::RemoveRTCPReportBlock(
1253 const WebRtc_UWord32 SSRC) {
1254 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "RemoveRTCPReportBlock()");
1256 return _rtcpSender.RemoveReportBlock(SSRC);
1260 * (REMB) Receiver Estimated Max Bitrate
1262 bool ModuleRtpRtcpImpl::REMB() const {
1263 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "REMB()");
1265 return _rtcpSender.REMB();
1268 WebRtc_Word32 ModuleRtpRtcpImpl::SetREMBStatus(const bool enable) {
1269 if (enable) {
1270 WEBRTC_TRACE(kTraceModuleCall,
1271 kTraceRtpRtcp,
1272 _id,
1273 "SetREMBStatus(enable)");
1274 } else {
1275 WEBRTC_TRACE(kTraceModuleCall,
1276 kTraceRtpRtcp,
1277 _id,
1278 "SetREMBStatus(disable)");
1280 return _rtcpSender.SetREMBStatus(enable);
1283 WebRtc_Word32 ModuleRtpRtcpImpl::SetREMBData(const WebRtc_UWord32 bitrate,
1284 const WebRtc_UWord8 numberOfSSRC,
1285 const WebRtc_UWord32* SSRC) {
1286 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1287 "SetREMBData(bitrate:%d,?,?)", bitrate);
1288 return _rtcpSender.SetREMBData(bitrate, numberOfSSRC, SSRC);
1292 * (IJ) Extended jitter report.
1294 bool ModuleRtpRtcpImpl::IJ() const {
1295 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "IJ()");
1297 return _rtcpSender.IJ();
1300 WebRtc_Word32 ModuleRtpRtcpImpl::SetIJStatus(const bool enable) {
1301 WEBRTC_TRACE(kTraceModuleCall,
1302 kTraceRtpRtcp,
1303 _id,
1304 "SetIJStatus(%s)", enable ? "true" : "false");
1306 return _rtcpSender.SetIJStatus(enable);
1309 WebRtc_Word32 ModuleRtpRtcpImpl::RegisterSendRtpHeaderExtension(
1310 const RTPExtensionType type,
1311 const WebRtc_UWord8 id) {
1312 return _rtpSender.RegisterRtpHeaderExtension(type, id);
1315 WebRtc_Word32 ModuleRtpRtcpImpl::DeregisterSendRtpHeaderExtension(
1316 const RTPExtensionType type) {
1317 return _rtpSender.DeregisterRtpHeaderExtension(type);
1320 WebRtc_Word32 ModuleRtpRtcpImpl::RegisterReceiveRtpHeaderExtension(
1321 const RTPExtensionType type,
1322 const WebRtc_UWord8 id) {
1323 return _rtpReceiver.RegisterRtpHeaderExtension(type, id);
1326 WebRtc_Word32 ModuleRtpRtcpImpl::DeregisterReceiveRtpHeaderExtension(
1327 const RTPExtensionType type) {
1328 return _rtpReceiver.DeregisterRtpHeaderExtension(type);
1331 void ModuleRtpRtcpImpl::SetTransmissionSmoothingStatus(const bool enable) {
1332 _rtpSender.SetTransmissionSmoothingStatus(enable);
1335 bool ModuleRtpRtcpImpl::TransmissionSmoothingStatus() const {
1336 return _rtpSender.TransmissionSmoothingStatus();
1340 * (TMMBR) Temporary Max Media Bit Rate
1342 bool ModuleRtpRtcpImpl::TMMBR() const {
1343 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "TMMBR()");
1345 return _rtcpSender.TMMBR();
1348 WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBRStatus(const bool enable) {
1349 if (enable) {
1350 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1351 "SetTMMBRStatus(enable)");
1352 } else {
1353 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1354 "SetTMMBRStatus(disable)");
1356 return _rtcpSender.SetTMMBRStatus(enable);
1359 WebRtc_Word32 ModuleRtpRtcpImpl::SetTMMBN(const TMMBRSet* boundingSet) {
1360 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SetTMMBN()");
1362 WebRtc_UWord32 maxBitrateKbit = _rtpSender.MaxConfiguredBitrateVideo() / 1000;
1363 return _rtcpSender.SetTMMBN(boundingSet, maxBitrateKbit);
1367 * (NACK) Negative acknowledgement
1370 // Is Negative acknowledgement requests on/off?
1371 NACKMethod ModuleRtpRtcpImpl::NACK() const {
1372 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "NACK()");
1374 NACKMethod childMethod = kNackOff;
1375 const bool defaultInstance(_childModules.empty() ? false : true);
1376 if (defaultInstance) {
1377 // for default we need to check all child modules too
1378 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1379 std::list<ModuleRtpRtcpImpl*>::const_iterator it =
1380 _childModules.begin();
1381 while (it != _childModules.end()) {
1382 RtpRtcp* module = *it;
1383 if (module) {
1384 NACKMethod nackMethod = module->NACK();
1385 if (nackMethod != kNackOff) {
1386 childMethod = nackMethod;
1387 break;
1390 it++;
1394 NACKMethod method = _nackMethod;
1395 if (childMethod != kNackOff) {
1396 method = childMethod;
1398 return method;
1401 // Turn negative acknowledgement requests on/off
1402 WebRtc_Word32 ModuleRtpRtcpImpl::SetNACKStatus(NACKMethod method) {
1403 WEBRTC_TRACE(kTraceModuleCall,
1404 kTraceRtpRtcp,
1405 _id,
1406 "SetNACKStatus(%u)", method);
1408 _nackMethod = method;
1409 _rtpReceiver.SetNACKStatus(method);
1410 return 0;
1413 // Returns the currently configured retransmission mode.
1414 int ModuleRtpRtcpImpl::SelectiveRetransmissions() const {
1415 WEBRTC_TRACE(kTraceModuleCall,
1416 kTraceRtpRtcp,
1417 _id,
1418 "SelectiveRetransmissions()");
1419 return _rtpSender.SelectiveRetransmissions();
1422 // Enable or disable a retransmission mode, which decides which packets will
1423 // be retransmitted if NACKed.
1424 int ModuleRtpRtcpImpl::SetSelectiveRetransmissions(uint8_t settings) {
1425 WEBRTC_TRACE(kTraceModuleCall,
1426 kTraceRtpRtcp,
1427 _id,
1428 "SetSelectiveRetransmissions(%u)",
1429 settings);
1430 return _rtpSender.SetSelectiveRetransmissions(settings);
1433 // Send a Negative acknowledgement packet
1434 WebRtc_Word32 ModuleRtpRtcpImpl::SendNACK(const WebRtc_UWord16* nackList,
1435 const WebRtc_UWord16 size) {
1436 WEBRTC_TRACE(kTraceModuleCall,
1437 kTraceRtpRtcp,
1438 _id,
1439 "SendNACK(size:%u)", size);
1441 if (size > NACK_PACKETS_MAX_SIZE) {
1442 RequestKeyFrame();
1443 return -1;
1445 WebRtc_UWord16 avgRTT = 0;
1446 _rtcpReceiver.RTT(_rtpReceiver.SSRC(), NULL, &avgRTT, NULL, NULL);
1448 WebRtc_Word64 waitTime = 5 + ((avgRTT * 3) >> 1); // 5 + RTT*1.5
1449 if (waitTime == 5) {
1450 waitTime = 100; // During startup we don't have an RTT
1452 const WebRtc_Word64 now = _clock.GetTimeInMS();
1453 const WebRtc_Word64 timeLimit = now - waitTime;
1455 if (_nackLastTimeSent < timeLimit) {
1456 // send list
1457 } else {
1458 // only send if extended list
1459 if (_nackLastSeqNumberSent == nackList[size - 1]) {
1460 // last seq num is the same don't send list
1461 return 0;
1462 } else {
1463 // send list
1466 _nackLastTimeSent = now;
1467 _nackLastSeqNumberSent = nackList[size - 1];
1469 switch (_nackMethod) {
1470 case kNackRtcp:
1471 return _rtcpSender.SendRTCP(kRtcpNack, size, nackList);
1472 case kNackOff:
1473 return -1;
1475 return -1;
1478 // Store the sent packets, needed to answer to a Negative acknowledgement
1479 // requests
1480 WebRtc_Word32 ModuleRtpRtcpImpl::SetStorePacketsStatus(
1481 const bool enable,
1482 const WebRtc_UWord16 numberToStore) {
1483 if (enable) {
1484 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1485 "SetStorePacketsStatus(enable, numberToStore:%d)",
1486 numberToStore);
1487 } else {
1488 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1489 "SetStorePacketsStatus(disable)");
1491 return _rtpSender.SetStorePacketsStatus(enable, numberToStore);
1495 * Audio
1498 // Outband TelephoneEvent detection
1499 WebRtc_Word32 ModuleRtpRtcpImpl::SetTelephoneEventStatus(
1500 const bool enable,
1501 const bool forwardToDecoder,
1502 const bool detectEndOfTone) {
1503 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1504 "SetTelephoneEventStatus(enable:%d forwardToDecoder:%d"
1505 " detectEndOfTone:%d)", enable, forwardToDecoder,
1506 detectEndOfTone);
1508 return _rtpReceiver.SetTelephoneEventStatus(enable, forwardToDecoder,
1509 detectEndOfTone);
1512 // Is outband TelephoneEvent turned on/off?
1513 bool ModuleRtpRtcpImpl::TelephoneEvent() const {
1514 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "TelephoneEvent()");
1516 return _rtpReceiver.TelephoneEvent();
1519 // Is forwarding of outband telephone events turned on/off?
1520 bool ModuleRtpRtcpImpl::TelephoneEventForwardToDecoder() const {
1521 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1522 "TelephoneEventForwardToDecoder()");
1524 return _rtpReceiver.TelephoneEventForwardToDecoder();
1527 // Send a TelephoneEvent tone using RFC 2833 (4733)
1528 WebRtc_Word32 ModuleRtpRtcpImpl::SendTelephoneEventOutband(
1529 const WebRtc_UWord8 key,
1530 const WebRtc_UWord16 timeMs,
1531 const WebRtc_UWord8 level) {
1532 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1533 "SendTelephoneEventOutband(key:%u, timeMs:%u, level:%u)", key,
1534 timeMs, level);
1536 return _rtpSender.SendTelephoneEvent(key, timeMs, level);
1539 bool ModuleRtpRtcpImpl::SendTelephoneEventActive(
1540 WebRtc_Word8& telephoneEvent) const {
1542 WEBRTC_TRACE(kTraceModuleCall,
1543 kTraceRtpRtcp,
1544 _id,
1545 "SendTelephoneEventActive()");
1547 return _rtpSender.SendTelephoneEventActive(telephoneEvent);
1550 // set audio packet size, used to determine when it's time to send a DTMF
1551 // packet in silence (CNG)
1552 WebRtc_Word32 ModuleRtpRtcpImpl::SetAudioPacketSize(
1553 const WebRtc_UWord16 packetSizeSamples) {
1555 WEBRTC_TRACE(kTraceModuleCall,
1556 kTraceRtpRtcp,
1557 _id,
1558 "SetAudioPacketSize(%u)",
1559 packetSizeSamples);
1561 return _rtpSender.SetAudioPacketSize(packetSizeSamples);
1564 WebRtc_Word32 ModuleRtpRtcpImpl::SetRTPAudioLevelIndicationStatus(
1565 const bool enable,
1566 const WebRtc_UWord8 ID) {
1568 WEBRTC_TRACE(kTraceModuleCall,
1569 kTraceRtpRtcp,
1570 _id,
1571 "SetRTPAudioLevelIndicationStatus(enable=%d, ID=%u)",
1572 enable,
1573 ID);
1575 if (enable) {
1576 _rtpReceiver.RegisterRtpHeaderExtension(kRtpExtensionAudioLevel, ID);
1577 } else {
1578 _rtpReceiver.DeregisterRtpHeaderExtension(kRtpExtensionAudioLevel);
1580 return _rtpSender.SetAudioLevelIndicationStatus(enable, ID);
1583 WebRtc_Word32 ModuleRtpRtcpImpl::GetRTPAudioLevelIndicationStatus(
1584 bool& enable,
1585 WebRtc_UWord8& ID) const {
1587 WEBRTC_TRACE(kTraceModuleCall,
1588 kTraceRtpRtcp,
1589 _id,
1590 "GetRTPAudioLevelIndicationStatus()");
1591 return _rtpSender.AudioLevelIndicationStatus(enable, ID);
1594 WebRtc_Word32 ModuleRtpRtcpImpl::SetAudioLevel(const WebRtc_UWord8 level_dBov) {
1595 WEBRTC_TRACE(kTraceModuleCall,
1596 kTraceRtpRtcp,
1597 _id,
1598 "SetAudioLevel(level_dBov:%u)",
1599 level_dBov);
1600 return _rtpSender.SetAudioLevel(level_dBov);
1603 // Set payload type for Redundant Audio Data RFC 2198
1604 WebRtc_Word32 ModuleRtpRtcpImpl::SetSendREDPayloadType(
1605 const WebRtc_Word8 payloadType) {
1606 WEBRTC_TRACE(kTraceModuleCall,
1607 kTraceRtpRtcp,
1608 _id,
1609 "SetSendREDPayloadType(%d)",
1610 payloadType);
1612 return _rtpSender.SetRED(payloadType);
1615 // Get payload type for Redundant Audio Data RFC 2198
1616 WebRtc_Word32 ModuleRtpRtcpImpl::SendREDPayloadType(
1617 WebRtc_Word8& payloadType) const {
1618 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "SendREDPayloadType()");
1620 return _rtpSender.RED(payloadType);
1625 * Video
1627 RtpVideoCodecTypes ModuleRtpRtcpImpl::ReceivedVideoCodec() const {
1628 return _rtpReceiver.VideoCodecType();
1631 RtpVideoCodecTypes ModuleRtpRtcpImpl::SendVideoCodec() const {
1632 return _rtpSender.VideoCodecType();
1635 void ModuleRtpRtcpImpl::SetTargetSendBitrate(const uint32_t bitrate) {
1636 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id,
1637 "SetTargetSendBitrate: %ubit", bitrate);
1639 const bool haveChildModules(_childModules.empty() ? false : true);
1640 if (haveChildModules) {
1641 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1642 if (_simulcast) {
1643 uint32_t bitrate_remainder = bitrate;
1644 std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1645 for (int i = 0; it != _childModules.end() &&
1646 i < _sendVideoCodec.numberOfSimulcastStreams; ++it) {
1647 if ((*it)->SendingMedia()) {
1648 RTPSender& rtpSender = (*it)->_rtpSender;
1649 if (_sendVideoCodec.simulcastStream[i].maxBitrate * 1000 >
1650 bitrate_remainder) {
1651 rtpSender.SetTargetSendBitrate(bitrate_remainder);
1652 bitrate_remainder = 0;
1653 } else {
1654 rtpSender.SetTargetSendBitrate(
1655 _sendVideoCodec.simulcastStream[i].maxBitrate * 1000);
1656 bitrate_remainder -=
1657 _sendVideoCodec.simulcastStream[i].maxBitrate * 1000;
1659 ++i;
1662 } else {
1663 std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1664 for (; it != _childModules.end(); ++it) {
1665 RTPSender& rtpSender = (*it)->_rtpSender;
1666 rtpSender.SetTargetSendBitrate(bitrate);
1669 } else {
1670 _rtpSender.SetTargetSendBitrate(bitrate);
1674 WebRtc_Word32 ModuleRtpRtcpImpl::SetKeyFrameRequestMethod(
1675 const KeyFrameRequestMethod method) {
1676 WEBRTC_TRACE(kTraceModuleCall,
1677 kTraceRtpRtcp,
1678 _id,
1679 "SetKeyFrameRequestMethod(method:%u)",
1680 method);
1682 _keyFrameReqMethod = method;
1683 return 0;
1686 WebRtc_Word32 ModuleRtpRtcpImpl::RequestKeyFrame() {
1687 WEBRTC_TRACE(kTraceModuleCall,
1688 kTraceRtpRtcp,
1689 _id,
1690 "RequestKeyFrame");
1692 switch (_keyFrameReqMethod) {
1693 case kKeyFrameReqFirRtp:
1694 return _rtpSender.SendRTPIntraRequest();
1695 case kKeyFrameReqPliRtcp:
1696 return _rtcpSender.SendRTCP(kRtcpPli);
1697 case kKeyFrameReqFirRtcp:
1698 return _rtcpSender.SendRTCP(kRtcpFir);
1700 return -1;
1703 WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCPSliceLossIndication(
1704 const WebRtc_UWord8 pictureID) {
1705 WEBRTC_TRACE(kTraceModuleCall,
1706 kTraceRtpRtcp,
1707 _id,
1708 "SendRTCPSliceLossIndication (pictureID:%d)",
1709 pictureID);
1710 return _rtcpSender.SendRTCP(kRtcpSli, 0, 0, false, pictureID);
1713 WebRtc_Word32 ModuleRtpRtcpImpl::SetCameraDelay(const WebRtc_Word32 delayMS) {
1714 WEBRTC_TRACE(kTraceModuleCall,
1715 kTraceRtpRtcp,
1716 _id,
1717 "SetCameraDelay(%d)",
1718 delayMS);
1719 const bool defaultInstance(_childModules.empty() ? false : true);
1721 if (defaultInstance) {
1722 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1724 std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1725 while (it != _childModules.end()) {
1726 RtpRtcp* module = *it;
1727 if (module) {
1728 module->SetCameraDelay(delayMS);
1730 it++;
1732 return 0;
1734 return _rtcpSender.SetCameraDelay(delayMS);
1737 WebRtc_Word32 ModuleRtpRtcpImpl::SetGenericFECStatus(
1738 const bool enable,
1739 const WebRtc_UWord8 payloadTypeRED,
1740 const WebRtc_UWord8 payloadTypeFEC) {
1741 if (enable) {
1742 WEBRTC_TRACE(kTraceModuleCall,
1743 kTraceRtpRtcp,
1744 _id,
1745 "SetGenericFECStatus(enable, %u)",
1746 payloadTypeRED);
1747 } else {
1748 WEBRTC_TRACE(kTraceModuleCall,
1749 kTraceRtpRtcp,
1750 _id,
1751 "SetGenericFECStatus(disable)");
1753 return _rtpSender.SetGenericFECStatus(enable,
1754 payloadTypeRED,
1755 payloadTypeFEC);
1758 WebRtc_Word32 ModuleRtpRtcpImpl::GenericFECStatus(
1759 bool& enable,
1760 WebRtc_UWord8& payloadTypeRED,
1761 WebRtc_UWord8& payloadTypeFEC) {
1763 WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, _id, "GenericFECStatus()");
1765 bool childEnabled = false;
1766 const bool defaultInstance(_childModules.empty() ? false : true);
1767 if (defaultInstance) {
1768 // for default we need to check all child modules too
1769 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1770 std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1771 while (it != _childModules.end()) {
1772 RtpRtcp* module = *it;
1773 if (module) {
1774 bool enabled = false;
1775 WebRtc_UWord8 dummyPTypeRED = 0;
1776 WebRtc_UWord8 dummyPTypeFEC = 0;
1777 if (module->GenericFECStatus(enabled,
1778 dummyPTypeRED,
1779 dummyPTypeFEC) == 0 && enabled) {
1780 childEnabled = true;
1781 break;
1784 it++;
1787 WebRtc_Word32 retVal = _rtpSender.GenericFECStatus(enable,
1788 payloadTypeRED,
1789 payloadTypeFEC);
1790 if (childEnabled) {
1791 // returns true if enabled for any child module
1792 enable = childEnabled;
1794 return retVal;
1797 WebRtc_Word32 ModuleRtpRtcpImpl::SetFecParameters(
1798 const FecProtectionParams* delta_params,
1799 const FecProtectionParams* key_params) {
1800 const bool defaultInstance(_childModules.empty() ? false : true);
1801 if (defaultInstance) {
1802 // for default we need to update all child modules too
1803 CriticalSectionScoped lock(_criticalSectionModulePtrs.get());
1805 std::list<ModuleRtpRtcpImpl*>::iterator it = _childModules.begin();
1806 while (it != _childModules.end()) {
1807 RtpRtcp* module = *it;
1808 if (module) {
1809 module->SetFecParameters(delta_params, key_params);
1811 it++;
1813 return 0;
1815 return _rtpSender.SetFecParameters(delta_params, key_params);
1818 void ModuleRtpRtcpImpl::SetRemoteSSRC(const WebRtc_UWord32 SSRC) {
1819 // inform about the incoming SSRC
1820 _rtcpSender.SetRemoteSSRC(SSRC);
1821 _rtcpReceiver.SetRemoteSSRC(SSRC);
1823 // check for a SSRC collision
1824 if (_rtpSender.SSRC() == SSRC && !_collisionDetected) {
1825 // if we detect a collision change the SSRC but only once
1826 _collisionDetected = true;
1827 WebRtc_UWord32 newSSRC = _rtpSender.GenerateNewSSRC();
1828 if (newSSRC == 0) {
1829 // configured via API ignore
1830 return;
1832 if (kRtcpOff != _rtcpSender.Status()) {
1833 // send RTCP bye on the current SSRC
1834 _rtcpSender.SendRTCP(kRtcpBye);
1836 // change local SSRC
1838 // inform all objects about the new SSRC
1839 _rtcpSender.SetSSRC(newSSRC);
1840 _rtcpReceiver.SetSSRC(newSSRC);
1844 WebRtc_UWord32 ModuleRtpRtcpImpl::BitrateReceivedNow() const {
1845 return _rtpReceiver.BitrateNow();
1848 void ModuleRtpRtcpImpl::BitrateSent(WebRtc_UWord32* totalRate,
1849 WebRtc_UWord32* videoRate,
1850 WebRtc_UWord32* fecRate,
1851 WebRtc_UWord32* nackRate) const {
1852 const bool defaultInstance(_childModules.empty() ? false : true);
1854 if (defaultInstance) {
1855 // for default we need to update the send bitrate
1856 CriticalSectionScoped lock(_criticalSectionModulePtrsFeedback.get());
1858 if (totalRate != NULL)
1859 *totalRate = 0;
1860 if (videoRate != NULL)
1861 *videoRate = 0;
1862 if (fecRate != NULL)
1863 *fecRate = 0;
1864 if (nackRate != NULL)
1865 *nackRate = 0;
1867 std::list<ModuleRtpRtcpImpl*>::const_iterator it =
1868 _childModules.begin();
1869 while (it != _childModules.end()) {
1870 RtpRtcp* module = *it;
1871 if (module) {
1872 WebRtc_UWord32 childTotalRate = 0;
1873 WebRtc_UWord32 childVideoRate = 0;
1874 WebRtc_UWord32 childFecRate = 0;
1875 WebRtc_UWord32 childNackRate = 0;
1876 module->BitrateSent(&childTotalRate,
1877 &childVideoRate,
1878 &childFecRate,
1879 &childNackRate);
1880 if (totalRate != NULL && childTotalRate > *totalRate)
1881 *totalRate = childTotalRate;
1882 if (videoRate != NULL && childVideoRate > *videoRate)
1883 *videoRate = childVideoRate;
1884 if (fecRate != NULL && childFecRate > *fecRate)
1885 *fecRate = childFecRate;
1886 if (nackRate != NULL && childNackRate > *nackRate)
1887 *nackRate = childNackRate;
1889 it++;
1891 return;
1893 if (totalRate != NULL)
1894 *totalRate = _rtpSender.BitrateLast();
1895 if (videoRate != NULL)
1896 *videoRate = _rtpSender.VideoBitrateSent();
1897 if (fecRate != NULL)
1898 *fecRate = _rtpSender.FecOverheadRate();
1899 if (nackRate != NULL)
1900 *nackRate = _rtpSender.NackOverheadRate();
1903 int ModuleRtpRtcpImpl::EstimatedReceiveBandwidth(
1904 WebRtc_UWord32* available_bandwidth) const {
1905 if (remote_bitrate_) {
1906 if (!remote_bitrate_->LatestEstimate(_rtpReceiver.SSRC(),
1907 available_bandwidth)) {
1908 return -1;
1910 return 0;
1912 // No bandwidth receive-side bandwidth estimation is connected to this module.
1913 return -1;
1916 // bad state of RTP receiver request a keyframe
1917 void ModuleRtpRtcpImpl::OnRequestIntraFrame() {
1918 RequestKeyFrame();
1921 void ModuleRtpRtcpImpl::OnRequestSendReport() {
1922 _rtcpSender.SendRTCP(kRtcpSr);
1925 WebRtc_Word32 ModuleRtpRtcpImpl::SendRTCPReferencePictureSelection(
1926 const WebRtc_UWord64 pictureID) {
1927 return _rtcpSender.SendRTCP(kRtcpRpsi, 0, 0, false, pictureID);
1930 WebRtc_UWord32 ModuleRtpRtcpImpl::SendTimeOfSendReport(
1931 const WebRtc_UWord32 sendReport) {
1932 return _rtcpSender.SendTimeOfSendReport(sendReport);
1935 void ModuleRtpRtcpImpl::OnReceivedNACK(
1936 const WebRtc_UWord16 nackSequenceNumbersLength,
1937 const WebRtc_UWord16* nackSequenceNumbers) {
1938 if (!_rtpSender.StorePackets() ||
1939 nackSequenceNumbers == NULL ||
1940 nackSequenceNumbersLength == 0) {
1941 return;
1943 WebRtc_UWord16 avgRTT = 0;
1944 _rtcpReceiver.RTT(_rtpReceiver.SSRC(), NULL, &avgRTT, NULL, NULL);
1945 _rtpSender.OnReceivedNACK(nackSequenceNumbersLength,
1946 nackSequenceNumbers,
1947 avgRTT);
1950 WebRtc_Word32 ModuleRtpRtcpImpl::LastReceivedNTP(
1951 WebRtc_UWord32& RTCPArrivalTimeSecs, // when we received the last report
1952 WebRtc_UWord32& RTCPArrivalTimeFrac,
1953 WebRtc_UWord32& remoteSR) {
1954 // remote SR: NTP inside the last received (mid 16 bits from sec and frac)
1955 WebRtc_UWord32 NTPsecs = 0;
1956 WebRtc_UWord32 NTPfrac = 0;
1958 if (-1 == _rtcpReceiver.NTP(&NTPsecs,
1959 &NTPfrac,
1960 &RTCPArrivalTimeSecs,
1961 &RTCPArrivalTimeFrac)) {
1962 return -1;
1964 remoteSR = ((NTPsecs & 0x0000ffff) << 16) + ((NTPfrac & 0xffff0000) >> 16);
1965 return 0;
1968 bool ModuleRtpRtcpImpl::UpdateRTCPReceiveInformationTimers() {
1969 // if this returns true this channel has timed out
1970 // periodically check if this is true and if so call UpdateTMMBR
1971 return _rtcpReceiver.UpdateRTCPReceiveInformationTimers();
1974 // called from RTCPsender
1975 WebRtc_Word32 ModuleRtpRtcpImpl::BoundingSet(bool& tmmbrOwner,
1976 TMMBRSet*& boundingSet) {
1977 return _rtcpReceiver.BoundingSet(tmmbrOwner, boundingSet);
1979 } // namespace webrtc