blob: d05dd2d5cd25fa111b650f35e094e72101b5deaf [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 }
803
804 rtcpPacketInformation.ResetNACKPacketIdArray();
805
806 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
807 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
808 {
809 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
810 pktType = rtcpParser.Iterate();
811 }
812}
813
814// no need for critsect we have _criticalSectionRTCPReceiver
815void
816RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
817 RTCPPacketInformation& rtcpPacketInformation)
818{
819 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
820
821 WebRtc_UWord16 bitMask = rtcpPacket.NACKItem.BitMask;
822 if(bitMask)
823 {
824 for(int i=1; i <= 16; ++i)
825 {
826 if(bitMask & 0x01)
827 {
828 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
829 }
830 bitMask = bitMask >>1;
831 }
832 }
833
834 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
835}
836
837// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000838void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
839 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000840
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000841 // clear our lists
842 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
843 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::iterator
844 reportBlockInfoIt = _receivedReportBlockMap.find(
845 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000846
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000847 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
848 delete reportBlockInfoIt->second;
849 _receivedReportBlockMap.erase(reportBlockInfoIt);
850 }
851 // we can't delete it due to TMMBR
852 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
853 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000854
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000855 if (receiveInfoIt != _receivedInfoMap.end()) {
856 receiveInfoIt->second->readyForDelete = true;
857 }
858
859 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator cnameInfoIt =
860 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
861
862 if (cnameInfoIt != _receivedCnameMap.end()) {
863 delete cnameInfoIt->second;
864 _receivedCnameMap.erase(cnameInfoIt);
865 }
866 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000867}
868
869// no need for critsect we have _criticalSectionRTCPReceiver
870void
871RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
872 RTCPPacketInformation& rtcpPacketInformation)
873{
874 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
875
876 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
877
878 if(rtcpPacket.XRVOIPMetricItem.SSRC == _SSRC)
879 {
880 // Store VoIP metrics block if it's about me
881 // from OriginatorSSRC do we filter it?
882 // rtcpPacket.XR.OriginatorSSRC;
883
884 RTCPVoIPMetric receivedVoIPMetrics;
885 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
886 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
887 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
888 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
889 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
890 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
891 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
892 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
893 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
894 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
895 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
896 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
897 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
898 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
899 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
900 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
901 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
902 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
903 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
904 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
905
906 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
907
908 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
909 }
910 rtcpParser.Iterate();
911}
912
913// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000914void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
915 RTCPPacketInformation& rtcpPacketInformation) {
916 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
917 if (_SSRC == rtcpPacket.PLI.MediaSSRC) {
918 // Received a signal that we need to send a new key frame.
919 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
920 }
921 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000922}
923
924// no need for critsect we have _criticalSectionRTCPReceiver
925void
926RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
927 RTCPPacketInformation& rtcpPacketInformation)
928{
929 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
930
931 WebRtc_UWord32 senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
932 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
933 if (ptrReceiveInfo == NULL)
934 {
935 // This remote SSRC must be saved before.
936 rtcpParser.Iterate();
937 return;
938 }
939 if(rtcpPacket.TMMBR.MediaSSRC)
940 {
941 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
942 // in relay mode this is a valid number
943 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
944 }
945
946 // Use packet length to calc max number of TMMBR blocks
947 // each TMMBR block is 8 bytes
948 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
949
950 // sanity
951 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
952 {
953 assert(false);
954 rtcpParser.Iterate();
955 return;
956 }
957 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((WebRtc_UWord32)maxNumOfTMMBRBlocks);
958
959 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
960 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
961 {
962 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
963 pktType = rtcpParser.Iterate();
964 }
965}
966
967// no need for critsect we have _criticalSectionRTCPReceiver
968void
969RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
970 const RTCPUtility::RTCPPacket& rtcpPacket,
971 RTCPPacketInformation& rtcpPacketInformation,
972 const WebRtc_UWord32 senderSSRC)
973{
974 if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
975 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
976 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000977 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000978 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +0000979 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
980 }
981}
982
983// no need for critsect we have _criticalSectionRTCPReceiver
984void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000985RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
986 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +0000987{
988 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
989 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
990 if (ptrReceiveInfo == NULL)
991 {
992 // This remote SSRC must be saved before.
993 rtcpParser.Iterate();
994 return;
995 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000996 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +0000997 // Use packet length to calc max number of TMMBN blocks
998 // each TMMBN block is 8 bytes
999 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1000
1001 // sanity
1002 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1003 {
1004 assert(false);
1005 rtcpParser.Iterate();
1006 return;
1007 }
1008
1009 ptrReceiveInfo->VerifyAndAllocateBoundingSet((WebRtc_UWord32)maxNumOfTMMBNBlocks);
1010
1011 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1012 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1013 {
1014 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1015 pktType = rtcpParser.Iterate();
1016 }
1017}
1018
1019// no need for critsect we have _criticalSectionRTCPReceiver
1020void
1021RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1022 RTCPPacketInformation& rtcpPacketInformation)
1023{
1024 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1025 rtcpParser.Iterate();
1026}
1027
1028// no need for critsect we have _criticalSectionRTCPReceiver
1029void
1030RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1031 const RTCPUtility::RTCPPacket& rtcpPacket)
1032{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001033 receiveInfo.TmmbnBoundingSet.AddEntry(
1034 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1035 rtcpPacket.TMMBNItem.MeasuredOverhead,
1036 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001037}
1038
1039// no need for critsect we have _criticalSectionRTCPReceiver
1040void
1041RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1042 RTCPPacketInformation& rtcpPacketInformation)
1043{
1044 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001045 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1046 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1047 {
1048 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1049 pktType = rtcpParser.Iterate();
1050 }
1051}
1052
1053// no need for critsect we have _criticalSectionRTCPReceiver
1054void
1055RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1056 RTCPPacketInformation& rtcpPacketInformation)
1057{
1058 // in theory there could be multiple slices lost
1059 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1060 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1061}
1062
1063void
1064RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1065 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1066{
1067 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001068 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1069 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1070 {
1071 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1072 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1073 {
1074 // to us unknown
1075 // continue
1076 rtcpParser.Iterate();
1077 return;
1078 }
1079 rtcpPacketInformation.rpsiPictureId = 0;
1080
1081 // convert NativeBitString to rpsiPictureId
1082 WebRtc_UWord8 numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1083 for(WebRtc_UWord8 n = 0; n < (numberOfBytes-1); n++)
1084 {
1085 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1086 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1087 }
1088 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1089 }
1090}
1091
1092// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001093void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1094 RTCPPacketInformation& rtcpPacketInformation) {
1095 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1096 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1097 pktType = rtcpParser.Iterate();
1098 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1099 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1100 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001101 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001102 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001103}
1104
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001105// no need for critsect we have _criticalSectionRTCPReceiver
1106void
1107RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1108 RTCPPacketInformation& rtcpPacketInformation)
1109{
1110 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1111
1112 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1113 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1114 {
1115 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1116 pktType = rtcpParser.Iterate();
1117 }
1118}
1119
1120void
1121RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1122 RTCPPacketInformation& rtcpPacketInformation)
1123{
1124 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1125 rtcpPacketInformation.interArrivalJitter =
1126 rtcpPacket.ExtendedJitterReportItem.Jitter;
1127}
1128
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001129void RTCPReceiver::HandleREMBItem(
1130 RTCPUtility::RTCPParserV2& rtcpParser,
1131 RTCPPacketInformation& rtcpPacketInformation) {
1132 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1133 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1134 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1135 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001136}
1137
1138// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001139void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1140 RTCPPacketInformation& rtcpPacketInformation) {
1141 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1142 RTCPReceiveInformation* ptrReceiveInfo =
1143 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001144
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001145 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1146 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1147 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1148 pktType = rtcpParser.Iterate();
1149 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001150}
1151
1152// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001153void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1154 const RTCPUtility::RTCPPacket& rtcpPacket,
1155 RTCPPacketInformation& rtcpPacketInformation) {
1156 // Is it our sender that is requested to generate a new keyframe
1157 if (_SSRC != rtcpPacket.FIRItem.SSRC) {
1158 return;
1159 }
1160 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1161 // we don't know who this originate from
1162 if (receiveInfo) {
1163 // check if we have reported this FIRSequenceNumber before
1164 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1165 receiveInfo->lastFIRSequenceNumber) {
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001166 WebRtc_Word64 now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001167 // sanity; don't go crazy with the callbacks
1168 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1169 receiveInfo->lastFIRRequest = now;
1170 receiveInfo->lastFIRSequenceNumber =
1171 rtcpPacket.FIRItem.CommandSequenceNumber;
1172 // received signal that we need to send a new key frame
1173 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1174 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001175 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001176 } else {
1177 // received signal that we need to send a new key frame
1178 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1179 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001180}
1181
1182void
1183RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1184 RTCPPacketInformation& rtcpPacketInformation)
1185{
1186 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1187
1188 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1189 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1190 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1191
1192 rtcpParser.Iterate();
1193}
1194
1195void
1196RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1197 RTCPPacketInformation& rtcpPacketInformation)
1198{
1199 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1200
1201 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1202
1203 rtcpParser.Iterate();
1204}
1205
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001206WebRtc_Word32 RTCPReceiver::UpdateTMMBR() {
1207 WebRtc_Word32 numBoundingSet = 0;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001208 WebRtc_UWord32 bitrate = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001209 WebRtc_UWord32 accNumCandidates = 0;
1210
1211 WebRtc_Word32 size = TMMBRReceived(0, 0, NULL);
1212 if (size > 0) {
1213 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1214 // Get candidate set from receiver.
1215 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1216 } else {
1217 // Candidate set empty.
1218 VerifyAndAllocateCandidateSet(0); // resets candidate set
1219 }
1220 // Find bounding set
1221 TMMBRSet* boundingSet = NULL;
1222 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1223 if (numBoundingSet == -1) {
1224 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1225 "Failed to find TMMBR bounding set.");
1226 return -1;
1227 }
1228 // Set bounding set
1229 // Inform remote clients about the new bandwidth
1230 // inform the remote client
1231 _rtpRtcp.SetTMMBN(boundingSet);
1232
1233 // might trigger a TMMBN
1234 if (numBoundingSet == 0) {
1235 // owner of max bitrate request has timed out
1236 // empty bounding set has been sent
1237 return 0;
1238 }
1239 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001240 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001241 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001242 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1243 if (_cbRtcpBandwidthObserver) {
1244 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1245 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1246 "Set TMMBR request:%d kbps", bitrate);
1247 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001248 }
1249 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001250}
1251
1252// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001253void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001254 RTCPPacketInformation& rtcpPacketInformation) {
1255 // Process TMMBR and REMB first to avoid multiple callbacks
1256 // to OnNetworkChanged.
1257 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1258 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1259 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001260
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001261 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1262 UpdateTMMBR();
1263 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001264 unsigned int local_ssrc = 0;
1265 {
1266 // We don't want to hold this critsect when triggering the callbacks below.
1267 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1268 local_ssrc = _SSRC;
1269 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001270 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1271 _rtpRtcp.OnRequestSendReport();
1272 }
1273 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
1274 if (rtcpPacketInformation.nackSequenceNumbersLength > 0) {
1275 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1276 "SIG [RTCP] Incoming NACK length:%d",
1277 rtcpPacketInformation.nackSequenceNumbersLength);
1278 _rtpRtcp.OnReceivedNACK(
1279 rtcpPacketInformation.nackSequenceNumbersLength,
1280 rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001281 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001282 }
1283 {
1284 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001285
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001286 // We need feedback that we have received a report block(s) so that we
1287 // can generate a new packet in a conference relay scenario, one received
1288 // report can generate several RTCP packets, based on number relayed/mixed
1289 // a send report block should go out to all receivers.
1290 if (_cbRtcpIntraFrameObserver) {
1291 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1292 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1293 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1294 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1295 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1296 rtcpPacketInformation.remoteSSRC);
1297 } else {
1298 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1299 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1300 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001301 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001302 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001303 }
1304 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1305 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001306 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001307 }
1308 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1309 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001310 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001311 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001312 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001313 if (_cbRtcpBandwidthObserver) {
1314 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1315 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1316 "SIG [RTCP] Incoming REMB:%d",
1317 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1318 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1319 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1320 }
1321 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1322 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
1323 rtcpPacketInformation.reportBlock) {
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001324 WebRtc_Word64 now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001325 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
1326 rtcpPacketInformation.remoteSSRC,
1327 rtcpPacketInformation.fractionLost,
1328 rtcpPacketInformation.roundTripTime,
1329 rtcpPacketInformation.lastReceivedExtendedHighSeqNum,
1330 now);
1331 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001332 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001333 if(_cbRtcpFeedback) {
1334 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) {
1335 _cbRtcpFeedback->OnSendReportReceived(_id,
stefan@webrtc.org976a7e62012-09-21 13:20:21 +00001336 rtcpPacketInformation.remoteSSRC,
1337 rtcpPacketInformation.ntp_secs,
1338 rtcpPacketInformation.ntp_frac,
1339 rtcpPacketInformation.rtp_timestamp);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001340 } else {
1341 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1342 rtcpPacketInformation.remoteSSRC);
1343 }
1344 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1345 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1346 rtcpPacketInformation.VoIPMetric);
1347 }
1348 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1349 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1350 rtcpPacketInformation.applicationSubType,
1351 rtcpPacketInformation.applicationName,
1352 rtcpPacketInformation.applicationLength,
1353 rtcpPacketInformation.applicationData);
1354 }
1355 }
1356 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001357}
1358
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001359WebRtc_Word32 RTCPReceiver::CNAME(const WebRtc_UWord32 remoteSSRC,
1360 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001361 assert(cName);
1362
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001363 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1364 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001365 if (cnameInfo == NULL) {
1366 return -1;
1367 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001368 cName[RTCP_CNAME_SIZE - 1] = 0;
1369 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1370 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001371}
1372
1373// no callbacks allowed inside this function
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001374WebRtc_Word32 RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size,
1375 const WebRtc_UWord32 accNumCandidates,
1376 TMMBRSet* candidateSet) const {
1377 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001378
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001379 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::const_iterator
1380 receiveInfoIt = _receivedInfoMap.begin();
1381 if (receiveInfoIt == _receivedInfoMap.end()) {
1382 return -1;
1383 }
1384 WebRtc_UWord32 num = accNumCandidates;
1385 if (candidateSet) {
1386 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1387 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1388 if (receiveInfo == NULL) {
1389 return 0;
1390 }
1391 for (WebRtc_UWord32 i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001392 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001393 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001394 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001395 num++;
1396 }
1397 }
1398 receiveInfoIt++;
1399 }
1400 } else {
1401 while (receiveInfoIt != _receivedInfoMap.end()) {
1402 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1403 if(receiveInfo == NULL) {
1404 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1405 "%s failed to get RTCPReceiveInformation",
1406 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001407 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001408 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001409 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001410 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001411 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001412 }
1413 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001414}
1415
1416WebRtc_Word32
1417RTCPReceiver::SetPacketTimeout(const WebRtc_UWord32 timeoutMS)
1418{
1419 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1420 _packetTimeOutMS = timeoutMS;
1421 return 0;
1422}
1423
1424void RTCPReceiver::PacketTimeout()
1425{
1426 if(_packetTimeOutMS == 0)
1427 {
1428 // not configured
1429 return;
1430 }
1431
1432 bool packetTimeOut = false;
1433 {
1434 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1435 if(_lastReceived == 0)
1436 {
1437 // not active
1438 return;
1439 }
1440
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001441 WebRtc_Word64 now = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +00001442 if(now - _lastReceived > _packetTimeOutMS)
1443 {
1444 packetTimeOut = true;
1445 _lastReceived = 0; // only one callback
1446 }
1447 }
1448 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1449 if(packetTimeOut && _cbRtcpFeedback)
1450 {
1451 _cbRtcpFeedback->OnRTCPPacketTimeout(_id);
1452 }
1453}
1454} // namespace webrtc