blob: fba1818dd8c4cdf541b5eddddd6b6281d14d2fde [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
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000116WebRtc_Word64
117RTCPReceiver::LastReceivedReceiverReport() const {
118 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
119 WebRtc_Word64 last_received_rr = -1;
120 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
121 it != _receivedInfoMap.end(); ++it) {
122 if (it->second->lastTimeReceived > last_received_rr) {
123 last_received_rr = it->second->lastTimeReceived;
124 }
125 }
126 return last_received_rr;
127}
128
niklase@google.com470e71d2011-07-07 08:21:25 +0000129WebRtc_Word32
130RTCPReceiver::SetRemoteSSRC( const WebRtc_UWord32 ssrc)
131{
132 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
133
134 // new SSRC reset old reports
135 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
136 _lastReceivedSRNTPsecs = 0;
137 _lastReceivedSRNTPfrac = 0;
138
139 _remoteSSRC = ssrc;
140 return 0;
141}
142
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000143void RTCPReceiver::RegisterRtcpObservers(
144 RtcpIntraFrameObserver* intra_frame_callback,
145 RtcpBandwidthObserver* bandwidth_callback,
146 RtcpFeedback* feedback_callback) {
147 CriticalSectionScoped lock(_criticalSectionFeedbacks);
148 _cbRtcpIntraFrameObserver = intra_frame_callback;
149 _cbRtcpBandwidthObserver = bandwidth_callback;
150 _cbRtcpFeedback = feedback_callback;
niklase@google.com470e71d2011-07-07 08:21:25 +0000151}
152
niklase@google.com470e71d2011-07-07 08:21:25 +0000153
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000154void RTCPReceiver::SetSSRC(const WebRtc_UWord32 ssrc) {
155 WebRtc_UWord32 old_ssrc = 0;
156 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000157 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000158 old_ssrc = _SSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000159 _SSRC = ssrc;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000160 }
161 {
162 CriticalSectionScoped lock(_criticalSectionFeedbacks);
163 if (_cbRtcpIntraFrameObserver && old_ssrc != ssrc) {
164 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, ssrc);
165 }
166 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000167}
168
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000169WebRtc_Word32 RTCPReceiver::ResetRTT(const WebRtc_UWord32 remoteSSRC) {
170 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
171 RTCPReportBlockInformation* reportBlock =
172 GetReportBlockInformation(remoteSSRC);
173 if (reportBlock == NULL) {
174 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
175 "\tfailed to GetReportBlockInformation(%u)", remoteSSRC);
176 return -1;
177 }
178 reportBlock->RTT = 0;
179 reportBlock->avgRTT = 0;
180 reportBlock->minRTT = 0;
181 reportBlock->maxRTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000182 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000183}
184
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000185WebRtc_Word32 RTCPReceiver::RTT(const WebRtc_UWord32 remoteSSRC,
186 WebRtc_UWord16* RTT,
187 WebRtc_UWord16* avgRTT,
188 WebRtc_UWord16* minRTT,
189 WebRtc_UWord16* maxRTT) const {
190 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000191
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000192 RTCPReportBlockInformation* reportBlock =
193 GetReportBlockInformation(remoteSSRC);
194
195 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000196 return -1;
197 }
198 if (RTT) {
199 *RTT = reportBlock->RTT;
200 }
201 if (avgRTT) {
202 *avgRTT = reportBlock->avgRTT;
203 }
204 if (minRTT) {
205 *minRTT = reportBlock->minRTT;
206 }
207 if (maxRTT) {
208 *maxRTT = reportBlock->maxRTT;
209 }
210 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000211}
212
mflodman@webrtc.orgd7d46882012-02-14 12:49:59 +0000213WebRtc_UWord16 RTCPReceiver::RTT() const {
214 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
215 if (!_receivedReportBlockMap.empty()) {
216 return 0;
217 }
218 return _rtt;
219}
220
221int RTCPReceiver::SetRTT(WebRtc_UWord16 rtt) {
222 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
223 if (!_receivedReportBlockMap.empty()) {
224 return -1;
225 }
226 _rtt = rtt;
227 return 0;
228}
229
niklase@google.com470e71d2011-07-07 08:21:25 +0000230WebRtc_Word32
231RTCPReceiver::NTP(WebRtc_UWord32 *ReceivedNTPsecs,
232 WebRtc_UWord32 *ReceivedNTPfrac,
233 WebRtc_UWord32 *RTCPArrivalTimeSecs,
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000234 WebRtc_UWord32 *RTCPArrivalTimeFrac,
235 WebRtc_UWord32 *rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000236{
237 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
238 if(ReceivedNTPsecs)
239 {
240 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
241 }
242 if(ReceivedNTPfrac)
243 {
244 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
245 }
246 if(RTCPArrivalTimeFrac)
247 {
248 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
249 }
250 if(RTCPArrivalTimeSecs)
251 {
252 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
253 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000254 if (rtcp_timestamp) {
255 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
256 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000257 return 0;
258}
259
260WebRtc_Word32
261RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
262{
263 if(senderInfo == NULL)
264 {
265 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
266 return -1;
267 }
268 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
269 if(_lastReceivedSRNTPsecs == 0)
270 {
271 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
272 return -1;
273 }
274 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
275 return 0;
276}
277
278// statistics
279// we can get multiple receive reports when we receive the report from a CE
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000280WebRtc_Word32 RTCPReceiver::StatisticsReceived(
281 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000282 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000283 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
284
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000285 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::const_iterator it =
286 _receivedReportBlockMap.begin();
287
288 while (it != _receivedReportBlockMap.end()) {
289 receiveBlocks->push_back(it->second->remoteReceiveBlock);
290 it++;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000291 }
292 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000293}
294
295WebRtc_Word32
296RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
297 RTCPUtility::RTCPParserV2* rtcpParser)
298{
299 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
300
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000301 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000302
303 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
304 while (pktType != RTCPUtility::kRtcpNotValidCode)
305 {
306 // Each "case" is responsible for iterate the parser to the
307 // next top level packet.
308 switch (pktType)
309 {
310 case RTCPUtility::kRtcpSrCode:
311 case RTCPUtility::kRtcpRrCode:
312 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
313 break;
314 case RTCPUtility::kRtcpSdesCode:
315 HandleSDES(*rtcpParser);
316 break;
317 case RTCPUtility::kRtcpXrVoipMetricCode:
318 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
319 break;
320 case RTCPUtility::kRtcpByeCode:
321 HandleBYE(*rtcpParser);
322 break;
323 case RTCPUtility::kRtcpRtpfbNackCode:
324 HandleNACK(*rtcpParser, rtcpPacketInformation);
325 break;
326 case RTCPUtility::kRtcpRtpfbTmmbrCode:
327 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
328 break;
329 case RTCPUtility::kRtcpRtpfbTmmbnCode:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000330 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 break;
332 case RTCPUtility::kRtcpRtpfbSrReqCode:
333 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
334 break;
335 case RTCPUtility::kRtcpPsfbPliCode:
336 HandlePLI(*rtcpParser, rtcpPacketInformation);
337 break;
338 case RTCPUtility::kRtcpPsfbSliCode:
339 HandleSLI(*rtcpParser, rtcpPacketInformation);
340 break;
341 case RTCPUtility::kRtcpPsfbRpsiCode:
342 HandleRPSI(*rtcpParser, rtcpPacketInformation);
343 break;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000344 case RTCPUtility::kRtcpExtendedIjCode:
345 HandleIJ(*rtcpParser, rtcpPacketInformation);
346 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000347 case RTCPUtility::kRtcpPsfbFirCode:
348 HandleFIR(*rtcpParser, rtcpPacketInformation);
349 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000350 case RTCPUtility::kRtcpPsfbAppCode:
351 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
352 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000353 case RTCPUtility::kRtcpAppCode:
354 // generic application messages
355 HandleAPP(*rtcpParser, rtcpPacketInformation);
356 break;
357 case RTCPUtility::kRtcpAppItemCode:
358 // generic application messages
359 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
360 break;
361 default:
362 rtcpParser->Iterate();
363 break;
364 }
365 pktType = rtcpParser->PacketType();
366 }
367 return 0;
368}
369
370// no need for critsect we have _criticalSectionRTCPReceiver
371void
372RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
373 RTCPPacketInformation& rtcpPacketInformation)
374{
375 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
376 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
377
378 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
379
380 // SR.SenderSSRC
381 // The synchronization source identifier for the originator of this SR packet
382
383 // rtcpPacket.RR.SenderSSRC
384 // The source of the packet sender, same as of SR? or is this a CE?
385
386 const WebRtc_UWord32 remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
387 const WebRtc_UWord8 numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
388
389 rtcpPacketInformation.remoteSSRC = remoteSSRC;
390
391 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
392 if (!ptrReceiveInfo)
393 {
394 rtcpParser.Iterate();
395 return;
396 }
397
398 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
399 {
400 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
401 "Received SR(%d). SSRC:0x%x, from SSRC:0x%x, to us %d.", _id, _SSRC, remoteSSRC, (_remoteSSRC == remoteSSRC)?1:0);
402
403 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
404 {
405 // only signal that we have received a SR when we accept one
406 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
407
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000408 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
409 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
410 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
411
niklase@google.com470e71d2011-07-07 08:21:25 +0000412 // We will only store the send report from one source, but
413 // we will store all the receive block
414
415 // Save the NTP time of this report
416 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
417 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
418 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
419 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
420 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
421
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000422 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000423 }
424 else
425 {
426 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
427 }
428 } else
429 {
430 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
431 "Received RR(%d). SSRC:0x%x, from SSRC:0x%x", _id, _SSRC, remoteSSRC);
432
433 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
434 }
435 UpdateReceiveInformation(*ptrReceiveInfo);
436
437 rtcpPacketType = rtcpParser.Iterate();
438
439 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
440 {
441 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
442 rtcpPacketType = rtcpParser.Iterate();
443 }
444}
445
446// no need for critsect we have _criticalSectionRTCPReceiver
447void
448RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
449 RTCPPacketInformation& rtcpPacketInformation,
450 const WebRtc_UWord32 remoteSSRC,
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000451 const WebRtc_UWord8 numberOfReportBlocks) {
452 // This will be called once per report block in the RTCP packet.
453 // We filter out all report blocks that are not for us.
454 // Each packet has max 31 RR blocks.
455 //
456 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000457
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000458 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
459 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000460
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000461 // Filter out all report blocks that are not for us.
462 if (rtcpPacket.ReportBlockItem.SSRC != _SSRC) {
463 // This block is not for us ignore it.
464 return;
465 }
466
467 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
468 // _criticalSectionRTCPReceiver.
469 _criticalSectionRTCPReceiver->Leave();
470 WebRtc_UWord32 sendTimeMS =
471 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
472 _criticalSectionRTCPReceiver->Enter();
473
474 RTCPReportBlockInformation* reportBlock =
475 CreateReportBlockInformation(remoteSSRC);
476 if (reportBlock == NULL) {
477 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
478 "\tfailed to CreateReportBlockInformation(%u)", remoteSSRC);
479 return;
480 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000481
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000482 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000483 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
484 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
485 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
486 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
487 reportBlock->remoteReceiveBlock.cumulativeLost =
488 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000489 if (rb.ExtendedHighestSequenceNumber >
490 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
491 // We have successfully delivered new RTP packets to the remote side after
492 // the last RR was sent from the remote side.
493 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000494 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000495 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
496 rb.ExtendedHighestSequenceNumber;
497 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
498 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
499 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
500
501 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
502 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
503 }
504
505 WebRtc_UWord32 delaySinceLastSendReport =
506 rtcpPacket.ReportBlockItem.DelayLastSR;
507
508 // local NTP time when we received this
509 WebRtc_UWord32 lastReceivedRRNTPsecs = 0;
510 WebRtc_UWord32 lastReceivedRRNTPfrac = 0;
511
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000512 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000513
514 // time when we received this in MS
515 WebRtc_UWord32 receiveTimeMS = ModuleRTPUtility::ConvertNTPTimeToMS(
516 lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
517
518 // Estimate RTT
519 WebRtc_UWord32 d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
520 d /= 65536;
521 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
522
523 WebRtc_Word32 RTT = 0;
524
525 if (sendTimeMS > 0) {
526 RTT = receiveTimeMS - d - sendTimeMS;
527 if (RTT <= 0) {
528 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000529 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000530 if (RTT > reportBlock->maxRTT) {
531 // store max RTT
532 reportBlock->maxRTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000533 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000534 if (reportBlock->minRTT == 0) {
535 // first RTT
536 reportBlock->minRTT = (WebRtc_UWord16) RTT;
537 } else if (RTT < reportBlock->minRTT) {
538 // Store min RTT
539 reportBlock->minRTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000540 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000541 // store last RTT
542 reportBlock->RTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000543
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000544 // store average RTT
545 if (reportBlock->numAverageCalcs != 0) {
546 float ac = static_cast<float> (reportBlock->numAverageCalcs);
547 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
548 + ((1 / (ac + 1)) * RTT);
549 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
550 } else {
551 // first RTT
552 reportBlock->avgRTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000553 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000554 reportBlock->numAverageCalcs++;
555 }
556
557 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
558 " -> Received report block(%d), from SSRC:0x%x, RTT:%d, loss:%d",
559 _id, remoteSSRC, RTT, rtcpPacket.ReportBlockItem.FractionLost);
560
561 // rtcpPacketInformation
562 rtcpPacketInformation.AddReportInfo(
563 reportBlock->remoteReceiveBlock.fractionLost, (WebRtc_UWord16) RTT,
564 reportBlock->remoteReceiveBlock.extendedHighSeqNum,
565 reportBlock->remoteReceiveBlock.jitter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000566}
567
568RTCPReportBlockInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000569RTCPReceiver::CreateReportBlockInformation(WebRtc_UWord32 remoteSSRC) {
570 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000571
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000572 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::iterator it =
573 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000574
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000575 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
576 if (it != _receivedReportBlockMap.end()) {
577 ptrReportBlockInfo = it->second;
578 } else {
579 ptrReportBlockInfo = new RTCPReportBlockInformation;
580 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
581 }
582 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000583}
584
585RTCPReportBlockInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000586RTCPReceiver::GetReportBlockInformation(WebRtc_UWord32 remoteSSRC) const {
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, RTCPReportBlockInformation*>::const_iterator it =
590 _receivedReportBlockMap.find(remoteSSRC);
591
592 if (it == _receivedReportBlockMap.end()) {
593 return NULL;
594 }
595 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000596}
597
598RTCPCnameInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000599RTCPReceiver::CreateCnameInformation(WebRtc_UWord32 remoteSSRC) {
600 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000601
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000602 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator it =
603 _receivedCnameMap.find(remoteSSRC);
604
605 if (it != _receivedCnameMap.end()) {
606 return it->second;
607 }
608 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000609 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000610 _receivedCnameMap[remoteSSRC] = cnameInfo;
611 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000612}
613
614RTCPCnameInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000615RTCPReceiver::GetCnameInformation(WebRtc_UWord32 remoteSSRC) const {
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, RTCPCnameInformation*>::const_iterator it =
619 _receivedCnameMap.find(remoteSSRC);
620
621 if (it == _receivedCnameMap.end()) {
622 return NULL;
623 }
624 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000625}
626
627RTCPReceiveInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000628RTCPReceiver::CreateReceiveInformation(WebRtc_UWord32 remoteSSRC) {
629 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000630
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000631 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator it =
632 _receivedInfoMap.find(remoteSSRC);
633
634 if (it != _receivedInfoMap.end()) {
635 return it->second;
636 }
637 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
638 _receivedInfoMap[remoteSSRC] = receiveInfo;
639 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000640}
641
642RTCPReceiveInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000643RTCPReceiver::GetReceiveInformation(WebRtc_UWord32 remoteSSRC) {
644 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000645
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000646 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator it =
647 _receivedInfoMap.find(remoteSSRC);
648 if (it == _receivedInfoMap.end()) {
649 return NULL;
650 }
651 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000652}
653
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000654void RTCPReceiver::UpdateReceiveInformation(
655 RTCPReceiveInformation& receiveInformation) {
656 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000657 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000658}
659
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000660bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
661 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
662 if (_lastReceivedRrMs == 0)
663 return false;
664
665 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000666 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000667 // Reset the timer to only trigger one log.
668 _lastReceivedRrMs = 0;
669 return true;
670 }
671 return false;
672}
673
674bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
675 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
676 if (_lastIncreasedSequenceNumberMs == 0)
677 return false;
678
679 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000680 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000681 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000682 // Reset the timer to only trigger one log.
683 _lastIncreasedSequenceNumberMs = 0;
684 return true;
685 }
686 return false;
687}
688
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000689bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
690 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000691
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000692 bool updateBoundingSet = false;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000693 WebRtc_Word64 timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000694
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000695 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
696 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000697
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000698 while (receiveInfoIt != _receivedInfoMap.end()) {
699 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
700 if (receiveInfo == NULL) {
701 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000702 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000703 // time since last received rtcp packet
704 // when we dont have a lastTimeReceived and the object is marked
705 // readyForDelete it's removed from the map
706 if (receiveInfo->lastTimeReceived) {
707 /// use audio define since we don't know what interval the remote peer is
708 // using
709 if ((timeNow - receiveInfo->lastTimeReceived) >
710 5 * RTCP_INTERVAL_AUDIO_MS) {
711 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000712 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000713 // prevent that we call this over and over again
714 receiveInfo->lastTimeReceived = 0;
715 // send new TMMBN to all channels using the default codec
716 updateBoundingSet = true;
717 }
718 receiveInfoIt++;
719 } else if (receiveInfo->readyForDelete) {
720 // store our current receiveInfoItem
721 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator
722 receiveInfoItemToBeErased = receiveInfoIt;
723 receiveInfoIt++;
724 delete receiveInfoItemToBeErased->second;
725 _receivedInfoMap.erase(receiveInfoItemToBeErased);
726 } else {
727 receiveInfoIt++;
728 }
729 }
730 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000731}
732
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000733WebRtc_Word32 RTCPReceiver::BoundingSet(bool &tmmbrOwner,
hta@webrtc.org65a4e4e2012-04-30 11:23:41 +0000734 TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000735 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000736
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000737 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
738 _receivedInfoMap.find(_remoteSSRC);
739
740 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000741 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000742 }
743 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
744 if (receiveInfo == NULL) {
745 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
746 "%s failed to get RTCPReceiveInformation",
747 __FUNCTION__);
748 return -1;
749 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000750 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000751 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000752 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
753 for(WebRtc_UWord32 i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
754 i++) {
755 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == _SSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000756 // owner of bounding set
757 tmmbrOwner = true;
758 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000759 boundingSetRec->SetEntry(i,
760 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
761 receiveInfo->TmmbnBoundingSet.PacketOH(i),
762 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000763 }
764 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000765 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000766}
767
768// no need for critsect we have _criticalSectionRTCPReceiver
769void
770RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
771{
772 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
773 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
774 {
775 HandleSDESChunk(rtcpParser);
776 pktType = rtcpParser.Iterate();
777 }
778}
779
780// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000781void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
782 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
783 RTCPCnameInformation* cnameInfo =
784 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
785 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000786
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000787 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
788 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000789}
790
791// no need for critsect we have _criticalSectionRTCPReceiver
792void
793RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
794 RTCPPacketInformation& rtcpPacketInformation)
795{
796 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000797 if (_SSRC != rtcpPacket.NACK.MediaSSRC)
798 {
799 // Not to us.
800 rtcpParser.Iterate();
801 return;
802 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000803 rtcpPacketInformation.ResetNACKPacketIdArray();
804
805 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
806 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
807 {
808 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
809 pktType = rtcpParser.Iterate();
810 }
811}
812
813// no need for critsect we have _criticalSectionRTCPReceiver
814void
815RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
816 RTCPPacketInformation& rtcpPacketInformation)
817{
818 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
819
820 WebRtc_UWord16 bitMask = rtcpPacket.NACKItem.BitMask;
821 if(bitMask)
822 {
823 for(int i=1; i <= 16; ++i)
824 {
825 if(bitMask & 0x01)
826 {
827 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
828 }
829 bitMask = bitMask >>1;
830 }
831 }
832
833 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
834}
835
836// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000837void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
838 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000839
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000840 // clear our lists
841 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
842 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::iterator
843 reportBlockInfoIt = _receivedReportBlockMap.find(
844 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000845
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000846 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
847 delete reportBlockInfoIt->second;
848 _receivedReportBlockMap.erase(reportBlockInfoIt);
849 }
850 // we can't delete it due to TMMBR
851 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
852 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000853
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000854 if (receiveInfoIt != _receivedInfoMap.end()) {
855 receiveInfoIt->second->readyForDelete = true;
856 }
857
858 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator cnameInfoIt =
859 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
860
861 if (cnameInfoIt != _receivedCnameMap.end()) {
862 delete cnameInfoIt->second;
863 _receivedCnameMap.erase(cnameInfoIt);
864 }
865 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000866}
867
868// no need for critsect we have _criticalSectionRTCPReceiver
869void
870RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
871 RTCPPacketInformation& rtcpPacketInformation)
872{
873 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
874
875 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
876
877 if(rtcpPacket.XRVOIPMetricItem.SSRC == _SSRC)
878 {
879 // Store VoIP metrics block if it's about me
880 // from OriginatorSSRC do we filter it?
881 // rtcpPacket.XR.OriginatorSSRC;
882
883 RTCPVoIPMetric receivedVoIPMetrics;
884 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
885 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
886 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
887 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
888 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
889 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
890 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
891 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
892 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
893 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
894 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
895 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
896 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
897 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
898 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
899 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
900 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
901 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
902 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
903 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
904
905 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
906
907 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
908 }
909 rtcpParser.Iterate();
910}
911
912// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000913void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
914 RTCPPacketInformation& rtcpPacketInformation) {
915 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
916 if (_SSRC == rtcpPacket.PLI.MediaSSRC) {
917 // Received a signal that we need to send a new key frame.
918 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
919 }
920 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000921}
922
923// no need for critsect we have _criticalSectionRTCPReceiver
924void
925RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
926 RTCPPacketInformation& rtcpPacketInformation)
927{
928 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
929
930 WebRtc_UWord32 senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
931 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
932 if (ptrReceiveInfo == NULL)
933 {
934 // This remote SSRC must be saved before.
935 rtcpParser.Iterate();
936 return;
937 }
938 if(rtcpPacket.TMMBR.MediaSSRC)
939 {
940 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
941 // in relay mode this is a valid number
942 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
943 }
944
945 // Use packet length to calc max number of TMMBR blocks
946 // each TMMBR block is 8 bytes
947 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
948
949 // sanity
950 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
951 {
952 assert(false);
953 rtcpParser.Iterate();
954 return;
955 }
956 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((WebRtc_UWord32)maxNumOfTMMBRBlocks);
957
958 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
959 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
960 {
961 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
962 pktType = rtcpParser.Iterate();
963 }
964}
965
966// no need for critsect we have _criticalSectionRTCPReceiver
967void
968RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
969 const RTCPUtility::RTCPPacket& rtcpPacket,
970 RTCPPacketInformation& rtcpPacketInformation,
971 const WebRtc_UWord32 senderSSRC)
972{
973 if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
974 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
975 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000976 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000977 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +0000978 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
979 }
980}
981
982// no need for critsect we have _criticalSectionRTCPReceiver
983void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000984RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
985 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +0000986{
987 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
988 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
989 if (ptrReceiveInfo == NULL)
990 {
991 // This remote SSRC must be saved before.
992 rtcpParser.Iterate();
993 return;
994 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000995 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +0000996 // Use packet length to calc max number of TMMBN blocks
997 // each TMMBN block is 8 bytes
998 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
999
1000 // sanity
1001 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1002 {
1003 assert(false);
1004 rtcpParser.Iterate();
1005 return;
1006 }
1007
1008 ptrReceiveInfo->VerifyAndAllocateBoundingSet((WebRtc_UWord32)maxNumOfTMMBNBlocks);
1009
1010 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1011 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1012 {
1013 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1014 pktType = rtcpParser.Iterate();
1015 }
1016}
1017
1018// no need for critsect we have _criticalSectionRTCPReceiver
1019void
1020RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1021 RTCPPacketInformation& rtcpPacketInformation)
1022{
1023 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1024 rtcpParser.Iterate();
1025}
1026
1027// no need for critsect we have _criticalSectionRTCPReceiver
1028void
1029RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1030 const RTCPUtility::RTCPPacket& rtcpPacket)
1031{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001032 receiveInfo.TmmbnBoundingSet.AddEntry(
1033 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1034 rtcpPacket.TMMBNItem.MeasuredOverhead,
1035 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001036}
1037
1038// no need for critsect we have _criticalSectionRTCPReceiver
1039void
1040RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1041 RTCPPacketInformation& rtcpPacketInformation)
1042{
1043 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001044 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1045 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1046 {
1047 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1048 pktType = rtcpParser.Iterate();
1049 }
1050}
1051
1052// no need for critsect we have _criticalSectionRTCPReceiver
1053void
1054RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1055 RTCPPacketInformation& rtcpPacketInformation)
1056{
1057 // in theory there could be multiple slices lost
1058 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1059 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1060}
1061
1062void
1063RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1064 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1065{
1066 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001067 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1068 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1069 {
1070 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1071 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1072 {
1073 // to us unknown
1074 // continue
1075 rtcpParser.Iterate();
1076 return;
1077 }
1078 rtcpPacketInformation.rpsiPictureId = 0;
1079
1080 // convert NativeBitString to rpsiPictureId
1081 WebRtc_UWord8 numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1082 for(WebRtc_UWord8 n = 0; n < (numberOfBytes-1); n++)
1083 {
1084 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1085 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1086 }
1087 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1088 }
1089}
1090
1091// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001092void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1093 RTCPPacketInformation& rtcpPacketInformation) {
1094 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1095 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1096 pktType = rtcpParser.Iterate();
1097 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1098 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1099 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001100 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001101 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001102}
1103
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001104// no need for critsect we have _criticalSectionRTCPReceiver
1105void
1106RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1107 RTCPPacketInformation& rtcpPacketInformation)
1108{
1109 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1110
1111 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1112 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1113 {
1114 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1115 pktType = rtcpParser.Iterate();
1116 }
1117}
1118
1119void
1120RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1121 RTCPPacketInformation& rtcpPacketInformation)
1122{
1123 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1124 rtcpPacketInformation.interArrivalJitter =
1125 rtcpPacket.ExtendedJitterReportItem.Jitter;
1126}
1127
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001128void RTCPReceiver::HandleREMBItem(
1129 RTCPUtility::RTCPParserV2& rtcpParser,
1130 RTCPPacketInformation& rtcpPacketInformation) {
1131 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1132 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1133 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1134 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001135}
1136
1137// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001138void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1139 RTCPPacketInformation& rtcpPacketInformation) {
1140 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1141 RTCPReceiveInformation* ptrReceiveInfo =
1142 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001143
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001144 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1145 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1146 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1147 pktType = rtcpParser.Iterate();
1148 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001149}
1150
1151// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001152void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1153 const RTCPUtility::RTCPPacket& rtcpPacket,
1154 RTCPPacketInformation& rtcpPacketInformation) {
1155 // Is it our sender that is requested to generate a new keyframe
1156 if (_SSRC != rtcpPacket.FIRItem.SSRC) {
1157 return;
1158 }
1159 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1160 // we don't know who this originate from
1161 if (receiveInfo) {
1162 // check if we have reported this FIRSequenceNumber before
1163 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1164 receiveInfo->lastFIRSequenceNumber) {
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001165 WebRtc_Word64 now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001166 // sanity; don't go crazy with the callbacks
1167 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1168 receiveInfo->lastFIRRequest = now;
1169 receiveInfo->lastFIRSequenceNumber =
1170 rtcpPacket.FIRItem.CommandSequenceNumber;
1171 // received signal that we need to send a new key frame
1172 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1173 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001174 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001175 } else {
1176 // received signal that we need to send a new key frame
1177 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1178 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001179}
1180
1181void
1182RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1183 RTCPPacketInformation& rtcpPacketInformation)
1184{
1185 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1186
1187 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1188 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1189 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1190
1191 rtcpParser.Iterate();
1192}
1193
1194void
1195RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1196 RTCPPacketInformation& rtcpPacketInformation)
1197{
1198 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1199
1200 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1201
1202 rtcpParser.Iterate();
1203}
1204
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001205WebRtc_Word32 RTCPReceiver::UpdateTMMBR() {
1206 WebRtc_Word32 numBoundingSet = 0;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001207 WebRtc_UWord32 bitrate = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001208 WebRtc_UWord32 accNumCandidates = 0;
1209
1210 WebRtc_Word32 size = TMMBRReceived(0, 0, NULL);
1211 if (size > 0) {
1212 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1213 // Get candidate set from receiver.
1214 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1215 } else {
1216 // Candidate set empty.
1217 VerifyAndAllocateCandidateSet(0); // resets candidate set
1218 }
1219 // Find bounding set
1220 TMMBRSet* boundingSet = NULL;
1221 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1222 if (numBoundingSet == -1) {
1223 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1224 "Failed to find TMMBR bounding set.");
1225 return -1;
1226 }
1227 // Set bounding set
1228 // Inform remote clients about the new bandwidth
1229 // inform the remote client
1230 _rtpRtcp.SetTMMBN(boundingSet);
1231
1232 // might trigger a TMMBN
1233 if (numBoundingSet == 0) {
1234 // owner of max bitrate request has timed out
1235 // empty bounding set has been sent
1236 return 0;
1237 }
1238 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001239 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001240 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001241 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1242 if (_cbRtcpBandwidthObserver) {
1243 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1244 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1245 "Set TMMBR request:%d kbps", bitrate);
1246 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001247 }
1248 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001249}
1250
1251// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001252void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001253 RTCPPacketInformation& rtcpPacketInformation) {
1254 // Process TMMBR and REMB first to avoid multiple callbacks
1255 // to OnNetworkChanged.
1256 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1257 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1258 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001259
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001260 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1261 UpdateTMMBR();
1262 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001263 unsigned int local_ssrc = 0;
1264 {
1265 // We don't want to hold this critsect when triggering the callbacks below.
1266 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1267 local_ssrc = _SSRC;
1268 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001269 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1270 _rtpRtcp.OnRequestSendReport();
1271 }
1272 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001273 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001274 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1275 "SIG [RTCP] Incoming NACK length:%d",
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001276 rtcpPacketInformation.nackSequenceNumbers.size());
1277 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001278 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001279 }
1280 {
1281 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001282
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001283 // We need feedback that we have received a report block(s) so that we
1284 // can generate a new packet in a conference relay scenario, one received
1285 // report can generate several RTCP packets, based on number relayed/mixed
1286 // a send report block should go out to all receivers.
1287 if (_cbRtcpIntraFrameObserver) {
1288 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1289 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1290 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1291 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1292 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1293 rtcpPacketInformation.remoteSSRC);
1294 } else {
1295 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1296 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1297 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001298 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001299 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001300 }
1301 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1302 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001303 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001304 }
1305 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1306 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001307 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001308 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001309 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001310 if (_cbRtcpBandwidthObserver) {
1311 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1312 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1313 "SIG [RTCP] Incoming REMB:%d",
1314 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1315 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1316 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1317 }
1318 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1319 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
1320 rtcpPacketInformation.reportBlock) {
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001321 WebRtc_Word64 now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001322 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
1323 rtcpPacketInformation.remoteSSRC,
1324 rtcpPacketInformation.fractionLost,
1325 rtcpPacketInformation.roundTripTime,
1326 rtcpPacketInformation.lastReceivedExtendedHighSeqNum,
1327 now);
1328 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001329 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001330 if(_cbRtcpFeedback) {
1331 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) {
1332 _cbRtcpFeedback->OnSendReportReceived(_id,
stefan@webrtc.org976a7e62012-09-21 13:20:21 +00001333 rtcpPacketInformation.remoteSSRC,
1334 rtcpPacketInformation.ntp_secs,
1335 rtcpPacketInformation.ntp_frac,
1336 rtcpPacketInformation.rtp_timestamp);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001337 } else {
1338 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1339 rtcpPacketInformation.remoteSSRC);
1340 }
1341 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1342 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1343 rtcpPacketInformation.VoIPMetric);
1344 }
1345 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1346 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1347 rtcpPacketInformation.applicationSubType,
1348 rtcpPacketInformation.applicationName,
1349 rtcpPacketInformation.applicationLength,
1350 rtcpPacketInformation.applicationData);
1351 }
1352 }
1353 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001354}
1355
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001356WebRtc_Word32 RTCPReceiver::CNAME(const WebRtc_UWord32 remoteSSRC,
1357 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001358 assert(cName);
1359
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001360 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1361 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001362 if (cnameInfo == NULL) {
1363 return -1;
1364 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001365 cName[RTCP_CNAME_SIZE - 1] = 0;
1366 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1367 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001368}
1369
1370// no callbacks allowed inside this function
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001371WebRtc_Word32 RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size,
1372 const WebRtc_UWord32 accNumCandidates,
1373 TMMBRSet* candidateSet) const {
1374 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001375
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001376 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::const_iterator
1377 receiveInfoIt = _receivedInfoMap.begin();
1378 if (receiveInfoIt == _receivedInfoMap.end()) {
1379 return -1;
1380 }
1381 WebRtc_UWord32 num = accNumCandidates;
1382 if (candidateSet) {
1383 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1384 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1385 if (receiveInfo == NULL) {
1386 return 0;
1387 }
1388 for (WebRtc_UWord32 i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001389 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001390 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001391 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001392 num++;
1393 }
1394 }
1395 receiveInfoIt++;
1396 }
1397 } else {
1398 while (receiveInfoIt != _receivedInfoMap.end()) {
1399 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1400 if(receiveInfo == NULL) {
1401 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1402 "%s failed to get RTCPReceiveInformation",
1403 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001404 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001405 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001406 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001407 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001408 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001409 }
1410 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001411}
1412
1413WebRtc_Word32
1414RTCPReceiver::SetPacketTimeout(const WebRtc_UWord32 timeoutMS)
1415{
1416 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1417 _packetTimeOutMS = timeoutMS;
1418 return 0;
1419}
1420
1421void RTCPReceiver::PacketTimeout()
1422{
1423 if(_packetTimeOutMS == 0)
1424 {
1425 // not configured
1426 return;
1427 }
1428
1429 bool packetTimeOut = false;
1430 {
1431 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1432 if(_lastReceived == 0)
1433 {
1434 // not active
1435 return;
1436 }
1437
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001438 WebRtc_Word64 now = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +00001439 if(now - _lastReceived > _packetTimeOutMS)
1440 {
1441 packetTimeOut = true;
1442 _lastReceived = 0; // only one callback
1443 }
1444 }
1445 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1446 if(packetTimeOut && _cbRtcpFeedback)
1447 {
1448 _cbRtcpFeedback->OnRTCPPacketTimeout(_id);
1449 }
1450}
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001451
niklase@google.com470e71d2011-07-07 08:21:25 +00001452} // namespace webrtc