blob: dabfe7106bb779525e44e1729102e02f8d069451 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 *
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.org0644b1d2011-12-01 15:42:31 +000030RTCPReceiver::RTCPReceiver(const WebRtc_Word32 id,
31 RtpRtcpClock* clock,
32 ModuleRtpRtcpImpl* owner) :
niklase@google.com470e71d2011-07-07 08:21:25 +000033 _id(id),
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +000034 _clock(*clock),
niklase@google.com470e71d2011-07-07 08:21:25 +000035 _method(kRtcpOff),
36 _lastReceived(0),
pwestin@webrtc.org741da942011-09-20 13:52:04 +000037 _rtpRtcp(*owner),
niklase@google.com470e71d2011-07-07 08:21:25 +000038 _criticalSectionFeedbacks(*CriticalSectionWrapper::CreateCriticalSection()),
39 _cbRtcpFeedback(NULL),
40 _cbVideoFeedback(NULL),
41 _criticalSectionRTCPReceiver(*CriticalSectionWrapper::CreateCriticalSection()),
42 _SSRC(0),
43 _remoteSSRC(0),
44 _remoteSenderInfo(),
45 _lastReceivedSRNTPsecs(0),
46 _lastReceivedSRNTPfrac(0),
47 _receivedInfoMap(),
48 _packetTimeOutMS(0)
49{
50 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
51 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
52}
53
54RTCPReceiver::~RTCPReceiver()
55{
56 delete &_criticalSectionRTCPReceiver;
57 delete &_criticalSectionFeedbacks;
58
59 bool loop = true;
60 do
61 {
62 MapItem* item = _receivedReportBlockMap.First();
63 if(item)
64 {
65 // delete
66 RTCPReportBlockInformation* block= ((RTCPReportBlockInformation*)item->GetItem());
67 delete block;
68
69 // remove from map and delete Item
70 _receivedReportBlockMap.Erase(item);
71 } else
72 {
73 loop = false;
74 }
75 } while (loop);
76
77 loop = true;
78 do
79 {
80 MapItem* item = _receivedInfoMap.First();
81 if(item)
82 {
83 // delete
84 RTCPReceiveInformation* block= ((RTCPReceiveInformation*)item->GetItem());
85 delete block;
86
87 // remove from map and delete Item
88 _receivedInfoMap.Erase(item);
89 } else
90 {
91 loop = false;
92 }
93 } while (loop);
94
95 loop = true;
96 do
97 {
98 MapItem* item = _receivedCnameMap.First();
99 if(item)
100 {
101 // delete
102 RTCPCnameInformation* block= ((RTCPCnameInformation*)item->GetItem());
103 delete block;
104
105 // remove from map and delete Item
106 _receivedCnameMap.Erase(item);
107 } else
108 {
109 loop = false;
110 }
111 } while (loop);
112
113 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id, "%s deleted", __FUNCTION__);
114}
115
116void
117RTCPReceiver::ChangeUniqueId(const WebRtc_Word32 id)
118{
119 _id = id;
120}
121
122RTCPMethod
123RTCPReceiver::Status() const
124{
125 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
126 return _method;
127}
128
129WebRtc_Word32
130RTCPReceiver::SetRTCPStatus(const RTCPMethod method)
131{
132 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
133 _method = method;
134 return 0;
135}
136
137WebRtc_UWord32
138RTCPReceiver::LastReceived()
139{
140 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
141 return _lastReceived;
142}
143
144WebRtc_Word32
145RTCPReceiver::SetRemoteSSRC( const WebRtc_UWord32 ssrc)
146{
147 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
148
149 // new SSRC reset old reports
150 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
151 _lastReceivedSRNTPsecs = 0;
152 _lastReceivedSRNTPfrac = 0;
153
154 _remoteSSRC = ssrc;
155 return 0;
156}
157
158WebRtc_Word32
159RTCPReceiver::RegisterIncomingRTCPCallback(RtcpFeedback* incomingMessagesCallback)
160{
161 CriticalSectionScoped lock(_criticalSectionFeedbacks);
162 _cbRtcpFeedback = incomingMessagesCallback;
163 return 0;
164}
165
166WebRtc_Word32
167RTCPReceiver::RegisterIncomingVideoCallback(RtpVideoFeedback* incomingMessagesCallback)
168{
169 CriticalSectionScoped lock(_criticalSectionFeedbacks);
170 _cbVideoFeedback = incomingMessagesCallback;
171 return 0;
172}
173
174void
175RTCPReceiver::SetSSRC( const WebRtc_UWord32 ssrc)
176{
177 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
178 _SSRC = ssrc;
179}
180
181WebRtc_Word32
182RTCPReceiver::ResetRTT(const WebRtc_UWord32 remoteSSRC)
183{
184 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
185 RTCPReportBlockInformation* reportBlock = GetReportBlockInformation(remoteSSRC);
186 if(reportBlock == NULL)
187 {
188 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "\tfailed to GetReportBlockInformation(%d)", remoteSSRC);
189 return -1;
190 }
191 reportBlock->RTT = 0;
192 reportBlock->avgRTT = 0;
193 reportBlock->minRTT = 0;
194 reportBlock->maxRTT = 0;
195
196 return 0;
197}
198
199WebRtc_Word32
200RTCPReceiver::RTT(const WebRtc_UWord32 remoteSSRC,
201 WebRtc_UWord16* RTT,
202 WebRtc_UWord16* avgRTT,
203 WebRtc_UWord16* minRTT,
204 WebRtc_UWord16* maxRTT) const
205
206{
207 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
208 RTCPReportBlockInformation* reportBlock = GetReportBlockInformation(remoteSSRC);
209 if(reportBlock == NULL)
210 {
211 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "\tfailed to GetReportBlockInformation(%d)", remoteSSRC);
212 return -1;
213 }
214 if(RTT)
215 {
216 *RTT = reportBlock->RTT;
217 }
218 if(avgRTT)
219 {
220 *avgRTT = reportBlock->avgRTT;
221 }
222 if(minRTT)
223 {
224 *minRTT = reportBlock->minRTT;
225 }
226 if(maxRTT)
227 {
228 *maxRTT = reportBlock->maxRTT;
229 }
230 return 0;
231}
232
233void
234RTCPReceiver::UpdateLipSync(const WebRtc_Word32 audioVideoOffset) const
235{
236 CriticalSectionScoped lock(_criticalSectionFeedbacks);
237 if(_cbRtcpFeedback)
238 {
239 _cbRtcpFeedback->OnLipSyncUpdate(_id,audioVideoOffset);
240 }
241};
242
243WebRtc_Word32
244RTCPReceiver::NTP(WebRtc_UWord32 *ReceivedNTPsecs,
245 WebRtc_UWord32 *ReceivedNTPfrac,
246 WebRtc_UWord32 *RTCPArrivalTimeSecs,
247 WebRtc_UWord32 *RTCPArrivalTimeFrac) const
248{
249 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
250 if(ReceivedNTPsecs)
251 {
252 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
253 }
254 if(ReceivedNTPfrac)
255 {
256 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
257 }
258 if(RTCPArrivalTimeFrac)
259 {
260 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
261 }
262 if(RTCPArrivalTimeSecs)
263 {
264 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
265 }
266 return 0;
267}
268
269WebRtc_Word32
270RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
271{
272 if(senderInfo == NULL)
273 {
274 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
275 return -1;
276 }
277 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
278 if(_lastReceivedSRNTPsecs == 0)
279 {
280 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
281 return -1;
282 }
283 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
284 return 0;
285}
286
287// statistics
288// we can get multiple receive reports when we receive the report from a CE
289WebRtc_Word32
290RTCPReceiver::StatisticsReceived(const WebRtc_UWord32 remoteSSRC,
291 RTCPReportBlock* receiveBlock) const
292{
293 if(receiveBlock == NULL)
294 {
295 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
296 return -1;
297 }
298 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
299 RTCPReportBlockInformation* reportBlockInfo = GetReportBlockInformation(remoteSSRC);
300 if(reportBlockInfo == NULL)
301 {
302 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "\tfailed to GetReportBlockInformation(%d)", remoteSSRC);
303 return -1;
304 }
305 memcpy(receiveBlock, &(reportBlockInfo->remoteReceiveBlock), sizeof(RTCPReportBlock));
306 return 0;
307}
308
309WebRtc_Word32
310RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
311 RTCPUtility::RTCPParserV2* rtcpParser)
312{
313 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
314
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000315 _lastReceived = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +0000316
317 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
318 while (pktType != RTCPUtility::kRtcpNotValidCode)
319 {
320 // Each "case" is responsible for iterate the parser to the
321 // next top level packet.
322 switch (pktType)
323 {
324 case RTCPUtility::kRtcpSrCode:
325 case RTCPUtility::kRtcpRrCode:
326 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
327 break;
328 case RTCPUtility::kRtcpSdesCode:
329 HandleSDES(*rtcpParser);
330 break;
331 case RTCPUtility::kRtcpXrVoipMetricCode:
332 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
333 break;
334 case RTCPUtility::kRtcpByeCode:
335 HandleBYE(*rtcpParser);
336 break;
337 case RTCPUtility::kRtcpRtpfbNackCode:
338 HandleNACK(*rtcpParser, rtcpPacketInformation);
339 break;
340 case RTCPUtility::kRtcpRtpfbTmmbrCode:
341 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
342 break;
343 case RTCPUtility::kRtcpRtpfbTmmbnCode:
344 HandleTMMBN(*rtcpParser);
345 break;
346 case RTCPUtility::kRtcpRtpfbSrReqCode:
347 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
348 break;
349 case RTCPUtility::kRtcpPsfbPliCode:
350 HandlePLI(*rtcpParser, rtcpPacketInformation);
351 break;
352 case RTCPUtility::kRtcpPsfbSliCode:
353 HandleSLI(*rtcpParser, rtcpPacketInformation);
354 break;
355 case RTCPUtility::kRtcpPsfbRpsiCode:
356 HandleRPSI(*rtcpParser, rtcpPacketInformation);
357 break;
358 case RTCPUtility::kRtcpPsfbFirCode:
359 HandleFIR(*rtcpParser, rtcpPacketInformation);
360 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000361 case RTCPUtility::kRtcpPsfbAppCode:
362 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
363 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000364 case RTCPUtility::kRtcpAppCode:
365 // generic application messages
366 HandleAPP(*rtcpParser, rtcpPacketInformation);
367 break;
368 case RTCPUtility::kRtcpAppItemCode:
369 // generic application messages
370 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
371 break;
372 default:
373 rtcpParser->Iterate();
374 break;
375 }
376 pktType = rtcpParser->PacketType();
377 }
378 return 0;
379}
380
381// no need for critsect we have _criticalSectionRTCPReceiver
382void
383RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
384 RTCPPacketInformation& rtcpPacketInformation)
385{
386 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
387 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
388
389 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
390
391 // SR.SenderSSRC
392 // The synchronization source identifier for the originator of this SR packet
393
394 // rtcpPacket.RR.SenderSSRC
395 // The source of the packet sender, same as of SR? or is this a CE?
396
397 const WebRtc_UWord32 remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
398 const WebRtc_UWord8 numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
399
400 rtcpPacketInformation.remoteSSRC = remoteSSRC;
401
402 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
403 if (!ptrReceiveInfo)
404 {
405 rtcpParser.Iterate();
406 return;
407 }
408
409 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
410 {
411 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
412 "Received SR(%d). SSRC:0x%x, from SSRC:0x%x, to us %d.", _id, _SSRC, remoteSSRC, (_remoteSSRC == remoteSSRC)?1:0);
413
414 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
415 {
416 // only signal that we have received a SR when we accept one
417 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
418
419 // We will only store the send report from one source, but
420 // we will store all the receive block
421
422 // Save the NTP time of this report
423 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
424 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
425 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
426 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
427 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
428
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000429 _clock.CurrentNTP(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000430 }
431 else
432 {
433 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
434 }
435 } else
436 {
437 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
438 "Received RR(%d). SSRC:0x%x, from SSRC:0x%x", _id, _SSRC, remoteSSRC);
439
440 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
441 }
442 UpdateReceiveInformation(*ptrReceiveInfo);
443
444 rtcpPacketType = rtcpParser.Iterate();
445
446 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
447 {
448 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
449 rtcpPacketType = rtcpParser.Iterate();
450 }
451}
452
453// no need for critsect we have _criticalSectionRTCPReceiver
454void
455RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
456 RTCPPacketInformation& rtcpPacketInformation,
457 const WebRtc_UWord32 remoteSSRC,
458 const WebRtc_UWord8 numberOfReportBlocks)
459{
460 // this will be called once per report block in the RTCP packet
461 // we store all incoming reports
462 // each packet has max 31 RR blocks
463 //
464 // we can calc RTT if we send a send report and get a report block back
465
466 /*
467 rtcpPacket.ReportBlockItem.SSRC
468 The SSRC identifier of the source to which the information in this
469 reception report block pertains.
470 */
471
472 // if we receive a RTCP packet with multiple reportBlocks only store the ones to us
473 if( _SSRC &&
474 numberOfReportBlocks > 1)
475 {
476 // we have more than one reportBlock in the RTCP packet
477 if(rtcpPacket.ReportBlockItem.SSRC != _SSRC)
478 {
479 // this block is not for us ignore it
480 return;
481 }
482 }
483
484 _criticalSectionRTCPReceiver.Leave();
485 // to avoid problem with accuireing _criticalSectionRTCPSender while holding _criticalSectionRTCPReceiver
486
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000487 WebRtc_UWord32 sendTimeMS =
488 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
niklase@google.com470e71d2011-07-07 08:21:25 +0000489
490 _criticalSectionRTCPReceiver.Enter();
491
492 // ReportBlockItem.SSRC is who it's to
493 // we store all incoming reports, used in conference relay
494
495 RTCPReportBlockInformation* reportBlock = CreateReportBlockInformation(remoteSSRC);
496 if(reportBlock == NULL)
497 {
498 return;
499 }
500
501 reportBlock->remoteReceiveBlock.fractionLost = rtcpPacket.ReportBlockItem.FractionLost;
502 reportBlock->remoteReceiveBlock.cumulativeLost = rtcpPacket.ReportBlockItem.CumulativeNumOfPacketsLost;
503 reportBlock->remoteReceiveBlock.extendedHighSeqNum= rtcpPacket.ReportBlockItem.ExtendedHighestSequenceNumber;
504 reportBlock->remoteReceiveBlock.jitter = rtcpPacket.ReportBlockItem.Jitter;
505 reportBlock->remoteReceiveBlock.delaySinceLastSR = rtcpPacket.ReportBlockItem.DelayLastSR;
506 reportBlock->remoteReceiveBlock.lastSR = rtcpPacket.ReportBlockItem.LastSR;
507
508 if(rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter)
509 {
510 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
511 }
512
513 WebRtc_UWord32 delaySinceLastSendReport = rtcpPacket.ReportBlockItem.DelayLastSR;
514
515 // do we have a local SSRC
516 // keep track of our relayed SSRC too
517 if(_SSRC)
518 {
519 // we filter rtcpPacket.ReportBlockItem.SSRC to our SSRC
520 // hence only reports to us
521 if( rtcpPacket.ReportBlockItem.SSRC == _SSRC)
522 {
523 // local NTP time when we received this
524 WebRtc_UWord32 lastReceivedRRNTPsecs = 0;
525 WebRtc_UWord32 lastReceivedRRNTPfrac = 0;
526
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000527 _clock.CurrentNTP(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000528
529 // time when we received this in MS
530 WebRtc_UWord32 receiveTimeMS = ModuleRTPUtility::ConvertNTPTimeToMS(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
531
532 // Estimate RTT
533 WebRtc_UWord32 d =(delaySinceLastSendReport&0x0000ffff)*1000;
534 d /= 65536;
535 d+=((delaySinceLastSendReport&0xffff0000)>>16)*1000;
536
537 WebRtc_Word32 RTT = 0;
538
539 if(sendTimeMS > 0)
540 {
541 RTT = receiveTimeMS - d - sendTimeMS;
542 if( RTT <= 0)
543 {
544 RTT = 1;
545 }
546 if (RTT > reportBlock->maxRTT)
547 {
548 // store max RTT
549 reportBlock->maxRTT = (WebRtc_UWord16)RTT;
550 }
551 if(reportBlock->minRTT == 0)
552 {
553 // first RTT
554 reportBlock->minRTT = (WebRtc_UWord16)RTT;
555 }else if (RTT < reportBlock->minRTT)
556 {
557 // Store min RTT
558 reportBlock->minRTT = (WebRtc_UWord16)RTT;
559 }
560 // store last RTT
561 reportBlock->RTT = (WebRtc_UWord16)RTT;
562
563 // store average RTT
564 if(reportBlock->numAverageCalcs != 0)
565 {
566 float ac = static_cast<float>(reportBlock->numAverageCalcs);
567 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * RTT);
568 reportBlock->avgRTT = static_cast<int>(newAverage + 0.5f);
569 }else
570 {
571 // first RTT
572 reportBlock->avgRTT = (WebRtc_UWord16)RTT;
573 }
574 reportBlock->numAverageCalcs++;
575 }
576
577 WEBRTC_TRACE(kTraceDebug, kTraceRtpRtcp, _id,
578 " -> Received report block(%d), from SSRC:0x%x, RTT:%d, loss:%d", _id, remoteSSRC, RTT, rtcpPacket.ReportBlockItem.FractionLost);
579
580 // rtcpPacketInformation
581 rtcpPacketInformation.AddReportInfo(reportBlock->remoteReceiveBlock.fractionLost,
582 (WebRtc_UWord16)RTT,
583 reportBlock->remoteReceiveBlock.extendedHighSeqNum,
584 reportBlock->remoteReceiveBlock.jitter);
585 }
586 }
587}
588
589RTCPReportBlockInformation*
590RTCPReceiver::CreateReportBlockInformation(WebRtc_UWord32 remoteSSRC)
591{
592 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
593
594 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
595 MapItem* ptrReportBlockInfoItem = _receivedReportBlockMap.Find(remoteSSRC);
596 if (ptrReportBlockInfoItem == NULL)
597 {
598 ptrReportBlockInfo = new RTCPReportBlockInformation;
599 _receivedReportBlockMap.Insert(remoteSSRC, ptrReportBlockInfo);
600 } else
601 {
602 ptrReportBlockInfo = static_cast<RTCPReportBlockInformation*>(ptrReportBlockInfoItem->GetItem());
603 }
604 return ptrReportBlockInfo;
605
606}
607
608RTCPReportBlockInformation*
609RTCPReceiver::GetReportBlockInformation(WebRtc_UWord32 remoteSSRC) const
610{
611 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
612
613 MapItem* ptrReportBlockInfoItem = _receivedReportBlockMap.Find(remoteSSRC);
614 if (ptrReportBlockInfoItem == NULL)
615 {
616 return NULL;
617 }
618 return static_cast<RTCPReportBlockInformation*>(ptrReportBlockInfoItem->GetItem());
619}
620
621RTCPCnameInformation*
622RTCPReceiver::CreateCnameInformation(WebRtc_UWord32 remoteSSRC)
623{
624 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
625
626 RTCPCnameInformation* ptrCnameInfo = NULL;
627 MapItem* ptrCnameInfoItem = _receivedCnameMap.Find(remoteSSRC);
628 if (ptrCnameInfoItem == NULL)
629 {
630 ptrCnameInfo = new RTCPCnameInformation;
631 _receivedCnameMap.Insert(remoteSSRC, ptrCnameInfo);
632 } else
633 {
634 ptrCnameInfo = static_cast<RTCPCnameInformation*>(ptrCnameInfoItem->GetItem());
635 }
636 return ptrCnameInfo;
637}
638
639RTCPCnameInformation*
640RTCPReceiver::GetCnameInformation(WebRtc_UWord32 remoteSSRC) const
641{
642 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
643
644 MapItem* ptrCnameInfoItem = _receivedCnameMap.Find(remoteSSRC);
645 if (ptrCnameInfoItem == NULL)
646 {
647 return NULL;
648 }
649 return static_cast<RTCPCnameInformation*>(ptrCnameInfoItem->GetItem());
650}
651
652RTCPReceiveInformation*
653RTCPReceiver::CreateReceiveInformation(WebRtc_UWord32 remoteSSRC)
654{
655 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
656
657 RTCPReceiveInformation* ptrReceiveInfo = NULL;
658 MapItem* ptrReceiveInfoItem = _receivedInfoMap.Find(remoteSSRC);
659 if (ptrReceiveInfoItem == NULL)
660 {
661 ptrReceiveInfo = new RTCPReceiveInformation;
662 _receivedInfoMap.Insert(remoteSSRC, ptrReceiveInfo);
663 } else
664 {
665 ptrReceiveInfo = static_cast<RTCPReceiveInformation*>(ptrReceiveInfoItem->GetItem());
666 }
667 return ptrReceiveInfo;
668}
669
670RTCPReceiveInformation*
671RTCPReceiver::GetReceiveInformation(WebRtc_UWord32 remoteSSRC)
672{
673 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
674
675 MapItem* ptrReceiveInfoItem = _receivedInfoMap.Find(remoteSSRC);
676 if (ptrReceiveInfoItem == NULL)
677 {
678 return NULL;
679 }
680 return static_cast<RTCPReceiveInformation*>(ptrReceiveInfoItem->GetItem());
681}
682
683void
684RTCPReceiver::UpdateReceiveInformation( RTCPReceiveInformation& receiveInformation)
685{
686 // Update that this remote is alive
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000687 receiveInformation.lastTimeReceived = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +0000688}
689
690bool
691RTCPReceiver::UpdateRTCPReceiveInformationTimers()
692{
693 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
694
695 bool updateBoundingSet = false;
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000696 WebRtc_UWord32 timeNow = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +0000697 MapItem* receiveInfoItem=_receivedInfoMap.First();
698
699 while(receiveInfoItem)
700 {
701 RTCPReceiveInformation* receiveInfo = (RTCPReceiveInformation*)receiveInfoItem->GetItem();
702 if(receiveInfo == NULL)
703 {
704 return updateBoundingSet;
705 }
706 // time since last received rtcp packet
707 // when we dont have a lastTimeReceived and the object is marked readyForDelete
708 // it's removed from the map
709 if( receiveInfo->lastTimeReceived)
710 {
711 if((timeNow - receiveInfo->lastTimeReceived) > 5*RTCP_INTERVAL_AUDIO_MS) // use audio define since we don't know what interval the remote peer is using
712 {
713 // no rtcp packet for the last five regular intervals, reset limitations
714 receiveInfo->TmmbrSet.lengthOfSet = 0;
715 receiveInfo->lastTimeReceived = 0; // prevent that we call this over and over again
716 updateBoundingSet = true; // send new TMMBN to all channels using the default codec
717 }
718 receiveInfoItem = _receivedInfoMap.Next(receiveInfoItem);
719 }else
720 {
721 if(receiveInfo->readyForDelete)
722 {
723 // store our current receiveInfoItem
724 MapItem* receiveInfoItemToBeErased = receiveInfoItem;
725
726 // iterate
727 receiveInfoItem = _receivedInfoMap.Next(receiveInfoItem);
728
729 // delete current
730 delete receiveInfo;
731 _receivedInfoMap.Erase(receiveInfoItemToBeErased);
732 }else
733 {
734 receiveInfoItem = _receivedInfoMap.Next(receiveInfoItem);
735 }
736 }
737
738 }
739 return updateBoundingSet;
740}
741
742WebRtc_Word32
743RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet*& boundingSetRec)
744{
745 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
746
747 MapItem* receiveInfoItem=_receivedInfoMap.Find(_remoteSSRC);
748 if(receiveInfoItem )
749 {
750 RTCPReceiveInformation* receiveInfo = (RTCPReceiveInformation*)receiveInfoItem->GetItem();
751 if(receiveInfo == NULL)
752 {
753 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s failed to get RTCPReceiveInformation", __FUNCTION__);
754 return -1;
755 }
756 if(receiveInfo->TmmbnBoundingSet.lengthOfSet > 0)
757 {
758 boundingSetRec->VerifyAndAllocateSet(receiveInfo->TmmbnBoundingSet.lengthOfSet + 1);
759 for(WebRtc_UWord32 i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet; i++)
760 {
761 if(receiveInfo->TmmbnBoundingSet.ptrSsrcSet[i] == _SSRC)
762 {
763 // owner of bounding set
764 tmmbrOwner = true;
765 }
766 boundingSetRec->ptrTmmbrSet[i] = receiveInfo->TmmbnBoundingSet.ptrTmmbrSet[i];
767 boundingSetRec->ptrPacketOHSet[i] = receiveInfo->TmmbnBoundingSet.ptrPacketOHSet[i];
768 boundingSetRec->ptrSsrcSet[i] = receiveInfo->TmmbnBoundingSet.ptrSsrcSet[i];
769 }
770 return receiveInfo->TmmbnBoundingSet.lengthOfSet;
771 }
772 }
773 return -1;
774}
775
776// no need for critsect we have _criticalSectionRTCPReceiver
777void
778RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
779{
780 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
781 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
782 {
783 HandleSDESChunk(rtcpParser);
784 pktType = rtcpParser.Iterate();
785 }
786}
787
788// no need for critsect we have _criticalSectionRTCPReceiver
789void
790RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser)
791{
792 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
793
794 RTCPCnameInformation* cnameInfo = CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
795 if (cnameInfo)
796 {
797 memcpy(cnameInfo->name, rtcpPacket.CName.CName, rtcpPacket.CName.CNameLength);
798 cnameInfo->length = rtcpPacket.CName.CNameLength;
799 }
800}
801
802// no need for critsect we have _criticalSectionRTCPReceiver
803void
804RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
805 RTCPPacketInformation& rtcpPacketInformation)
806{
807 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
808
809 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.NACK.SenderSSRC);
810 if (ptrReceiveInfo == NULL)
811 {
812 // This remote SSRC must be saved before.
813 rtcpParser.Iterate();
814 return;
815 }
816 if (_SSRC != rtcpPacket.NACK.MediaSSRC)
817 {
818 // Not to us.
819 rtcpParser.Iterate();
820 return;
821 }
822
823 rtcpPacketInformation.ResetNACKPacketIdArray();
824
825 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
826 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
827 {
828 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
829 pktType = rtcpParser.Iterate();
830 }
831}
832
833// no need for critsect we have _criticalSectionRTCPReceiver
834void
835RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
836 RTCPPacketInformation& rtcpPacketInformation)
837{
838 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
839
840 WebRtc_UWord16 bitMask = rtcpPacket.NACKItem.BitMask;
841 if(bitMask)
842 {
843 for(int i=1; i <= 16; ++i)
844 {
845 if(bitMask & 0x01)
846 {
847 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
848 }
849 bitMask = bitMask >>1;
850 }
851 }
852
853 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
854}
855
856// no need for critsect we have _criticalSectionRTCPReceiver
857void
858RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser)
859{
860 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
861
862 // clear our lists
863 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
864
865 MapItem* ptrReportBlockInfoItem = _receivedReportBlockMap.Find(rtcpPacket.BYE.SenderSSRC);
866 if (ptrReportBlockInfoItem != NULL)
867 {
868 delete static_cast<RTCPReportBlockInformation*>(ptrReportBlockInfoItem->GetItem());
869 _receivedReportBlockMap.Erase(ptrReportBlockInfoItem);
870 }
871 // we can't delete it due to TMMBR
872 MapItem* ptrReceiveInfoItem = _receivedInfoMap.Find(rtcpPacket.BYE.SenderSSRC);
873 if (ptrReceiveInfoItem != NULL)
874 {
875 static_cast<RTCPReceiveInformation*>(ptrReceiveInfoItem->GetItem())->readyForDelete = true;
876 }
877
878 MapItem* ptrCnameInfoItem = _receivedCnameMap.Find(rtcpPacket.BYE.SenderSSRC);
879 if (ptrCnameInfoItem != NULL)
880 {
881 delete static_cast<RTCPCnameInformation*>(ptrCnameInfoItem->GetItem());
882 _receivedCnameMap.Erase(ptrCnameInfoItem);
883 }
884 rtcpParser.Iterate();
885}
886
887// no need for critsect we have _criticalSectionRTCPReceiver
888void
889RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
890 RTCPPacketInformation& rtcpPacketInformation)
891{
892 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
893
894 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
895
896 if(rtcpPacket.XRVOIPMetricItem.SSRC == _SSRC)
897 {
898 // Store VoIP metrics block if it's about me
899 // from OriginatorSSRC do we filter it?
900 // rtcpPacket.XR.OriginatorSSRC;
901
902 RTCPVoIPMetric receivedVoIPMetrics;
903 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
904 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
905 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
906 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
907 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
908 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
909 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
910 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
911 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
912 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
913 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
914 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
915 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
916 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
917 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
918 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
919 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
920 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
921 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
922 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
923
924 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
925
926 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
927 }
928 rtcpParser.Iterate();
929}
930
931// no need for critsect we have _criticalSectionRTCPReceiver
932void
933RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
934 RTCPPacketInformation& rtcpPacketInformation)
935{
936 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
937
938 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.PLI.SenderSSRC);
939 if (ptrReceiveInfo == NULL)
940 {
941 // This remote SSRC must be saved before.
942 rtcpParser.Iterate();
943 return;
944 }
945 if (_SSRC != rtcpPacket.PLI.MediaSSRC)
946 {
947 // Not to us.
948 rtcpParser.Iterate();
949 return;
950 }
951 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli; // received signal that we need to send a new key frame
952 rtcpParser.Iterate();
953}
954
955// no need for critsect we have _criticalSectionRTCPReceiver
956void
957RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
958 RTCPPacketInformation& rtcpPacketInformation)
959{
960 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
961
962 WebRtc_UWord32 senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
963 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
964 if (ptrReceiveInfo == NULL)
965 {
966 // This remote SSRC must be saved before.
967 rtcpParser.Iterate();
968 return;
969 }
970 if(rtcpPacket.TMMBR.MediaSSRC)
971 {
972 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
973 // in relay mode this is a valid number
974 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
975 }
976
977 // Use packet length to calc max number of TMMBR blocks
978 // each TMMBR block is 8 bytes
979 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
980
981 // sanity
982 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
983 {
984 assert(false);
985 rtcpParser.Iterate();
986 return;
987 }
988 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((WebRtc_UWord32)maxNumOfTMMBRBlocks);
989
990 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
991 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
992 {
993 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
994 pktType = rtcpParser.Iterate();
995 }
996}
997
998// no need for critsect we have _criticalSectionRTCPReceiver
999void
1000RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1001 const RTCPUtility::RTCPPacket& rtcpPacket,
1002 RTCPPacketInformation& rtcpPacketInformation,
1003 const WebRtc_UWord32 senderSSRC)
1004{
1005 if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
1006 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
1007 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +00001008 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1009 _clock.GetTimeInMS());
niklase@google.com470e71d2011-07-07 08:21:25 +00001010 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1011 }
1012}
1013
1014// no need for critsect we have _criticalSectionRTCPReceiver
1015void
1016RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser)
1017{
1018 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1019 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
1020 if (ptrReceiveInfo == NULL)
1021 {
1022 // This remote SSRC must be saved before.
1023 rtcpParser.Iterate();
1024 return;
1025 }
1026 // Use packet length to calc max number of TMMBN blocks
1027 // each TMMBN block is 8 bytes
1028 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1029
1030 // sanity
1031 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1032 {
1033 assert(false);
1034 rtcpParser.Iterate();
1035 return;
1036 }
1037
1038 ptrReceiveInfo->VerifyAndAllocateBoundingSet((WebRtc_UWord32)maxNumOfTMMBNBlocks);
1039
1040 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1041 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1042 {
1043 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1044 pktType = rtcpParser.Iterate();
1045 }
1046}
1047
1048// no need for critsect we have _criticalSectionRTCPReceiver
1049void
1050RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1051 RTCPPacketInformation& rtcpPacketInformation)
1052{
1053 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1054 rtcpParser.Iterate();
1055}
1056
1057// no need for critsect we have _criticalSectionRTCPReceiver
1058void
1059RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1060 const RTCPUtility::RTCPPacket& rtcpPacket)
1061{
1062 const unsigned int idx = receiveInfo.TmmbnBoundingSet.lengthOfSet;
1063
1064 receiveInfo.TmmbnBoundingSet.ptrTmmbrSet[idx] = rtcpPacket.TMMBNItem.MaxTotalMediaBitRate;
1065 receiveInfo.TmmbnBoundingSet.ptrPacketOHSet[idx] = rtcpPacket.TMMBNItem.MeasuredOverhead;
1066 receiveInfo.TmmbnBoundingSet.ptrSsrcSet[idx] = rtcpPacket.TMMBNItem.SSRC;
1067
1068 ++receiveInfo.TmmbnBoundingSet.lengthOfSet;
1069}
1070
1071// no need for critsect we have _criticalSectionRTCPReceiver
1072void
1073RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1074 RTCPPacketInformation& rtcpPacketInformation)
1075{
1076 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1077
1078 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.SLI.SenderSSRC);
1079 if (ptrReceiveInfo == NULL)
1080 {
1081 // This remote SSRC must be saved before.
1082 rtcpParser.Iterate();
1083 return;
1084 }
1085
1086 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1087 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1088 {
1089 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1090 pktType = rtcpParser.Iterate();
1091 }
1092}
1093
1094// no need for critsect we have _criticalSectionRTCPReceiver
1095void
1096RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1097 RTCPPacketInformation& rtcpPacketInformation)
1098{
1099 // in theory there could be multiple slices lost
1100 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1101 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1102}
1103
1104void
1105RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1106 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1107{
1108 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1109
1110 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.RPSI.SenderSSRC);
1111 if (ptrReceiveInfo == NULL)
1112 {
1113 // This remote SSRC must be saved before.
1114 rtcpParser.Iterate();
1115 return;
1116 }
1117 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1118 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1119 {
1120 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1121 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1122 {
1123 // to us unknown
1124 // continue
1125 rtcpParser.Iterate();
1126 return;
1127 }
1128 rtcpPacketInformation.rpsiPictureId = 0;
1129
1130 // convert NativeBitString to rpsiPictureId
1131 WebRtc_UWord8 numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1132 for(WebRtc_UWord8 n = 0; n < (numberOfBytes-1); n++)
1133 {
1134 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1135 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1136 }
1137 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1138 }
1139}
1140
1141// no need for critsect we have _criticalSectionRTCPReceiver
1142void
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001143RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1144 RTCPPacketInformation& rtcpPacketInformation)
1145{
1146 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1147 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode)
1148 {
1149 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1150 }
1151}
1152
1153void
1154RTCPReceiver::HandleREMBItem(RTCPUtility::RTCPParserV2& rtcpParser,
1155 RTCPPacketInformation& rtcpPacketInformation)
1156{
1157 rtcpParser.Iterate();
1158 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1159
1160 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1161 rtcpPacketInformation.receiverEstimatedMaxBitrate = rtcpPacket.REMB.BitRate;
pwestin@webrtc.org1da1ce02011-10-13 15:19:55 +00001162 // TODO(pwestin) send up SSRCs and do a sanity check
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001163}
1164
1165// no need for critsect we have _criticalSectionRTCPReceiver
1166void
niklase@google.com470e71d2011-07-07 08:21:25 +00001167RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1168 RTCPPacketInformation& rtcpPacketInformation)
1169{
1170 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1171
1172 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
1173 if (ptrReceiveInfo == NULL)
1174 {
1175 // This remote SSRC must be saved before.
1176 rtcpParser.Iterate();
1177 return;
1178 }
1179
1180 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1181 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode)
1182 {
1183 HandleFIRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1184 pktType = rtcpParser.Iterate();
1185 }
1186}
1187
1188// no need for critsect we have _criticalSectionRTCPReceiver
1189void
1190RTCPReceiver::HandleFIRItem(RTCPReceiveInformation& receiveInfo,
1191 const RTCPUtility::RTCPPacket& rtcpPacket,
1192 RTCPPacketInformation& rtcpPacketInformation)
1193{
1194 if (_SSRC == rtcpPacket.FIRItem.SSRC) // is it our sender that is requested to generate a new keyframe
1195 {
1196 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1197 // we don't know who this originate from
1198
1199 // check if we have reported this FIRSequenceNumber before
1200 if (rtcpPacket.FIRItem.CommandSequenceNumber != receiveInfo.lastFIRSequenceNumber)
1201 {
1202 //
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +00001203 WebRtc_UWord32 now = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +00001204
1205 // extra sanity don't go crazy with the callbacks
1206 if( (now - receiveInfo.lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS)
1207 {
1208 receiveInfo.lastFIRRequest = now;
1209 receiveInfo.lastFIRSequenceNumber = rtcpPacket.FIRItem.CommandSequenceNumber;
1210
1211 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir; // received signal that we need to send a new key frame
1212 }
1213 }
1214 }
1215}
1216
1217void
1218RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1219 RTCPPacketInformation& rtcpPacketInformation)
1220{
1221 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1222
1223 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1224 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1225 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1226
1227 rtcpParser.Iterate();
1228}
1229
1230void
1231RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1232 RTCPPacketInformation& rtcpPacketInformation)
1233{
1234 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1235
1236 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1237
1238 rtcpParser.Iterate();
1239}
1240
1241void
pwestin@webrtc.org1da1ce02011-10-13 15:19:55 +00001242RTCPReceiver::OnReceivedIntraFrameRequest(const FrameType frameType,
1243 const WebRtc_UWord8 streamIdx) const
niklase@google.com470e71d2011-07-07 08:21:25 +00001244{
1245 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1246
1247 if(_cbVideoFeedback)
1248 {
pwestin@webrtc.org1da1ce02011-10-13 15:19:55 +00001249 _cbVideoFeedback->OnReceivedIntraFrameRequest(_id, frameType, streamIdx);
niklase@google.com470e71d2011-07-07 08:21:25 +00001250 }
1251}
1252
1253void
1254RTCPReceiver::OnReceivedSliceLossIndication(const WebRtc_UWord8 pitureID) const
1255{
1256 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1257
1258 if(_cbRtcpFeedback)
1259 {
1260 _cbRtcpFeedback->OnSLIReceived(_id, pitureID);
1261 }
1262}
1263
1264void
1265RTCPReceiver::OnReceivedReferencePictureSelectionIndication(const WebRtc_UWord64 pitureID) const
1266{
1267 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1268
1269 if(_cbRtcpFeedback)
1270 {
1271 _cbRtcpFeedback->OnRPSIReceived(_id, pitureID);
1272 }
1273}
1274
1275// Holding no Critical section
1276void
1277RTCPReceiver::TriggerCallbacksFromRTCPPacket(RTCPPacketInformation& rtcpPacketInformation)
1278{
1279 // callback if SR or RR
1280 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1281 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)
1282 {
1283 if(rtcpPacketInformation.reportBlock)
1284 {
mflodman@webrtc.org26b97772011-11-24 15:22:33 +00001285 // We only want to trigger one OnNetworkChanged callback per RTCP
1286 // packet. The callback is triggered by a SR, RR and TMMBR, so we
1287 // don't want to trigger one from here if the packet also contains a
1288 // TMMBR block.
1289 bool triggerCallback =
1290 !(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr);
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001291 _rtpRtcp.OnPacketLossStatisticsUpdate(
1292 rtcpPacketInformation.fractionLost,
1293 rtcpPacketInformation.roundTripTime,
mflodman@webrtc.org26b97772011-11-24 15:22:33 +00001294 rtcpPacketInformation.lastReceivedExtendedHighSeqNum,
1295 triggerCallback);
niklase@google.com470e71d2011-07-07 08:21:25 +00001296 }
1297 }
1298 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)
1299 {
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001300 _rtpRtcp.OnReceivedNTP();
niklase@google.com470e71d2011-07-07 08:21:25 +00001301 }
1302 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)
1303 {
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001304 _rtpRtcp.OnRequestSendReport();
niklase@google.com470e71d2011-07-07 08:21:25 +00001305 }
1306 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)
1307 {
1308 if (rtcpPacketInformation.nackSequenceNumbersLength > 0)
1309 {
1310 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id, "SIG [RTCP] Incoming NACK to id:%d", _id);
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001311 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbersLength,
niklase@google.com470e71d2011-07-07 08:21:25 +00001312 rtcpPacketInformation.nackSequenceNumbers);
1313 }
1314 }
1315 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr)
1316 {
1317 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id, "SIG [RTCP] Incoming TMMBR to id:%d", _id);
1318
1319 // might trigger a OnReceivedBandwidthEstimateUpdate
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001320 _rtpRtcp.OnReceivedTMMBR();
niklase@google.com470e71d2011-07-07 08:21:25 +00001321 }
1322 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1323 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir))
1324 {
1325 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli)
1326 {
1327 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id, "SIG [RTCP] Incoming PLI to id:%d", _id);
1328 }else
1329 {
1330 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id, "SIG [RTCP] Incoming FIR to id:%d", _id);
1331 }
pwestin@webrtc.org1da1ce02011-10-13 15:19:55 +00001332 _rtpRtcp.OnReceivedIntraFrameRequest(&_rtpRtcp);
niklase@google.com470e71d2011-07-07 08:21:25 +00001333 }
1334 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli)
1335 {
1336 // we need use a bounce it up to handle default channel
pwestin@webrtc.org1da1ce02011-10-13 15:19:55 +00001337 _rtpRtcp.OnReceivedSliceLossIndication(
1338 rtcpPacketInformation.sliPictureId);
1339 }
1340 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb)
1341 {
1342 // We need to bounce this to the default channel
1343 _rtpRtcp.OnReceivedEstimatedMaxBitrate(
1344 rtcpPacketInformation.receiverEstimatedMaxBitrate);
niklase@google.com470e71d2011-07-07 08:21:25 +00001345 }
1346 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi)
1347 {
1348 // we need use a bounce it up to handle default channel
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001349 _rtpRtcp.OnReceivedReferencePictureSelectionIndication(
1350 rtcpPacketInformation.rpsiPictureId);
niklase@google.com470e71d2011-07-07 08:21:25 +00001351 }
1352 {
1353 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1354
1355 // we need a feedback that we have received a report block(s) so that we can generate a new packet
1356 // in a conference relay scenario, one received report can generate several RTCP packets, based
1357 // on number relayed/mixed
1358 // a send report block should go out to all receivers
1359 if(_cbRtcpFeedback)
1360 {
1361 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)
1362 {
1363 _cbRtcpFeedback->OnSendReportReceived(_id, rtcpPacketInformation.remoteSSRC);
1364 } else
1365 {
1366 _cbRtcpFeedback->OnReceiveReportReceived(_id, rtcpPacketInformation.remoteSSRC);
1367 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001368 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb)
1369 {
1370 _cbRtcpFeedback->OnReceiverEstimatedMaxBitrateReceived(_id,
1371 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1372 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001373 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric)
1374 {
1375 WebRtc_Word8 VoIPmetricBuffer[7*4];
1376 VoIPmetricBuffer[0] = rtcpPacketInformation.VoIPMetric->lossRate;
1377 VoIPmetricBuffer[1] = rtcpPacketInformation.VoIPMetric->discardRate;
1378 VoIPmetricBuffer[2] = rtcpPacketInformation.VoIPMetric->burstDensity;
1379 VoIPmetricBuffer[3] = rtcpPacketInformation.VoIPMetric->gapDensity;
1380
1381 VoIPmetricBuffer[4] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->burstDuration >> 8);
1382 VoIPmetricBuffer[5] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->burstDuration);
1383 VoIPmetricBuffer[6] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->gapDuration >> 8);
1384 VoIPmetricBuffer[7] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->gapDuration);
1385
1386 VoIPmetricBuffer[8] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->roundTripDelay >> 8);
1387 VoIPmetricBuffer[9] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->roundTripDelay);
1388 VoIPmetricBuffer[10] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->endSystemDelay >> 8);
1389 VoIPmetricBuffer[11] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->endSystemDelay);
1390
1391 VoIPmetricBuffer[12] = rtcpPacketInformation.VoIPMetric->signalLevel;
1392 VoIPmetricBuffer[13] = rtcpPacketInformation.VoIPMetric->noiseLevel;
1393 VoIPmetricBuffer[14] = rtcpPacketInformation.VoIPMetric->RERL;
1394 VoIPmetricBuffer[15] = rtcpPacketInformation.VoIPMetric->Gmin;
1395
1396 VoIPmetricBuffer[16] = rtcpPacketInformation.VoIPMetric->Rfactor;
1397 VoIPmetricBuffer[17] = rtcpPacketInformation.VoIPMetric->extRfactor;
1398 VoIPmetricBuffer[18] = rtcpPacketInformation.VoIPMetric->MOSLQ;
1399 VoIPmetricBuffer[19] = rtcpPacketInformation.VoIPMetric->MOSCQ;
1400
1401 VoIPmetricBuffer[20] = rtcpPacketInformation.VoIPMetric->RXconfig;
1402 VoIPmetricBuffer[21] = 0; // reserved
1403 VoIPmetricBuffer[22] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->JBnominal >> 8);
1404 VoIPmetricBuffer[23] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->JBnominal);
1405
1406 VoIPmetricBuffer[24] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->JBmax >> 8);
1407 VoIPmetricBuffer[25] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->JBmax);
1408 VoIPmetricBuffer[26] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->JBabsMax >> 8);
1409 VoIPmetricBuffer[27] = (WebRtc_UWord8)(rtcpPacketInformation.VoIPMetric->JBabsMax);
1410
1411 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id, rtcpPacketInformation.VoIPMetric, VoIPmetricBuffer);
1412 }
1413 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp)
1414 {
1415 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1416 rtcpPacketInformation.applicationSubType,
1417 rtcpPacketInformation.applicationName,
1418 rtcpPacketInformation.applicationLength,
1419 rtcpPacketInformation.applicationData);
1420 }
1421 }
1422 }
1423}
1424
1425void
1426RTCPReceiver::UpdateBandwidthEstimate(const WebRtc_UWord16 bwEstimateKbit)
1427{
1428 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1429
1430 if(_cbRtcpFeedback)
1431 {
1432 _cbRtcpFeedback->OnTMMBRReceived(_id, bwEstimateKbit);
1433 }
1434
1435}
1436
1437WebRtc_Word32
1438RTCPReceiver::CNAME(const WebRtc_UWord32 remoteSSRC,
1439 WebRtc_Word8 cName[RTCP_CNAME_SIZE]) const
1440{
1441 if(cName == NULL)
1442 {
1443 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
1444 return -1;
1445 }
1446
1447 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1448
1449 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
1450 if(cnameInfo == NULL)
1451 {
1452 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "\tfailed to GetCnameInformation(%d)", remoteSSRC);
1453 return -1;
1454 }
1455 memcpy(cName, cnameInfo->name, cnameInfo->length);
1456 cName[cnameInfo->length] = 0;
1457 return 0;
1458}
1459
1460// no callbacks allowed inside this function
1461WebRtc_Word32
1462RTCPReceiver::TMMBRReceived(const WebRtc_UWord32 size,
1463 const WebRtc_UWord32 accNumCandidates,
1464 TMMBRSet* candidateSet) const
1465{
1466 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1467
1468 MapItem* receiveInfoItem=_receivedInfoMap.First();
1469 if(receiveInfoItem == NULL)
1470 {
1471 return -1;
1472 }
1473 WebRtc_UWord32 num = accNumCandidates;
1474 if(candidateSet)
1475 {
1476 while( num < size && receiveInfoItem)
1477 {
1478 RTCPReceiveInformation* receiveInfo = (RTCPReceiveInformation*)receiveInfoItem->GetItem();
1479 if(receiveInfo == NULL)
1480 {
1481 return 0;
1482 }
1483 for (WebRtc_UWord32 i = 0; (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet); i++)
1484 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +00001485 if(receiveInfo->GetTMMBRSet(i, num, candidateSet,
1486 _clock.GetTimeInMS()) == 0)
niklase@google.com470e71d2011-07-07 08:21:25 +00001487 {
1488 num++;
1489 }
1490 }
1491 receiveInfoItem = _receivedInfoMap.Next(receiveInfoItem);
1492 }
1493 } else
1494 {
1495 while(receiveInfoItem)
1496 {
1497 RTCPReceiveInformation* receiveInfo = (RTCPReceiveInformation*)receiveInfoItem->GetItem();
1498 if(receiveInfo == NULL)
1499 {
1500 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s failed to get RTCPReceiveInformation", __FUNCTION__);
1501 return -1;
1502 }
1503 num += receiveInfo->TmmbrSet.lengthOfSet;
1504
1505 receiveInfoItem = _receivedInfoMap.Next(receiveInfoItem);
1506 }
1507 }
1508 return num;
1509}
1510
1511WebRtc_Word32
1512RTCPReceiver::SetPacketTimeout(const WebRtc_UWord32 timeoutMS)
1513{
1514 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1515 _packetTimeOutMS = timeoutMS;
1516 return 0;
1517}
1518
1519void RTCPReceiver::PacketTimeout()
1520{
1521 if(_packetTimeOutMS == 0)
1522 {
1523 // not configured
1524 return;
1525 }
1526
1527 bool packetTimeOut = false;
1528 {
1529 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1530 if(_lastReceived == 0)
1531 {
1532 // not active
1533 return;
1534 }
1535
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +00001536 WebRtc_UWord32 now = _clock.GetTimeInMS();
niklase@google.com470e71d2011-07-07 08:21:25 +00001537
1538 if(now - _lastReceived > _packetTimeOutMS)
1539 {
1540 packetTimeOut = true;
1541 _lastReceived = 0; // only one callback
1542 }
1543 }
1544 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1545 if(packetTimeOut && _cbRtcpFeedback)
1546 {
1547 _cbRtcpFeedback->OnRTCPPacketTimeout(_id);
1548 }
1549}
1550} // namespace webrtc