blob: e30043983bc0c336e830ef1fdd5081f56357e890 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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 "rtcp_receiver.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
13#include <string.h> //memset
14#include <cassert> //assert
15
16#include "trace.h"
17#include "critical_section_wrapper.h"
pwestin@webrtc.org741da942011-09-20 13:52:04 +000018#include "rtcp_utility.h"
19#include "rtp_rtcp_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000020
21namespace
22{
23 const float FRAC = 4.294967296E9;
24}
25
26namespace webrtc {
27using namespace RTCPUtility;
28using namespace RTCPHelp;
29
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000030// The number of RTCP time intervals needed to trigger a timeout.
31const int kRrTimeoutIntervals = 3;
32
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +000033RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, Clock* clock,
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000034 ModuleRtpRtcpImpl* owner)
35 : TMMBRHelp(),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000036 _id(id),
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +000037 _clock(clock),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000038 _method(kRtcpOff),
39 _lastReceived(0),
40 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000041 _criticalSectionFeedbacks(
42 CriticalSectionWrapper::CreateCriticalSection()),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000043 _cbRtcpFeedback(NULL),
44 _cbRtcpBandwidthObserver(NULL),
45 _cbRtcpIntraFrameObserver(NULL),
46 _criticalSectionRTCPReceiver(
47 CriticalSectionWrapper::CreateCriticalSection()),
48 _SSRC(0),
49 _remoteSSRC(0),
50 _remoteSenderInfo(),
51 _lastReceivedSRNTPsecs(0),
52 _lastReceivedSRNTPfrac(0),
53 _receivedInfoMap(),
54 _packetTimeOutMS(0),
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000055 _lastReceivedRrMs(0),
56 _lastIncreasedSequenceNumberMs(0),
57 _rtt(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +000058 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
59 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
60}
61
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000062RTCPReceiver::~RTCPReceiver() {
63 delete _criticalSectionRTCPReceiver;
64 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000065
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000066 while (!_receivedReportBlockMap.empty()) {
67 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::iterator first =
68 _receivedReportBlockMap.begin();
69 delete first->second;
70 _receivedReportBlockMap.erase(first);
71 }
72 while (!_receivedInfoMap.empty()) {
73 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator first =
74 _receivedInfoMap.begin();
75 delete first->second;
76 _receivedInfoMap.erase(first);
77 }
78 while (!_receivedCnameMap.empty()) {
79 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator first =
80 _receivedCnameMap.begin();
81 delete first->second;
82 _receivedCnameMap.erase(first);
83 }
84 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id,
85 "%s deleted", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +000086}
87
88void
89RTCPReceiver::ChangeUniqueId(const WebRtc_Word32 id)
90{
91 _id = id;
92}
93
94RTCPMethod
95RTCPReceiver::Status() const
96{
97 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
98 return _method;
99}
100
101WebRtc_Word32
102RTCPReceiver::SetRTCPStatus(const RTCPMethod method)
103{
104 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
105 _method = method;
106 return 0;
107}
108
pwestin@webrtc.org18530052012-07-03 10:41:54 +0000109WebRtc_Word64
niklase@google.com470e71d2011-07-07 08:21:25 +0000110RTCPReceiver::LastReceived()
111{
112 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
113 return _lastReceived;
114}
115
116WebRtc_Word32
117RTCPReceiver::SetRemoteSSRC( const WebRtc_UWord32 ssrc)
118{
119 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
120
121 // new SSRC reset old reports
122 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
123 _lastReceivedSRNTPsecs = 0;
124 _lastReceivedSRNTPfrac = 0;
125
126 _remoteSSRC = ssrc;
127 return 0;
128}
129
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000130void RTCPReceiver::RegisterRtcpObservers(
131 RtcpIntraFrameObserver* intra_frame_callback,
132 RtcpBandwidthObserver* bandwidth_callback,
133 RtcpFeedback* feedback_callback) {
134 CriticalSectionScoped lock(_criticalSectionFeedbacks);
135 _cbRtcpIntraFrameObserver = intra_frame_callback;
136 _cbRtcpBandwidthObserver = bandwidth_callback;
137 _cbRtcpFeedback = feedback_callback;
niklase@google.com470e71d2011-07-07 08:21:25 +0000138}
139
niklase@google.com470e71d2011-07-07 08:21:25 +0000140
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000141void RTCPReceiver::SetSSRC(const WebRtc_UWord32 ssrc) {
142 WebRtc_UWord32 old_ssrc = 0;
143 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000144 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000145 old_ssrc = _SSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000146 _SSRC = ssrc;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000147 }
148 {
149 CriticalSectionScoped lock(_criticalSectionFeedbacks);
150 if (_cbRtcpIntraFrameObserver && old_ssrc != ssrc) {
151 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, ssrc);
152 }
153 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000154}
155
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000156WebRtc_Word32 RTCPReceiver::ResetRTT(const WebRtc_UWord32 remoteSSRC) {
157 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
158 RTCPReportBlockInformation* reportBlock =
159 GetReportBlockInformation(remoteSSRC);
160 if (reportBlock == NULL) {
161 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
162 "\tfailed to GetReportBlockInformation(%u)", remoteSSRC);
163 return -1;
164 }
165 reportBlock->RTT = 0;
166 reportBlock->avgRTT = 0;
167 reportBlock->minRTT = 0;
168 reportBlock->maxRTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000169 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000170}
171
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000172WebRtc_Word32 RTCPReceiver::RTT(const WebRtc_UWord32 remoteSSRC,
173 WebRtc_UWord16* RTT,
174 WebRtc_UWord16* avgRTT,
175 WebRtc_UWord16* minRTT,
176 WebRtc_UWord16* maxRTT) const {
177 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000178
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000179 RTCPReportBlockInformation* reportBlock =
180 GetReportBlockInformation(remoteSSRC);
181
182 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000183 return -1;
184 }
185 if (RTT) {
186 *RTT = reportBlock->RTT;
187 }
188 if (avgRTT) {
189 *avgRTT = reportBlock->avgRTT;
190 }
191 if (minRTT) {
192 *minRTT = reportBlock->minRTT;
193 }
194 if (maxRTT) {
195 *maxRTT = reportBlock->maxRTT;
196 }
197 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000198}
199
mflodman@webrtc.orgd7d46882012-02-14 12:49:59 +0000200WebRtc_UWord16 RTCPReceiver::RTT() const {
201 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
202 if (!_receivedReportBlockMap.empty()) {
203 return 0;
204 }
205 return _rtt;
206}
207
208int RTCPReceiver::SetRTT(WebRtc_UWord16 rtt) {
209 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
210 if (!_receivedReportBlockMap.empty()) {
211 return -1;
212 }
213 _rtt = rtt;
214 return 0;
215}
216
niklase@google.com470e71d2011-07-07 08:21:25 +0000217WebRtc_Word32
218RTCPReceiver::NTP(WebRtc_UWord32 *ReceivedNTPsecs,
219 WebRtc_UWord32 *ReceivedNTPfrac,
220 WebRtc_UWord32 *RTCPArrivalTimeSecs,
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000221 WebRtc_UWord32 *RTCPArrivalTimeFrac,
222 WebRtc_UWord32 *rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000223{
224 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
225 if(ReceivedNTPsecs)
226 {
227 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
228 }
229 if(ReceivedNTPfrac)
230 {
231 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
232 }
233 if(RTCPArrivalTimeFrac)
234 {
235 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
236 }
237 if(RTCPArrivalTimeSecs)
238 {
239 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
240 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000241 if (rtcp_timestamp) {
242 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
243 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000244 return 0;
245}
246
247WebRtc_Word32
248RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
249{
250 if(senderInfo == NULL)
251 {
252 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
253 return -1;
254 }
255 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
256 if(_lastReceivedSRNTPsecs == 0)
257 {
258 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
259 return -1;
260 }
261 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
262 return 0;
263}
264
265// statistics
266// we can get multiple receive reports when we receive the report from a CE
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000267WebRtc_Word32 RTCPReceiver::StatisticsReceived(
268 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000269 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000270 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
271
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000272 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::const_iterator it =
273 _receivedReportBlockMap.begin();
274
275 while (it != _receivedReportBlockMap.end()) {
276 receiveBlocks->push_back(it->second->remoteReceiveBlock);
277 it++;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000278 }
279 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000280}
281
282WebRtc_Word32
283RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
284 RTCPUtility::RTCPParserV2* rtcpParser)
285{
286 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
287
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000288 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000289
290 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
291 while (pktType != RTCPUtility::kRtcpNotValidCode)
292 {
293 // Each "case" is responsible for iterate the parser to the
294 // next top level packet.
295 switch (pktType)
296 {
297 case RTCPUtility::kRtcpSrCode:
298 case RTCPUtility::kRtcpRrCode:
299 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
300 break;
301 case RTCPUtility::kRtcpSdesCode:
302 HandleSDES(*rtcpParser);
303 break;
304 case RTCPUtility::kRtcpXrVoipMetricCode:
305 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
306 break;
307 case RTCPUtility::kRtcpByeCode:
308 HandleBYE(*rtcpParser);
309 break;
310 case RTCPUtility::kRtcpRtpfbNackCode:
311 HandleNACK(*rtcpParser, rtcpPacketInformation);
312 break;
313 case RTCPUtility::kRtcpRtpfbTmmbrCode:
314 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
315 break;
316 case RTCPUtility::kRtcpRtpfbTmmbnCode:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000317 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000318 break;
319 case RTCPUtility::kRtcpRtpfbSrReqCode:
320 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
321 break;
322 case RTCPUtility::kRtcpPsfbPliCode:
323 HandlePLI(*rtcpParser, rtcpPacketInformation);
324 break;
325 case RTCPUtility::kRtcpPsfbSliCode:
326 HandleSLI(*rtcpParser, rtcpPacketInformation);
327 break;
328 case RTCPUtility::kRtcpPsfbRpsiCode:
329 HandleRPSI(*rtcpParser, rtcpPacketInformation);
330 break;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000331 case RTCPUtility::kRtcpExtendedIjCode:
332 HandleIJ(*rtcpParser, rtcpPacketInformation);
333 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 case RTCPUtility::kRtcpPsfbFirCode:
335 HandleFIR(*rtcpParser, rtcpPacketInformation);
336 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000337 case RTCPUtility::kRtcpPsfbAppCode:
338 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
339 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 case RTCPUtility::kRtcpAppCode:
341 // generic application messages
342 HandleAPP(*rtcpParser, rtcpPacketInformation);
343 break;
344 case RTCPUtility::kRtcpAppItemCode:
345 // generic application messages
346 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
347 break;
348 default:
349 rtcpParser->Iterate();
350 break;
351 }
352 pktType = rtcpParser->PacketType();
353 }
354 return 0;
355}
356
357// no need for critsect we have _criticalSectionRTCPReceiver
358void
359RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
360 RTCPPacketInformation& rtcpPacketInformation)
361{
362 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
363 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
364
365 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
366
367 // SR.SenderSSRC
368 // The synchronization source identifier for the originator of this SR packet
369
370 // rtcpPacket.RR.SenderSSRC
371 // The source of the packet sender, same as of SR? or is this a CE?
372
373 const WebRtc_UWord32 remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
374 const WebRtc_UWord8 numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
375
376 rtcpPacketInformation.remoteSSRC = remoteSSRC;
377
378 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
379 if (!ptrReceiveInfo)
380 {
381 rtcpParser.Iterate();
382 return;
383 }
384
385 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
386 {
387 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
388 "Received SR(%d). SSRC:0x%x, from SSRC:0x%x, to us %d.", _id, _SSRC, remoteSSRC, (_remoteSSRC == remoteSSRC)?1:0);
389
390 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
391 {
392 // only signal that we have received a SR when we accept one
393 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
394
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000395 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
396 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
397 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
398
niklase@google.com470e71d2011-07-07 08:21:25 +0000399 // We will only store the send report from one source, but
400 // we will store all the receive block
401
402 // Save the NTP time of this report
403 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
404 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
405 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
406 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
407 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
408
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000409 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000410 }
411 else
412 {
413 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
414 }
415 } else
416 {
417 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
418 "Received RR(%d). SSRC:0x%x, from SSRC:0x%x", _id, _SSRC, remoteSSRC);
419
420 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
421 }
422 UpdateReceiveInformation(*ptrReceiveInfo);
423
424 rtcpPacketType = rtcpParser.Iterate();
425
426 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
427 {
428 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
429 rtcpPacketType = rtcpParser.Iterate();
430 }
431}
432
433// no need for critsect we have _criticalSectionRTCPReceiver
434void
435RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
436 RTCPPacketInformation& rtcpPacketInformation,
437 const WebRtc_UWord32 remoteSSRC,
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000438 const WebRtc_UWord8 numberOfReportBlocks) {
439 // This will be called once per report block in the RTCP packet.
440 // We filter out all report blocks that are not for us.
441 // Each packet has max 31 RR blocks.
442 //
443 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000444
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000445 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
446 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000447
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000448 // Filter out all report blocks that are not for us.
449 if (rtcpPacket.ReportBlockItem.SSRC != _SSRC) {
450 // This block is not for us ignore it.
451 return;
452 }
453
454 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
455 // _criticalSectionRTCPReceiver.
456 _criticalSectionRTCPReceiver->Leave();
457 WebRtc_UWord32 sendTimeMS =
458 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
459 _criticalSectionRTCPReceiver->Enter();
460
461 RTCPReportBlockInformation* reportBlock =
462 CreateReportBlockInformation(remoteSSRC);
463 if (reportBlock == NULL) {
464 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
465 "\tfailed to CreateReportBlockInformation(%u)", remoteSSRC);
466 return;
467 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000468
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000469 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000470 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
471 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
472 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
473 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
474 reportBlock->remoteReceiveBlock.cumulativeLost =
475 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000476 if (rb.ExtendedHighestSequenceNumber >
477 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
478 // We have successfully delivered new RTP packets to the remote side after
479 // the last RR was sent from the remote side.
480 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000481 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000482 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
483 rb.ExtendedHighestSequenceNumber;
484 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
485 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
486 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
487
488 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
489 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
490 }
491
492 WebRtc_UWord32 delaySinceLastSendReport =
493 rtcpPacket.ReportBlockItem.DelayLastSR;
494
495 // local NTP time when we received this
496 WebRtc_UWord32 lastReceivedRRNTPsecs = 0;
497 WebRtc_UWord32 lastReceivedRRNTPfrac = 0;
498
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000499 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000500
501 // time when we received this in MS
502 WebRtc_UWord32 receiveTimeMS = ModuleRTPUtility::ConvertNTPTimeToMS(
503 lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
504
505 // Estimate RTT
506 WebRtc_UWord32 d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
507 d /= 65536;
508 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
509
510 WebRtc_Word32 RTT = 0;
511
512 if (sendTimeMS > 0) {
513 RTT = receiveTimeMS - d - sendTimeMS;
514 if (RTT <= 0) {
515 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000516 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000517 if (RTT > reportBlock->maxRTT) {
518 // store max RTT
519 reportBlock->maxRTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000520 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000521 if (reportBlock->minRTT == 0) {
522 // first RTT
523 reportBlock->minRTT = (WebRtc_UWord16) RTT;
524 } else if (RTT < reportBlock->minRTT) {
525 // Store min RTT
526 reportBlock->minRTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000527 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000528 // store last RTT
529 reportBlock->RTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000530
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000531 // store average RTT
532 if (reportBlock->numAverageCalcs != 0) {
533 float ac = static_cast<float> (reportBlock->numAverageCalcs);
534 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
535 + ((1 / (ac + 1)) * RTT);
536 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
537 } else {
538 // first RTT
539 reportBlock->avgRTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000540 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000541 reportBlock->numAverageCalcs++;
542 }
543
544 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
545 " -> Received report block(%d), from SSRC:0x%x, RTT:%d, loss:%d",
546 _id, remoteSSRC, RTT, rtcpPacket.ReportBlockItem.FractionLost);
547
548 // rtcpPacketInformation
549 rtcpPacketInformation.AddReportInfo(
550 reportBlock->remoteReceiveBlock.fractionLost, (WebRtc_UWord16) RTT,
551 reportBlock->remoteReceiveBlock.extendedHighSeqNum,
552 reportBlock->remoteReceiveBlock.jitter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000553}
554
555RTCPReportBlockInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000556RTCPReceiver::CreateReportBlockInformation(WebRtc_UWord32 remoteSSRC) {
557 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000558
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000559 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::iterator it =
560 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000561
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000562 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
563 if (it != _receivedReportBlockMap.end()) {
564 ptrReportBlockInfo = it->second;
565 } else {
566 ptrReportBlockInfo = new RTCPReportBlockInformation;
567 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
568 }
569 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000570}
571
572RTCPReportBlockInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000573RTCPReceiver::GetReportBlockInformation(WebRtc_UWord32 remoteSSRC) const {
574 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000575
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000576 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::const_iterator it =
577 _receivedReportBlockMap.find(remoteSSRC);
578
579 if (it == _receivedReportBlockMap.end()) {
580 return NULL;
581 }
582 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000583}
584
585RTCPCnameInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000586RTCPReceiver::CreateCnameInformation(WebRtc_UWord32 remoteSSRC) {
587 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000588
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000589 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator it =
590 _receivedCnameMap.find(remoteSSRC);
591
592 if (it != _receivedCnameMap.end()) {
593 return it->second;
594 }
595 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000596 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000597 _receivedCnameMap[remoteSSRC] = cnameInfo;
598 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000599}
600
601RTCPCnameInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000602RTCPReceiver::GetCnameInformation(WebRtc_UWord32 remoteSSRC) const {
603 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000604
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000605 std::map<WebRtc_UWord32, RTCPCnameInformation*>::const_iterator it =
606 _receivedCnameMap.find(remoteSSRC);
607
608 if (it == _receivedCnameMap.end()) {
609 return NULL;
610 }
611 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000612}
613
614RTCPReceiveInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000615RTCPReceiver::CreateReceiveInformation(WebRtc_UWord32 remoteSSRC) {
616 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000617
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000618 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator it =
619 _receivedInfoMap.find(remoteSSRC);
620
621 if (it != _receivedInfoMap.end()) {
622 return it->second;
623 }
624 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
625 _receivedInfoMap[remoteSSRC] = receiveInfo;
626 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000627}
628
629RTCPReceiveInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000630RTCPReceiver::GetReceiveInformation(WebRtc_UWord32 remoteSSRC) {
631 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000632
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000633 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator it =
634 _receivedInfoMap.find(remoteSSRC);
635 if (it == _receivedInfoMap.end()) {
636 return NULL;
637 }
638 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000639}
640
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000641void RTCPReceiver::UpdateReceiveInformation(
642 RTCPReceiveInformation& receiveInformation) {
643 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000644 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000645}
646
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000647bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
648 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
649 if (_lastReceivedRrMs == 0)
650 return false;
651
652 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000653 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000654 // Reset the timer to only trigger one log.
655 _lastReceivedRrMs = 0;
656 return true;
657 }
658 return false;
659}
660
661bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
662 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
663 if (_lastIncreasedSequenceNumberMs == 0)
664 return false;
665
666 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000667 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000668 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000669 // Reset the timer to only trigger one log.
670 _lastIncreasedSequenceNumberMs = 0;
671 return true;
672 }
673 return false;
674}
675
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000676bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
677 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000678
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000679 bool updateBoundingSet = false;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000680 WebRtc_Word64 timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000681
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000682 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
683 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000684
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000685 while (receiveInfoIt != _receivedInfoMap.end()) {
686 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
687 if (receiveInfo == NULL) {
688 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000689 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000690 // time since last received rtcp packet
691 // when we dont have a lastTimeReceived and the object is marked
692 // readyForDelete it's removed from the map
693 if (receiveInfo->lastTimeReceived) {
694 /// use audio define since we don't know what interval the remote peer is
695 // using
696 if ((timeNow - receiveInfo->lastTimeReceived) >
697 5 * RTCP_INTERVAL_AUDIO_MS) {
698 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000699 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000700 // prevent that we call this over and over again
701 receiveInfo->lastTimeReceived = 0;
702 // send new TMMBN to all channels using the default codec
703 updateBoundingSet = true;
704 }
705 receiveInfoIt++;
706 } else if (receiveInfo->readyForDelete) {
707 // store our current receiveInfoItem
708 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator
709 receiveInfoItemToBeErased = receiveInfoIt;
710 receiveInfoIt++;
711 delete receiveInfoItemToBeErased->second;
712 _receivedInfoMap.erase(receiveInfoItemToBeErased);
713 } else {
714 receiveInfoIt++;
715 }
716 }
717 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000718}
719
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000720WebRtc_Word32 RTCPReceiver::BoundingSet(bool &tmmbrOwner,
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000721 TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000722 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000723
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000724 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
725 _receivedInfoMap.find(_remoteSSRC);
726
727 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000728 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000729 }
730 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
731 if (receiveInfo == NULL) {
732 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
733 "%s failed to get RTCPReceiveInformation",
734 __FUNCTION__);
735 return -1;
736 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000737 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000738 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000739 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
740 for(WebRtc_UWord32 i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
741 i++) {
742 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == _SSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000743 // owner of bounding set
744 tmmbrOwner = true;
745 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000746 boundingSetRec->SetEntry(i,
747 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
748 receiveInfo->TmmbnBoundingSet.PacketOH(i),
749 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000750 }
751 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000752 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000753}
754
755// no need for critsect we have _criticalSectionRTCPReceiver
756void
757RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
758{
759 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
760 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
761 {
762 HandleSDESChunk(rtcpParser);
763 pktType = rtcpParser.Iterate();
764 }
765}
766
767// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000768void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
769 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
770 RTCPCnameInformation* cnameInfo =
771 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
772 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000773
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000774 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
775 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000776}
777
778// no need for critsect we have _criticalSectionRTCPReceiver
779void
780RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
781 RTCPPacketInformation& rtcpPacketInformation)
782{
783 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000784 if (_SSRC != rtcpPacket.NACK.MediaSSRC)
785 {
786 // Not to us.
787 rtcpParser.Iterate();
788 return;
789 }
790
791 rtcpPacketInformation.ResetNACKPacketIdArray();
792
793 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
794 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
795 {
796 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
797 pktType = rtcpParser.Iterate();
798 }
799}
800
801// no need for critsect we have _criticalSectionRTCPReceiver
802void
803RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
804 RTCPPacketInformation& rtcpPacketInformation)
805{
806 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
807
808 WebRtc_UWord16 bitMask = rtcpPacket.NACKItem.BitMask;
809 if(bitMask)
810 {
811 for(int i=1; i <= 16; ++i)
812 {
813 if(bitMask & 0x01)
814 {
815 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
816 }
817 bitMask = bitMask >>1;
818 }
819 }
820
821 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
822}
823
824// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000825void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
826 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000827
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000828 // clear our lists
829 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
830 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::iterator
831 reportBlockInfoIt = _receivedReportBlockMap.find(
832 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000833
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000834 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
835 delete reportBlockInfoIt->second;
836 _receivedReportBlockMap.erase(reportBlockInfoIt);
837 }
838 // we can't delete it due to TMMBR
839 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
840 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000841
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000842 if (receiveInfoIt != _receivedInfoMap.end()) {
843 receiveInfoIt->second->readyForDelete = true;
844 }
845
846 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator cnameInfoIt =
847 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
848
849 if (cnameInfoIt != _receivedCnameMap.end()) {
850 delete cnameInfoIt->second;
851 _receivedCnameMap.erase(cnameInfoIt);
852 }
853 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000854}
855
856// no need for critsect we have _criticalSectionRTCPReceiver
857void
858RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
859 RTCPPacketInformation& rtcpPacketInformation)
860{
861 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
862
863 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
864
865 if(rtcpPacket.XRVOIPMetricItem.SSRC == _SSRC)
866 {
867 // Store VoIP metrics block if it's about me
868 // from OriginatorSSRC do we filter it?
869 // rtcpPacket.XR.OriginatorSSRC;
870
871 RTCPVoIPMetric receivedVoIPMetrics;
872 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
873 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
874 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
875 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
876 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
877 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
878 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
879 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
880 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
881 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
882 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
883 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
884 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
885 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
886 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
887 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
888 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
889 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
890 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
891 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
892
893 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
894
895 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
896 }
897 rtcpParser.Iterate();
898}
899
900// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000901void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
902 RTCPPacketInformation& rtcpPacketInformation) {
903 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
904 if (_SSRC == rtcpPacket.PLI.MediaSSRC) {
905 // Received a signal that we need to send a new key frame.
906 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
907 }
908 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000909}
910
911// no need for critsect we have _criticalSectionRTCPReceiver
912void
913RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
914 RTCPPacketInformation& rtcpPacketInformation)
915{
916 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
917
918 WebRtc_UWord32 senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
919 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
920 if (ptrReceiveInfo == NULL)
921 {
922 // This remote SSRC must be saved before.
923 rtcpParser.Iterate();
924 return;
925 }
926 if(rtcpPacket.TMMBR.MediaSSRC)
927 {
928 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
929 // in relay mode this is a valid number
930 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
931 }
932
933 // Use packet length to calc max number of TMMBR blocks
934 // each TMMBR block is 8 bytes
935 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
936
937 // sanity
938 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
939 {
940 assert(false);
941 rtcpParser.Iterate();
942 return;
943 }
944 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((WebRtc_UWord32)maxNumOfTMMBRBlocks);
945
946 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
947 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
948 {
949 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
950 pktType = rtcpParser.Iterate();
951 }
952}
953
954// no need for critsect we have _criticalSectionRTCPReceiver
955void
956RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
957 const RTCPUtility::RTCPPacket& rtcpPacket,
958 RTCPPacketInformation& rtcpPacketInformation,
959 const WebRtc_UWord32 senderSSRC)
960{
961 if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
962 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
963 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000964 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000965 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +0000966 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
967 }
968}
969
970// no need for critsect we have _criticalSectionRTCPReceiver
971void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000972RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
973 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +0000974{
975 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
976 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
977 if (ptrReceiveInfo == NULL)
978 {
979 // This remote SSRC must be saved before.
980 rtcpParser.Iterate();
981 return;
982 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000983 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +0000984 // Use packet length to calc max number of TMMBN blocks
985 // each TMMBN block is 8 bytes
986 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
987
988 // sanity
989 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
990 {
991 assert(false);
992 rtcpParser.Iterate();
993 return;
994 }
995
996 ptrReceiveInfo->VerifyAndAllocateBoundingSet((WebRtc_UWord32)maxNumOfTMMBNBlocks);
997
998 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
999 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1000 {
1001 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1002 pktType = rtcpParser.Iterate();
1003 }
1004}
1005
1006// no need for critsect we have _criticalSectionRTCPReceiver
1007void
1008RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1009 RTCPPacketInformation& rtcpPacketInformation)
1010{
1011 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1012 rtcpParser.Iterate();
1013}
1014
1015// no need for critsect we have _criticalSectionRTCPReceiver
1016void
1017RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1018 const RTCPUtility::RTCPPacket& rtcpPacket)
1019{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001020 receiveInfo.TmmbnBoundingSet.AddEntry(
1021 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1022 rtcpPacket.TMMBNItem.MeasuredOverhead,
1023 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001024}
1025
1026// no need for critsect we have _criticalSectionRTCPReceiver
1027void
1028RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1029 RTCPPacketInformation& rtcpPacketInformation)
1030{
1031 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001032 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1033 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1034 {
1035 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1036 pktType = rtcpParser.Iterate();
1037 }
1038}
1039
1040// no need for critsect we have _criticalSectionRTCPReceiver
1041void
1042RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1043 RTCPPacketInformation& rtcpPacketInformation)
1044{
1045 // in theory there could be multiple slices lost
1046 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1047 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1048}
1049
1050void
1051RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1052 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1053{
1054 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001055 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1056 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1057 {
1058 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1059 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1060 {
1061 // to us unknown
1062 // continue
1063 rtcpParser.Iterate();
1064 return;
1065 }
1066 rtcpPacketInformation.rpsiPictureId = 0;
1067
1068 // convert NativeBitString to rpsiPictureId
1069 WebRtc_UWord8 numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1070 for(WebRtc_UWord8 n = 0; n < (numberOfBytes-1); n++)
1071 {
1072 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1073 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1074 }
1075 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1076 }
1077}
1078
1079// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001080void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1081 RTCPPacketInformation& rtcpPacketInformation) {
1082 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1083 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1084 pktType = rtcpParser.Iterate();
1085 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1086 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1087 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001088 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001089 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001090}
1091
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001092// no need for critsect we have _criticalSectionRTCPReceiver
1093void
1094RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1095 RTCPPacketInformation& rtcpPacketInformation)
1096{
1097 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1098
1099 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1100 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1101 {
1102 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1103 pktType = rtcpParser.Iterate();
1104 }
1105}
1106
1107void
1108RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1109 RTCPPacketInformation& rtcpPacketInformation)
1110{
1111 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1112 rtcpPacketInformation.interArrivalJitter =
1113 rtcpPacket.ExtendedJitterReportItem.Jitter;
1114}
1115
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001116void RTCPReceiver::HandleREMBItem(
1117 RTCPUtility::RTCPParserV2& rtcpParser,
1118 RTCPPacketInformation& rtcpPacketInformation) {
1119 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1120 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1121 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1122 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001123}
1124
1125// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001126void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1127 RTCPPacketInformation& rtcpPacketInformation) {
1128 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1129 RTCPReceiveInformation* ptrReceiveInfo =
1130 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001131
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001132 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1133 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1134 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1135 pktType = rtcpParser.Iterate();
1136 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001137}
1138
1139// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001140void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1141 const RTCPUtility::RTCPPacket& rtcpPacket,
1142 RTCPPacketInformation& rtcpPacketInformation) {
1143 // Is it our sender that is requested to generate a new keyframe
1144 if (_SSRC != rtcpPacket.FIRItem.SSRC) {
1145 return;
1146 }
1147 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1148 // we don't know who this originate from
1149 if (receiveInfo) {
1150 // check if we have reported this FIRSequenceNumber before
1151 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1152 receiveInfo->lastFIRSequenceNumber) {
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001153 WebRtc_Word64 now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001154 // sanity; don't go crazy with the callbacks
1155 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1156 receiveInfo->lastFIRRequest = now;
1157 receiveInfo->lastFIRSequenceNumber =
1158 rtcpPacket.FIRItem.CommandSequenceNumber;
1159 // received signal that we need to send a new key frame
1160 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1161 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001162 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001163 } else {
1164 // received signal that we need to send a new key frame
1165 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1166 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001167}
1168
1169void
1170RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1171 RTCPPacketInformation& rtcpPacketInformation)
1172{
1173 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1174
1175 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1176 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1177 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1178
1179 rtcpParser.Iterate();
1180}
1181
1182void
1183RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1184 RTCPPacketInformation& rtcpPacketInformation)
1185{
1186 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1187
1188 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1189
1190 rtcpParser.Iterate();
1191}
1192
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001193WebRtc_Word32 RTCPReceiver::UpdateTMMBR() {
1194 WebRtc_Word32 numBoundingSet = 0;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001195 WebRtc_UWord32 bitrate = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001196 WebRtc_UWord32 accNumCandidates = 0;
1197
1198 WebRtc_Word32 size = TMMBRReceived(0, 0, NULL);
1199 if (size > 0) {
1200 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1201 // Get candidate set from receiver.
1202 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1203 } else {
1204 // Candidate set empty.
1205 VerifyAndAllocateCandidateSet(0); // resets candidate set
1206 }
1207 // Find bounding set
1208 TMMBRSet* boundingSet = NULL;
1209 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1210 if (numBoundingSet == -1) {
1211 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1212 "Failed to find TMMBR bounding set.");
1213 return -1;
1214 }
1215 // Set bounding set
1216 // Inform remote clients about the new bandwidth
1217 // inform the remote client
1218 _rtpRtcp.SetTMMBN(boundingSet);
1219
1220 // might trigger a TMMBN
1221 if (numBoundingSet == 0) {
1222 // owner of max bitrate request has timed out
1223 // empty bounding set has been sent
1224 return 0;
1225 }
1226 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001227 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001228 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001229 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1230 if (_cbRtcpBandwidthObserver) {
1231 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1232 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1233 "Set TMMBR request:%d kbps", bitrate);
1234 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001235 }
1236 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001237}
1238
1239// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001240void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001241 RTCPPacketInformation& rtcpPacketInformation) {
1242 // Process TMMBR and REMB first to avoid multiple callbacks
1243 // to OnNetworkChanged.
1244 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1245 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1246 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001247
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001248 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1249 UpdateTMMBR();
1250 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001251 unsigned int local_ssrc = 0;
1252 {
1253 // We don't want to hold this critsect when triggering the callbacks below.
1254 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1255 local_ssrc = _SSRC;
1256 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001257 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1258 _rtpRtcp.OnRequestSendReport();
1259 }
1260 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
1261 if (rtcpPacketInformation.nackSequenceNumbersLength > 0) {
1262 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1263 "SIG [RTCP] Incoming NACK length:%d",
1264 rtcpPacketInformation.nackSequenceNumbersLength);
1265 _rtpRtcp.OnReceivedNACK(
1266 rtcpPacketInformation.nackSequenceNumbersLength,
1267 rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001268 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001269 }
1270 {
1271 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001272
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001273 // We need feedback that we have received a report block(s) so that we
1274 // can generate a new packet in a conference relay scenario, one received
1275 // report can generate several RTCP packets, based on number relayed/mixed
1276 // a send report block should go out to all receivers.
1277 if (_cbRtcpIntraFrameObserver) {
1278 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1279 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1280 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1281 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1282 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1283 rtcpPacketInformation.remoteSSRC);
1284 } else {
1285 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1286 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1287 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001288 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001289 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001290 }
1291 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1292 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001293 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001294 }
1295 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1296 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001297 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001298 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001299 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001300 if (_cbRtcpBandwidthObserver) {
1301 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1302 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1303 "SIG [RTCP] Incoming REMB:%d",
1304 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1305 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1306 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1307 }
1308 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1309 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
1310 rtcpPacketInformation.reportBlock) {
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001311 WebRtc_Word64 now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001312 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
1313 rtcpPacketInformation.remoteSSRC,
1314 rtcpPacketInformation.fractionLost,
1315 rtcpPacketInformation.roundTripTime,
1316 rtcpPacketInformation.lastReceivedExtendedHighSeqNum,
1317 now);
1318 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001319 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001320 if(_cbRtcpFeedback) {
1321 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) {
1322 _cbRtcpFeedback->OnSendReportReceived(_id,
stefan@webrtc.org976a7e62012-09-21 13:20:21 +00001323 rtcpPacketInformation.remoteSSRC,
1324 rtcpPacketInformation.ntp_secs,
1325 rtcpPacketInformation.ntp_frac,
1326 rtcpPacketInformation.rtp_timestamp);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001327 } else {
1328 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1329 rtcpPacketInformation.remoteSSRC);
1330 }
1331 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1332 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1333 rtcpPacketInformation.VoIPMetric);
1334 }
1335 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1336 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1337 rtcpPacketInformation.applicationSubType,
1338 rtcpPacketInformation.applicationName,
1339 rtcpPacketInformation.applicationLength,
1340 rtcpPacketInformation.applicationData);
1341 }
1342 }
1343 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001344}
1345
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001346WebRtc_Word32 RTCPReceiver::CNAME(const WebRtc_UWord32 remoteSSRC,
1347 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001348 assert(cName);
1349
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001350 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1351 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001352 if (cnameInfo == NULL) {
1353 return -1;
1354 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001355 cName[RTCP_CNAME_SIZE - 1] = 0;
1356 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1357 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001358}
1359
1360// no callbacks allowed inside this function
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001361WebRtc_Word32 RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size,
1362 const WebRtc_UWord32 accNumCandidates,
1363 TMMBRSet* candidateSet) const {
1364 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001365
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001366 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::const_iterator
1367 receiveInfoIt = _receivedInfoMap.begin();
1368 if (receiveInfoIt == _receivedInfoMap.end()) {
1369 return -1;
1370 }
1371 WebRtc_UWord32 num = accNumCandidates;
1372 if (candidateSet) {
1373 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1374 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1375 if (receiveInfo == NULL) {
1376 return 0;
1377 }
1378 for (WebRtc_UWord32 i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001379 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001380 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001381 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001382 num++;
1383 }
1384 }
1385 receiveInfoIt++;
1386 }
1387 } else {
1388 while (receiveInfoIt != _receivedInfoMap.end()) {
1389 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1390 if(receiveInfo == NULL) {
1391 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1392 "%s failed to get RTCPReceiveInformation",
1393 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001394 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001395 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001396 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001397 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001398 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001399 }
1400 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001401}
1402
1403WebRtc_Word32
1404RTCPReceiver::SetPacketTimeout(const WebRtc_UWord32 timeoutMS)
1405{
1406 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1407 _packetTimeOutMS = timeoutMS;
1408 return 0;
1409}
1410
1411void RTCPReceiver::PacketTimeout()
1412{
1413 if(_packetTimeOutMS == 0)
1414 {
1415 // not configured
1416 return;
1417 }
1418
1419 bool packetTimeOut = false;
1420 {
1421 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1422 if(_lastReceived == 0)
1423 {
1424 // not active
1425 return;
1426 }
1427
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001428 WebRtc_Word64 now = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +00001429 if(now - _lastReceived > _packetTimeOutMS)
1430 {
1431 packetTimeOut = true;
1432 _lastReceived = 0; // only one callback
1433 }
1434 }
1435 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1436 if(packetTimeOut && _cbRtcpFeedback)
1437 {
1438 _cbRtcpFeedback->OnRTCPPacketTimeout(_id);
1439 }
1440}
1441} // namespace webrtc