blob: e78f53a31695cb2babae13292ccc17b5f9383540 [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
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000030RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id, RtpRtcpClock* clock,
31 ModuleRtpRtcpImpl* owner)
32 : TMMBRHelp(),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000033 _id(id),
34 _clock(*clock),
35 _method(kRtcpOff),
36 _lastReceived(0),
37 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000038 _criticalSectionFeedbacks(
39 CriticalSectionWrapper::CreateCriticalSection()),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000040 _cbRtcpFeedback(NULL),
41 _cbRtcpBandwidthObserver(NULL),
42 _cbRtcpIntraFrameObserver(NULL),
43 _criticalSectionRTCPReceiver(
44 CriticalSectionWrapper::CreateCriticalSection()),
45 _SSRC(0),
46 _remoteSSRC(0),
47 _remoteSenderInfo(),
48 _lastReceivedSRNTPsecs(0),
49 _lastReceivedSRNTPfrac(0),
50 _receivedInfoMap(),
51 _packetTimeOutMS(0),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000052 _rtt(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +000053 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
54 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
55}
56
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000057RTCPReceiver::~RTCPReceiver() {
58 delete _criticalSectionRTCPReceiver;
59 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000060
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000061 while (!_receivedReportBlockMap.empty()) {
62 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::iterator first =
63 _receivedReportBlockMap.begin();
64 delete first->second;
65 _receivedReportBlockMap.erase(first);
66 }
67 while (!_receivedInfoMap.empty()) {
68 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator first =
69 _receivedInfoMap.begin();
70 delete first->second;
71 _receivedInfoMap.erase(first);
72 }
73 while (!_receivedCnameMap.empty()) {
74 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator first =
75 _receivedCnameMap.begin();
76 delete first->second;
77 _receivedCnameMap.erase(first);
78 }
79 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id,
80 "%s deleted", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +000081}
82
83void
84RTCPReceiver::ChangeUniqueId(const WebRtc_Word32 id)
85{
86 _id = id;
87}
88
89RTCPMethod
90RTCPReceiver::Status() const
91{
92 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
93 return _method;
94}
95
96WebRtc_Word32
97RTCPReceiver::SetRTCPStatus(const RTCPMethod method)
98{
99 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
100 _method = method;
101 return 0;
102}
103
104WebRtc_UWord32
105RTCPReceiver::LastReceived()
106{
107 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
108 return _lastReceived;
109}
110
111WebRtc_Word32
112RTCPReceiver::SetRemoteSSRC( const WebRtc_UWord32 ssrc)
113{
114 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
115
116 // new SSRC reset old reports
117 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
118 _lastReceivedSRNTPsecs = 0;
119 _lastReceivedSRNTPfrac = 0;
120
121 _remoteSSRC = ssrc;
122 return 0;
123}
124
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000125void RTCPReceiver::RegisterRtcpObservers(
126 RtcpIntraFrameObserver* intra_frame_callback,
127 RtcpBandwidthObserver* bandwidth_callback,
128 RtcpFeedback* feedback_callback) {
129 CriticalSectionScoped lock(_criticalSectionFeedbacks);
130 _cbRtcpIntraFrameObserver = intra_frame_callback;
131 _cbRtcpBandwidthObserver = bandwidth_callback;
132 _cbRtcpFeedback = feedback_callback;
niklase@google.com470e71d2011-07-07 08:21:25 +0000133}
134
niklase@google.com470e71d2011-07-07 08:21:25 +0000135
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000136void RTCPReceiver::SetSSRC( const WebRtc_UWord32 ssrc) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000137 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
138 _SSRC = ssrc;
139}
140
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000141WebRtc_Word32 RTCPReceiver::ResetRTT(const WebRtc_UWord32 remoteSSRC) {
142 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
143 RTCPReportBlockInformation* reportBlock =
144 GetReportBlockInformation(remoteSSRC);
145 if (reportBlock == NULL) {
146 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
147 "\tfailed to GetReportBlockInformation(%u)", remoteSSRC);
148 return -1;
149 }
150 reportBlock->RTT = 0;
151 reportBlock->avgRTT = 0;
152 reportBlock->minRTT = 0;
153 reportBlock->maxRTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000154 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000155}
156
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000157WebRtc_Word32 RTCPReceiver::RTT(const WebRtc_UWord32 remoteSSRC,
158 WebRtc_UWord16* RTT,
159 WebRtc_UWord16* avgRTT,
160 WebRtc_UWord16* minRTT,
161 WebRtc_UWord16* maxRTT) const {
162 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000163
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000164 RTCPReportBlockInformation* reportBlock =
165 GetReportBlockInformation(remoteSSRC);
166
167 if (reportBlock == NULL) {
168 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
169 "\tfailed to GetReportBlockInformation(%u)",
170 remoteSSRC);
171 return -1;
172 }
173 if (RTT) {
174 *RTT = reportBlock->RTT;
175 }
176 if (avgRTT) {
177 *avgRTT = reportBlock->avgRTT;
178 }
179 if (minRTT) {
180 *minRTT = reportBlock->minRTT;
181 }
182 if (maxRTT) {
183 *maxRTT = reportBlock->maxRTT;
184 }
185 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000186}
187
mflodman@webrtc.orgd7d46882012-02-14 12:49:59 +0000188WebRtc_UWord16 RTCPReceiver::RTT() const {
189 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
190 if (!_receivedReportBlockMap.empty()) {
191 return 0;
192 }
193 return _rtt;
194}
195
196int RTCPReceiver::SetRTT(WebRtc_UWord16 rtt) {
197 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
198 if (!_receivedReportBlockMap.empty()) {
199 return -1;
200 }
201 _rtt = rtt;
202 return 0;
203}
204
niklase@google.com470e71d2011-07-07 08:21:25 +0000205void
206RTCPReceiver::UpdateLipSync(const WebRtc_Word32 audioVideoOffset) const
207{
208 CriticalSectionScoped lock(_criticalSectionFeedbacks);
209 if(_cbRtcpFeedback)
210 {
211 _cbRtcpFeedback->OnLipSyncUpdate(_id,audioVideoOffset);
212 }
213};
214
215WebRtc_Word32
216RTCPReceiver::NTP(WebRtc_UWord32 *ReceivedNTPsecs,
217 WebRtc_UWord32 *ReceivedNTPfrac,
218 WebRtc_UWord32 *RTCPArrivalTimeSecs,
219 WebRtc_UWord32 *RTCPArrivalTimeFrac) const
220{
221 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
222 if(ReceivedNTPsecs)
223 {
224 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
225 }
226 if(ReceivedNTPfrac)
227 {
228 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
229 }
230 if(RTCPArrivalTimeFrac)
231 {
232 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
233 }
234 if(RTCPArrivalTimeSecs)
235 {
236 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
237 }
238 return 0;
239}
240
241WebRtc_Word32
242RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
243{
244 if(senderInfo == NULL)
245 {
246 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
247 return -1;
248 }
249 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
250 if(_lastReceivedSRNTPsecs == 0)
251 {
252 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
253 return -1;
254 }
255 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
256 return 0;
257}
258
259// statistics
260// we can get multiple receive reports when we receive the report from a CE
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000261WebRtc_Word32 RTCPReceiver::StatisticsReceived(
262 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000263 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000264 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
265
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000266 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::const_iterator it =
267 _receivedReportBlockMap.begin();
268
269 while (it != _receivedReportBlockMap.end()) {
270 receiveBlocks->push_back(it->second->remoteReceiveBlock);
271 it++;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000272 }
273 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000274}
275
276WebRtc_Word32
277RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
278 RTCPUtility::RTCPParserV2* rtcpParser)
279{
280 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
281
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000282 _lastReceived = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +0000283
284 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
285 while (pktType != RTCPUtility::kRtcpNotValidCode)
286 {
287 // Each "case" is responsible for iterate the parser to the
288 // next top level packet.
289 switch (pktType)
290 {
291 case RTCPUtility::kRtcpSrCode:
292 case RTCPUtility::kRtcpRrCode:
293 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
294 break;
295 case RTCPUtility::kRtcpSdesCode:
296 HandleSDES(*rtcpParser);
297 break;
298 case RTCPUtility::kRtcpXrVoipMetricCode:
299 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
300 break;
301 case RTCPUtility::kRtcpByeCode:
302 HandleBYE(*rtcpParser);
303 break;
304 case RTCPUtility::kRtcpRtpfbNackCode:
305 HandleNACK(*rtcpParser, rtcpPacketInformation);
306 break;
307 case RTCPUtility::kRtcpRtpfbTmmbrCode:
308 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
309 break;
310 case RTCPUtility::kRtcpRtpfbTmmbnCode:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000311 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000312 break;
313 case RTCPUtility::kRtcpRtpfbSrReqCode:
314 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
315 break;
316 case RTCPUtility::kRtcpPsfbPliCode:
317 HandlePLI(*rtcpParser, rtcpPacketInformation);
318 break;
319 case RTCPUtility::kRtcpPsfbSliCode:
320 HandleSLI(*rtcpParser, rtcpPacketInformation);
321 break;
322 case RTCPUtility::kRtcpPsfbRpsiCode:
323 HandleRPSI(*rtcpParser, rtcpPacketInformation);
324 break;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000325 case RTCPUtility::kRtcpExtendedIjCode:
326 HandleIJ(*rtcpParser, rtcpPacketInformation);
327 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 case RTCPUtility::kRtcpPsfbFirCode:
329 HandleFIR(*rtcpParser, rtcpPacketInformation);
330 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000331 case RTCPUtility::kRtcpPsfbAppCode:
332 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
333 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 case RTCPUtility::kRtcpAppCode:
335 // generic application messages
336 HandleAPP(*rtcpParser, rtcpPacketInformation);
337 break;
338 case RTCPUtility::kRtcpAppItemCode:
339 // generic application messages
340 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
341 break;
342 default:
343 rtcpParser->Iterate();
344 break;
345 }
346 pktType = rtcpParser->PacketType();
347 }
348 return 0;
349}
350
351// no need for critsect we have _criticalSectionRTCPReceiver
352void
353RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
354 RTCPPacketInformation& rtcpPacketInformation)
355{
356 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
357 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
358
359 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
360
361 // SR.SenderSSRC
362 // The synchronization source identifier for the originator of this SR packet
363
364 // rtcpPacket.RR.SenderSSRC
365 // The source of the packet sender, same as of SR? or is this a CE?
366
367 const WebRtc_UWord32 remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
368 const WebRtc_UWord8 numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
369
370 rtcpPacketInformation.remoteSSRC = remoteSSRC;
371
372 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
373 if (!ptrReceiveInfo)
374 {
375 rtcpParser.Iterate();
376 return;
377 }
378
379 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
380 {
381 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
382 "Received SR(%d). SSRC:0x%x, from SSRC:0x%x, to us %d.", _id, _SSRC, remoteSSRC, (_remoteSSRC == remoteSSRC)?1:0);
383
384 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
385 {
386 // only signal that we have received a SR when we accept one
387 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
388
389 // We will only store the send report from one source, but
390 // we will store all the receive block
391
392 // Save the NTP time of this report
393 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
394 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
395 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
396 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
397 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
398
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000399 _clock.CurrentNTP(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000400 }
401 else
402 {
403 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
404 }
405 } else
406 {
407 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
408 "Received RR(%d). SSRC:0x%x, from SSRC:0x%x", _id, _SSRC, remoteSSRC);
409
410 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
411 }
412 UpdateReceiveInformation(*ptrReceiveInfo);
413
414 rtcpPacketType = rtcpParser.Iterate();
415
416 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
417 {
418 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
419 rtcpPacketType = rtcpParser.Iterate();
420 }
421}
422
423// no need for critsect we have _criticalSectionRTCPReceiver
424void
425RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
426 RTCPPacketInformation& rtcpPacketInformation,
427 const WebRtc_UWord32 remoteSSRC,
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000428 const WebRtc_UWord8 numberOfReportBlocks) {
429 // This will be called once per report block in the RTCP packet.
430 // We filter out all report blocks that are not for us.
431 // Each packet has max 31 RR blocks.
432 //
433 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000434
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000435 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
436 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000437
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000438 // Filter out all report blocks that are not for us.
439 if (rtcpPacket.ReportBlockItem.SSRC != _SSRC) {
440 // This block is not for us ignore it.
441 return;
442 }
443
444 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
445 // _criticalSectionRTCPReceiver.
446 _criticalSectionRTCPReceiver->Leave();
447 WebRtc_UWord32 sendTimeMS =
448 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
449 _criticalSectionRTCPReceiver->Enter();
450
451 RTCPReportBlockInformation* reportBlock =
452 CreateReportBlockInformation(remoteSSRC);
453 if (reportBlock == NULL) {
454 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
455 "\tfailed to CreateReportBlockInformation(%u)", remoteSSRC);
456 return;
457 }
458 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
459 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
460 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
461 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
462 reportBlock->remoteReceiveBlock.cumulativeLost =
463 rb.CumulativeNumOfPacketsLost;
464 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
465 rb.ExtendedHighestSequenceNumber;
466 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
467 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
468 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
469
470 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
471 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
472 }
473
474 WebRtc_UWord32 delaySinceLastSendReport =
475 rtcpPacket.ReportBlockItem.DelayLastSR;
476
477 // local NTP time when we received this
478 WebRtc_UWord32 lastReceivedRRNTPsecs = 0;
479 WebRtc_UWord32 lastReceivedRRNTPfrac = 0;
480
481 _clock.CurrentNTP(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
482
483 // time when we received this in MS
484 WebRtc_UWord32 receiveTimeMS = ModuleRTPUtility::ConvertNTPTimeToMS(
485 lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
486
487 // Estimate RTT
488 WebRtc_UWord32 d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
489 d /= 65536;
490 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
491
492 WebRtc_Word32 RTT = 0;
493
494 if (sendTimeMS > 0) {
495 RTT = receiveTimeMS - d - sendTimeMS;
496 if (RTT <= 0) {
497 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000498 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000499 if (RTT > reportBlock->maxRTT) {
500 // store max RTT
501 reportBlock->maxRTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000502 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000503 if (reportBlock->minRTT == 0) {
504 // first RTT
505 reportBlock->minRTT = (WebRtc_UWord16) RTT;
506 } else if (RTT < reportBlock->minRTT) {
507 // Store min RTT
508 reportBlock->minRTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000509 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000510 // store last RTT
511 reportBlock->RTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000512
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000513 // store average RTT
514 if (reportBlock->numAverageCalcs != 0) {
515 float ac = static_cast<float> (reportBlock->numAverageCalcs);
516 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
517 + ((1 / (ac + 1)) * RTT);
518 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
519 } else {
520 // first RTT
521 reportBlock->avgRTT = (WebRtc_UWord16) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000522 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000523 reportBlock->numAverageCalcs++;
524 }
525
526 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
527 " -> Received report block(%d), from SSRC:0x%x, RTT:%d, loss:%d",
528 _id, remoteSSRC, RTT, rtcpPacket.ReportBlockItem.FractionLost);
529
530 // rtcpPacketInformation
531 rtcpPacketInformation.AddReportInfo(
532 reportBlock->remoteReceiveBlock.fractionLost, (WebRtc_UWord16) RTT,
533 reportBlock->remoteReceiveBlock.extendedHighSeqNum,
534 reportBlock->remoteReceiveBlock.jitter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000535}
536
537RTCPReportBlockInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000538RTCPReceiver::CreateReportBlockInformation(WebRtc_UWord32 remoteSSRC) {
539 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000540
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000541 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::iterator it =
542 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000543
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000544 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
545 if (it != _receivedReportBlockMap.end()) {
546 ptrReportBlockInfo = it->second;
547 } else {
548 ptrReportBlockInfo = new RTCPReportBlockInformation;
549 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
550 }
551 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000552}
553
554RTCPReportBlockInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000555RTCPReceiver::GetReportBlockInformation(WebRtc_UWord32 remoteSSRC) const {
556 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000557
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000558 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::const_iterator it =
559 _receivedReportBlockMap.find(remoteSSRC);
560
561 if (it == _receivedReportBlockMap.end()) {
562 return NULL;
563 }
564 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000565}
566
567RTCPCnameInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000568RTCPReceiver::CreateCnameInformation(WebRtc_UWord32 remoteSSRC) {
569 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000570
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000571 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator it =
572 _receivedCnameMap.find(remoteSSRC);
573
574 if (it != _receivedCnameMap.end()) {
575 return it->second;
576 }
577 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000578 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000579 _receivedCnameMap[remoteSSRC] = cnameInfo;
580 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000581}
582
583RTCPCnameInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000584RTCPReceiver::GetCnameInformation(WebRtc_UWord32 remoteSSRC) const {
585 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000586
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000587 std::map<WebRtc_UWord32, RTCPCnameInformation*>::const_iterator it =
588 _receivedCnameMap.find(remoteSSRC);
589
590 if (it == _receivedCnameMap.end()) {
591 return NULL;
592 }
593 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000594}
595
596RTCPReceiveInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000597RTCPReceiver::CreateReceiveInformation(WebRtc_UWord32 remoteSSRC) {
598 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000599
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000600 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator it =
601 _receivedInfoMap.find(remoteSSRC);
602
603 if (it != _receivedInfoMap.end()) {
604 return it->second;
605 }
606 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
607 _receivedInfoMap[remoteSSRC] = receiveInfo;
608 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000609}
610
611RTCPReceiveInformation*
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000612RTCPReceiver::GetReceiveInformation(WebRtc_UWord32 remoteSSRC) {
613 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000614
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000615 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator it =
616 _receivedInfoMap.find(remoteSSRC);
617 if (it == _receivedInfoMap.end()) {
618 return NULL;
619 }
620 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000621}
622
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000623void RTCPReceiver::UpdateReceiveInformation(
624 RTCPReceiveInformation& receiveInformation) {
625 // Update that this remote is alive
626 receiveInformation.lastTimeReceived = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +0000627}
628
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000629bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
630 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000631
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000632 bool updateBoundingSet = false;
633 WebRtc_UWord32 timeNow = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +0000634
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000635 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
636 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000637
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000638 while (receiveInfoIt != _receivedInfoMap.end()) {
639 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
640 if (receiveInfo == NULL) {
641 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000642 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000643 // time since last received rtcp packet
644 // when we dont have a lastTimeReceived and the object is marked
645 // readyForDelete it's removed from the map
646 if (receiveInfo->lastTimeReceived) {
647 /// use audio define since we don't know what interval the remote peer is
648 // using
649 if ((timeNow - receiveInfo->lastTimeReceived) >
650 5 * RTCP_INTERVAL_AUDIO_MS) {
651 // no rtcp packet for the last five regular intervals, reset limitations
652 receiveInfo->TmmbrSet.lengthOfSet = 0;
653 // prevent that we call this over and over again
654 receiveInfo->lastTimeReceived = 0;
655 // send new TMMBN to all channels using the default codec
656 updateBoundingSet = true;
657 }
658 receiveInfoIt++;
659 } else if (receiveInfo->readyForDelete) {
660 // store our current receiveInfoItem
661 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator
662 receiveInfoItemToBeErased = receiveInfoIt;
663 receiveInfoIt++;
664 delete receiveInfoItemToBeErased->second;
665 _receivedInfoMap.erase(receiveInfoItemToBeErased);
666 } else {
667 receiveInfoIt++;
668 }
669 }
670 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000671}
672
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000673WebRtc_Word32 RTCPReceiver::BoundingSet(bool &tmmbrOwner,
674 TMMBRSet*& boundingSetRec) {
675 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000676
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000677 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
678 _receivedInfoMap.find(_remoteSSRC);
679
680 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000681 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000682 }
683 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
684 if (receiveInfo == NULL) {
685 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
686 "%s failed to get RTCPReceiveInformation",
687 __FUNCTION__);
688 return -1;
689 }
690 if (receiveInfo->TmmbnBoundingSet.lengthOfSet > 0) {
691 boundingSetRec->VerifyAndAllocateSet(
692 receiveInfo->TmmbnBoundingSet.lengthOfSet + 1);
693 for(WebRtc_UWord32 i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet; i++) {
694 if(receiveInfo->TmmbnBoundingSet.ptrSsrcSet[i] == _SSRC) {
695 // owner of bounding set
696 tmmbrOwner = true;
697 }
698 boundingSetRec->ptrTmmbrSet[i] =
699 receiveInfo->TmmbnBoundingSet.ptrTmmbrSet[i];
700 boundingSetRec->ptrPacketOHSet[i] =
701 receiveInfo->TmmbnBoundingSet.ptrPacketOHSet[i];
702 boundingSetRec->ptrSsrcSet[i] =
703 receiveInfo->TmmbnBoundingSet.ptrSsrcSet[i];
704 }
705 }
706 return receiveInfo->TmmbnBoundingSet.lengthOfSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000707}
708
709// no need for critsect we have _criticalSectionRTCPReceiver
710void
711RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
712{
713 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
714 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
715 {
716 HandleSDESChunk(rtcpParser);
717 pktType = rtcpParser.Iterate();
718 }
719}
720
721// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000722void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
723 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
724 RTCPCnameInformation* cnameInfo =
725 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
726 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000727
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000728 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
729 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000730}
731
732// no need for critsect we have _criticalSectionRTCPReceiver
733void
734RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
735 RTCPPacketInformation& rtcpPacketInformation)
736{
737 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
738
739 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.NACK.SenderSSRC);
740 if (ptrReceiveInfo == NULL)
741 {
742 // This remote SSRC must be saved before.
743 rtcpParser.Iterate();
744 return;
745 }
746 if (_SSRC != rtcpPacket.NACK.MediaSSRC)
747 {
748 // Not to us.
749 rtcpParser.Iterate();
750 return;
751 }
752
753 rtcpPacketInformation.ResetNACKPacketIdArray();
754
755 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
756 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
757 {
758 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
759 pktType = rtcpParser.Iterate();
760 }
761}
762
763// no need for critsect we have _criticalSectionRTCPReceiver
764void
765RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
766 RTCPPacketInformation& rtcpPacketInformation)
767{
768 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
769
770 WebRtc_UWord16 bitMask = rtcpPacket.NACKItem.BitMask;
771 if(bitMask)
772 {
773 for(int i=1; i <= 16; ++i)
774 {
775 if(bitMask & 0x01)
776 {
777 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
778 }
779 bitMask = bitMask >>1;
780 }
781 }
782
783 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
784}
785
786// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000787void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
788 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000789
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000790 // clear our lists
791 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
792 std::map<WebRtc_UWord32, RTCPReportBlockInformation*>::iterator
793 reportBlockInfoIt = _receivedReportBlockMap.find(
794 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000795
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000796 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
797 delete reportBlockInfoIt->second;
798 _receivedReportBlockMap.erase(reportBlockInfoIt);
799 }
800 // we can't delete it due to TMMBR
801 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::iterator receiveInfoIt =
802 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000803
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000804 if (receiveInfoIt != _receivedInfoMap.end()) {
805 receiveInfoIt->second->readyForDelete = true;
806 }
807
808 std::map<WebRtc_UWord32, RTCPCnameInformation*>::iterator cnameInfoIt =
809 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
810
811 if (cnameInfoIt != _receivedCnameMap.end()) {
812 delete cnameInfoIt->second;
813 _receivedCnameMap.erase(cnameInfoIt);
814 }
815 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000816}
817
818// no need for critsect we have _criticalSectionRTCPReceiver
819void
820RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
821 RTCPPacketInformation& rtcpPacketInformation)
822{
823 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
824
825 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
826
827 if(rtcpPacket.XRVOIPMetricItem.SSRC == _SSRC)
828 {
829 // Store VoIP metrics block if it's about me
830 // from OriginatorSSRC do we filter it?
831 // rtcpPacket.XR.OriginatorSSRC;
832
833 RTCPVoIPMetric receivedVoIPMetrics;
834 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
835 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
836 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
837 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
838 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
839 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
840 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
841 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
842 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
843 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
844 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
845 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
846 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
847 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
848 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
849 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
850 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
851 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
852 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
853 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
854
855 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
856
857 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
858 }
859 rtcpParser.Iterate();
860}
861
862// no need for critsect we have _criticalSectionRTCPReceiver
863void
864RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
865 RTCPPacketInformation& rtcpPacketInformation)
866{
867 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
868
869 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.PLI.SenderSSRC);
870 if (ptrReceiveInfo == NULL)
871 {
872 // This remote SSRC must be saved before.
873 rtcpParser.Iterate();
874 return;
875 }
876 if (_SSRC != rtcpPacket.PLI.MediaSSRC)
877 {
878 // Not to us.
879 rtcpParser.Iterate();
880 return;
881 }
882 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli; // received signal that we need to send a new key frame
883 rtcpParser.Iterate();
884}
885
886// no need for critsect we have _criticalSectionRTCPReceiver
887void
888RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
889 RTCPPacketInformation& rtcpPacketInformation)
890{
891 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
892
893 WebRtc_UWord32 senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
894 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
895 if (ptrReceiveInfo == NULL)
896 {
897 // This remote SSRC must be saved before.
898 rtcpParser.Iterate();
899 return;
900 }
901 if(rtcpPacket.TMMBR.MediaSSRC)
902 {
903 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
904 // in relay mode this is a valid number
905 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
906 }
907
908 // Use packet length to calc max number of TMMBR blocks
909 // each TMMBR block is 8 bytes
910 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
911
912 // sanity
913 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
914 {
915 assert(false);
916 rtcpParser.Iterate();
917 return;
918 }
919 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((WebRtc_UWord32)maxNumOfTMMBRBlocks);
920
921 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
922 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
923 {
924 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
925 pktType = rtcpParser.Iterate();
926 }
927}
928
929// no need for critsect we have _criticalSectionRTCPReceiver
930void
931RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
932 const RTCPUtility::RTCPPacket& rtcpPacket,
933 RTCPPacketInformation& rtcpPacketInformation,
934 const WebRtc_UWord32 senderSSRC)
935{
936 if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
937 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
938 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000939 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
940 _clock.GetTimeInMS());
niklase@google.com470e71d2011-07-07 08:21:25 +0000941 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
942 }
943}
944
945// no need for critsect we have _criticalSectionRTCPReceiver
946void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000947RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
948 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +0000949{
950 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
951 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
952 if (ptrReceiveInfo == NULL)
953 {
954 // This remote SSRC must be saved before.
955 rtcpParser.Iterate();
956 return;
957 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000958 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +0000959 // Use packet length to calc max number of TMMBN blocks
960 // each TMMBN block is 8 bytes
961 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
962
963 // sanity
964 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
965 {
966 assert(false);
967 rtcpParser.Iterate();
968 return;
969 }
970
971 ptrReceiveInfo->VerifyAndAllocateBoundingSet((WebRtc_UWord32)maxNumOfTMMBNBlocks);
972
973 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
974 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
975 {
976 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
977 pktType = rtcpParser.Iterate();
978 }
979}
980
981// no need for critsect we have _criticalSectionRTCPReceiver
982void
983RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
984 RTCPPacketInformation& rtcpPacketInformation)
985{
986 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
987 rtcpParser.Iterate();
988}
989
990// no need for critsect we have _criticalSectionRTCPReceiver
991void
992RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
993 const RTCPUtility::RTCPPacket& rtcpPacket)
994{
995 const unsigned int idx = receiveInfo.TmmbnBoundingSet.lengthOfSet;
996
997 receiveInfo.TmmbnBoundingSet.ptrTmmbrSet[idx] = rtcpPacket.TMMBNItem.MaxTotalMediaBitRate;
998 receiveInfo.TmmbnBoundingSet.ptrPacketOHSet[idx] = rtcpPacket.TMMBNItem.MeasuredOverhead;
999 receiveInfo.TmmbnBoundingSet.ptrSsrcSet[idx] = rtcpPacket.TMMBNItem.SSRC;
1000
1001 ++receiveInfo.TmmbnBoundingSet.lengthOfSet;
1002}
1003
1004// no need for critsect we have _criticalSectionRTCPReceiver
1005void
1006RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1007 RTCPPacketInformation& rtcpPacketInformation)
1008{
1009 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1010
1011 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.SLI.SenderSSRC);
1012 if (ptrReceiveInfo == NULL)
1013 {
1014 // This remote SSRC must be saved before.
1015 rtcpParser.Iterate();
1016 return;
1017 }
1018
1019 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1020 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1021 {
1022 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1023 pktType = rtcpParser.Iterate();
1024 }
1025}
1026
1027// no need for critsect we have _criticalSectionRTCPReceiver
1028void
1029RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1030 RTCPPacketInformation& rtcpPacketInformation)
1031{
1032 // in theory there could be multiple slices lost
1033 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1034 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1035}
1036
1037void
1038RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1039 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1040{
1041 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1042
1043 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.RPSI.SenderSSRC);
1044 if (ptrReceiveInfo == NULL)
1045 {
1046 // This remote SSRC must be saved before.
1047 rtcpParser.Iterate();
1048 return;
1049 }
1050 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1051 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1052 {
1053 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1054 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1055 {
1056 // to us unknown
1057 // continue
1058 rtcpParser.Iterate();
1059 return;
1060 }
1061 rtcpPacketInformation.rpsiPictureId = 0;
1062
1063 // convert NativeBitString to rpsiPictureId
1064 WebRtc_UWord8 numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1065 for(WebRtc_UWord8 n = 0; n < (numberOfBytes-1); n++)
1066 {
1067 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1068 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1069 }
1070 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1071 }
1072}
1073
1074// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001075void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1076 RTCPPacketInformation& rtcpPacketInformation) {
1077 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1078 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1079 pktType = rtcpParser.Iterate();
1080 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1081 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1082 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001083 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001084 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001085}
1086
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001087// no need for critsect we have _criticalSectionRTCPReceiver
1088void
1089RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1090 RTCPPacketInformation& rtcpPacketInformation)
1091{
1092 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1093
1094 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1095 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1096 {
1097 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1098 pktType = rtcpParser.Iterate();
1099 }
1100}
1101
1102void
1103RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1104 RTCPPacketInformation& rtcpPacketInformation)
1105{
1106 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1107 rtcpPacketInformation.interArrivalJitter =
1108 rtcpPacket.ExtendedJitterReportItem.Jitter;
1109}
1110
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001111void RTCPReceiver::HandleREMBItem(
1112 RTCPUtility::RTCPParserV2& rtcpParser,
1113 RTCPPacketInformation& rtcpPacketInformation) {
1114 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1115 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1116 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1117 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001118}
1119
1120// no need for critsect we have _criticalSectionRTCPReceiver
1121void
niklase@google.com470e71d2011-07-07 08:21:25 +00001122RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1123 RTCPPacketInformation& rtcpPacketInformation)
1124{
1125 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1126
1127 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
1128 if (ptrReceiveInfo == NULL)
1129 {
1130 // This remote SSRC must be saved before.
1131 rtcpParser.Iterate();
1132 return;
1133 }
1134
1135 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1136 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode)
1137 {
1138 HandleFIRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1139 pktType = rtcpParser.Iterate();
1140 }
1141}
1142
1143// no need for critsect we have _criticalSectionRTCPReceiver
1144void
1145RTCPReceiver::HandleFIRItem(RTCPReceiveInformation& receiveInfo,
1146 const RTCPUtility::RTCPPacket& rtcpPacket,
1147 RTCPPacketInformation& rtcpPacketInformation)
1148{
1149 if (_SSRC == rtcpPacket.FIRItem.SSRC) // is it our sender that is requested to generate a new keyframe
1150 {
1151 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1152 // we don't know who this originate from
1153
1154 // check if we have reported this FIRSequenceNumber before
1155 if (rtcpPacket.FIRItem.CommandSequenceNumber != receiveInfo.lastFIRSequenceNumber)
1156 {
1157 //
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +00001158 WebRtc_UWord32 now = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +00001159
1160 // extra sanity don't go crazy with the callbacks
1161 if( (now - receiveInfo.lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS)
1162 {
1163 receiveInfo.lastFIRRequest = now;
1164 receiveInfo.lastFIRSequenceNumber = rtcpPacket.FIRItem.CommandSequenceNumber;
1165
1166 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir; // received signal that we need to send a new key frame
1167 }
1168 }
1169 }
1170}
1171
1172void
1173RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1174 RTCPPacketInformation& rtcpPacketInformation)
1175{
1176 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1177
1178 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1179 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1180 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1181
1182 rtcpParser.Iterate();
1183}
1184
1185void
1186RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1187 RTCPPacketInformation& rtcpPacketInformation)
1188{
1189 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1190
1191 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1192
1193 rtcpParser.Iterate();
1194}
1195
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001196WebRtc_Word32 RTCPReceiver::UpdateTMMBR() {
1197 WebRtc_Word32 numBoundingSet = 0;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001198 WebRtc_UWord32 bitrate = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001199 WebRtc_UWord32 accNumCandidates = 0;
1200
1201 WebRtc_Word32 size = TMMBRReceived(0, 0, NULL);
1202 if (size > 0) {
1203 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1204 // Get candidate set from receiver.
1205 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1206 } else {
1207 // Candidate set empty.
1208 VerifyAndAllocateCandidateSet(0); // resets candidate set
1209 }
1210 // Find bounding set
1211 TMMBRSet* boundingSet = NULL;
1212 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1213 if (numBoundingSet == -1) {
1214 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1215 "Failed to find TMMBR bounding set.");
1216 return -1;
1217 }
1218 // Set bounding set
1219 // Inform remote clients about the new bandwidth
1220 // inform the remote client
1221 _rtpRtcp.SetTMMBN(boundingSet);
1222
1223 // might trigger a TMMBN
1224 if (numBoundingSet == 0) {
1225 // owner of max bitrate request has timed out
1226 // empty bounding set has been sent
1227 return 0;
1228 }
1229 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001230 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001231 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001232 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1233 if (_cbRtcpBandwidthObserver) {
1234 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1235 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1236 "Set TMMBR request:%d kbps", bitrate);
1237 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001238 }
1239 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001240}
1241
1242// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001243void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001244 RTCPPacketInformation& rtcpPacketInformation) {
1245 // Process TMMBR and REMB first to avoid multiple callbacks
1246 // to OnNetworkChanged.
1247 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1248 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1249 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001250
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001251 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1252 UpdateTMMBR();
1253 }
1254 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) {
1255 _rtpRtcp.OnReceivedNTP();
1256 }
1257 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1258 _rtpRtcp.OnRequestSendReport();
1259 }
1260 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
1261 if (rtcpPacketInformation.nackSequenceNumbersLength > 0) {
1262 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1263 "SIG [RTCP] Incoming NACK length:%d",
1264 rtcpPacketInformation.nackSequenceNumbersLength);
1265 _rtpRtcp.OnReceivedNACK(
1266 rtcpPacketInformation.nackSequenceNumbersLength,
1267 rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001268 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001269 }
1270 {
1271 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001272
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001273 // We need feedback that we have received a report block(s) so that we
1274 // can generate a new packet in a conference relay scenario, one received
1275 // report can generate several RTCP packets, based on number relayed/mixed
1276 // a send report block should go out to all receivers.
1277 if (_cbRtcpIntraFrameObserver) {
1278 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1279 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1280 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1281 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1282 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1283 rtcpPacketInformation.remoteSSRC);
1284 } else {
1285 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1286 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1287 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001288 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001289 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(
1290 rtcpPacketInformation.remoteSSRC);
1291 }
1292 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1293 _cbRtcpIntraFrameObserver->OnReceivedSLI(
1294 rtcpPacketInformation.remoteSSRC,
pwestin@webrtc.org1da1ce02011-10-13 15:19:55 +00001295 rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001296 }
1297 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1298 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
1299 rtcpPacketInformation.remoteSSRC,
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001300 rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001301 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001302 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001303 if (_cbRtcpBandwidthObserver) {
1304 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1305 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1306 "SIG [RTCP] Incoming REMB:%d",
1307 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1308 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1309 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1310 }
1311 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1312 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
1313 rtcpPacketInformation.reportBlock) {
1314 WebRtc_UWord32 now = _clock.GetTimeInMS();
1315 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
1316 rtcpPacketInformation.remoteSSRC,
1317 rtcpPacketInformation.fractionLost,
1318 rtcpPacketInformation.roundTripTime,
1319 rtcpPacketInformation.lastReceivedExtendedHighSeqNum,
1320 now);
1321 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001322 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001323 if(_cbRtcpFeedback) {
1324 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) {
1325 _cbRtcpFeedback->OnSendReportReceived(_id,
1326 rtcpPacketInformation.remoteSSRC);
1327 } else {
1328 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1329 rtcpPacketInformation.remoteSSRC);
1330 }
1331 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1332 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1333 rtcpPacketInformation.VoIPMetric);
1334 }
1335 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1336 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1337 rtcpPacketInformation.applicationSubType,
1338 rtcpPacketInformation.applicationName,
1339 rtcpPacketInformation.applicationLength,
1340 rtcpPacketInformation.applicationData);
1341 }
1342 }
1343 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001344}
1345
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001346WebRtc_Word32 RTCPReceiver::CNAME(const WebRtc_UWord32 remoteSSRC,
1347 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001348 assert(cName);
1349
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001350 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1351 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001352 if (cnameInfo == NULL) {
1353 return -1;
1354 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001355 cName[RTCP_CNAME_SIZE - 1] = 0;
1356 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1357 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001358}
1359
1360// no callbacks allowed inside this function
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001361WebRtc_Word32 RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size,
1362 const WebRtc_UWord32 accNumCandidates,
1363 TMMBRSet* candidateSet) const {
1364 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001365
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001366 std::map<WebRtc_UWord32, RTCPReceiveInformation*>::const_iterator
1367 receiveInfoIt = _receivedInfoMap.begin();
1368 if (receiveInfoIt == _receivedInfoMap.end()) {
1369 return -1;
1370 }
1371 WebRtc_UWord32 num = accNumCandidates;
1372 if (candidateSet) {
1373 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1374 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1375 if (receiveInfo == NULL) {
1376 return 0;
1377 }
1378 for (WebRtc_UWord32 i = 0;
1379 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet); i++) {
1380 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
1381 _clock.GetTimeInMS()) == 0) {
1382 num++;
1383 }
1384 }
1385 receiveInfoIt++;
1386 }
1387 } else {
1388 while (receiveInfoIt != _receivedInfoMap.end()) {
1389 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1390 if(receiveInfo == NULL) {
1391 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1392 "%s failed to get RTCPReceiveInformation",
1393 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001394 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001395 }
1396 num += receiveInfo->TmmbrSet.lengthOfSet;
1397 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001398 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001399 }
1400 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001401}
1402
1403WebRtc_Word32
1404RTCPReceiver::SetPacketTimeout(const WebRtc_UWord32 timeoutMS)
1405{
1406 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1407 _packetTimeOutMS = timeoutMS;
1408 return 0;
1409}
1410
1411void RTCPReceiver::PacketTimeout()
1412{
1413 if(_packetTimeOutMS == 0)
1414 {
1415 // not configured
1416 return;
1417 }
1418
1419 bool packetTimeOut = false;
1420 {
1421 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1422 if(_lastReceived == 0)
1423 {
1424 // not active
1425 return;
1426 }
1427
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +00001428 WebRtc_UWord32 now = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +00001429
1430 if(now - _lastReceived > _packetTimeOutMS)
1431 {
1432 packetTimeOut = true;
1433 _lastReceived = 0; // only one callback
1434 }
1435 }
1436 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1437 if(packetTimeOut && _cbRtcpFeedback)
1438 {
1439 _cbRtcpFeedback->OnRTCPPacketTimeout(_id);
1440 }
1441}
1442} // namespace webrtc