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