blob: 698325c9d7f8523912aaace532cad40baa73ba7a [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000011#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
niklase@google.com470e71d2011-07-07 08:21:25 +000013#include <cassert> //assert
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000014#include <string.h> //memset
niklase@google.com470e71d2011-07-07 08:21:25 +000015
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000016#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
17#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
18#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19#include "webrtc/system_wrappers/interface/trace.h"
20#include "webrtc/system_wrappers/interface/trace_event.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000021
22namespace
23{
24 const float FRAC = 4.294967296E9;
25}
26
27namespace webrtc {
28using namespace RTCPUtility;
29using namespace RTCPHelp;
30
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000031// The number of RTCP time intervals needed to trigger a timeout.
32const int kRrTimeoutIntervals = 3;
33
pbos@webrtc.org2f446732013-04-08 11:08:41 +000034RTCPReceiver::RTCPReceiver(const int32_t id, Clock* clock,
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000035 ModuleRtpRtcpImpl* owner)
36 : TMMBRHelp(),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000037 _id(id),
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +000038 _clock(clock),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000039 _method(kRtcpOff),
40 _lastReceived(0),
41 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000042 _criticalSectionFeedbacks(
43 CriticalSectionWrapper::CreateCriticalSection()),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000044 _cbRtcpFeedback(NULL),
45 _cbRtcpBandwidthObserver(NULL),
46 _cbRtcpIntraFrameObserver(NULL),
47 _criticalSectionRTCPReceiver(
48 CriticalSectionWrapper::CreateCriticalSection()),
49 _SSRC(0),
50 _remoteSSRC(0),
51 _remoteSenderInfo(),
52 _lastReceivedSRNTPsecs(0),
53 _lastReceivedSRNTPfrac(0),
54 _receivedInfoMap(),
55 _packetTimeOutMS(0),
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000056 _lastReceivedRrMs(0),
stefan@webrtc.org8ca8a712013-04-23 16:48:32 +000057 _lastIncreasedSequenceNumberMs(0),
58 _rtt(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +000059 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
60 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
61}
62
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000063RTCPReceiver::~RTCPReceiver() {
64 delete _criticalSectionRTCPReceiver;
65 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000066
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000067 while (!_receivedReportBlockMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000068 std::map<uint32_t, RTCPReportBlockInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000069 _receivedReportBlockMap.begin();
70 delete first->second;
71 _receivedReportBlockMap.erase(first);
72 }
73 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000074 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000075 _receivedInfoMap.begin();
76 delete first->second;
77 _receivedInfoMap.erase(first);
78 }
79 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000080 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000081 _receivedCnameMap.begin();
82 delete first->second;
83 _receivedCnameMap.erase(first);
84 }
85 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id,
86 "%s deleted", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +000087}
88
89void
pbos@webrtc.org2f446732013-04-08 11:08:41 +000090RTCPReceiver::ChangeUniqueId(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +000091{
92 _id = id;
93}
94
95RTCPMethod
96RTCPReceiver::Status() const
97{
98 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
99 return _method;
100}
101
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000102int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000103RTCPReceiver::SetRTCPStatus(const RTCPMethod method)
104{
105 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
106 _method = method;
107 return 0;
108}
109
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000110int64_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000111RTCPReceiver::LastReceived()
112{
113 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
114 return _lastReceived;
115}
116
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000117int64_t
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000118RTCPReceiver::LastReceivedReceiverReport() const {
119 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000120 int64_t last_received_rr = -1;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000121 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
122 it != _receivedInfoMap.end(); ++it) {
123 if (it->second->lastTimeReceived > last_received_rr) {
124 last_received_rr = it->second->lastTimeReceived;
125 }
126 }
127 return last_received_rr;
128}
129
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000130int32_t
131RTCPReceiver::SetRemoteSSRC( const uint32_t ssrc)
niklase@google.com470e71d2011-07-07 08:21:25 +0000132{
133 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
134
135 // new SSRC reset old reports
136 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
137 _lastReceivedSRNTPsecs = 0;
138 _lastReceivedSRNTPfrac = 0;
139
140 _remoteSSRC = ssrc;
141 return 0;
142}
143
stefan@webrtc.org66b2e5c2013-07-05 14:30:48 +0000144uint32_t RTCPReceiver::RemoteSSRC() const {
145 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
146 return _remoteSSRC;
147}
148
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000149void RTCPReceiver::RegisterRtcpObservers(
150 RtcpIntraFrameObserver* intra_frame_callback,
151 RtcpBandwidthObserver* bandwidth_callback,
152 RtcpFeedback* feedback_callback) {
153 CriticalSectionScoped lock(_criticalSectionFeedbacks);
154 _cbRtcpIntraFrameObserver = intra_frame_callback;
155 _cbRtcpBandwidthObserver = bandwidth_callback;
156 _cbRtcpFeedback = feedback_callback;
niklase@google.com470e71d2011-07-07 08:21:25 +0000157}
158
niklase@google.com470e71d2011-07-07 08:21:25 +0000159
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000160void RTCPReceiver::SetSSRC(const uint32_t ssrc) {
161 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000162 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000163 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000164 old_ssrc = _SSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000165 _SSRC = ssrc;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000166 }
167 {
168 CriticalSectionScoped lock(_criticalSectionFeedbacks);
169 if (_cbRtcpIntraFrameObserver && old_ssrc != ssrc) {
170 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, ssrc);
171 }
172 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000173}
174
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000175int32_t RTCPReceiver::ResetRTT(const uint32_t remoteSSRC) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000176 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
177 RTCPReportBlockInformation* reportBlock =
178 GetReportBlockInformation(remoteSSRC);
179 if (reportBlock == NULL) {
180 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
181 "\tfailed to GetReportBlockInformation(%u)", remoteSSRC);
182 return -1;
183 }
184 reportBlock->RTT = 0;
185 reportBlock->avgRTT = 0;
186 reportBlock->minRTT = 0;
187 reportBlock->maxRTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000188 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000189}
190
stefan@webrtc.org66b2e5c2013-07-05 14:30:48 +0000191int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000192 uint16_t* RTT,
193 uint16_t* avgRTT,
194 uint16_t* minRTT,
195 uint16_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000196 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000197
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000198 RTCPReportBlockInformation* reportBlock =
199 GetReportBlockInformation(remoteSSRC);
200
201 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000202 return -1;
203 }
204 if (RTT) {
205 *RTT = reportBlock->RTT;
206 }
207 if (avgRTT) {
208 *avgRTT = reportBlock->avgRTT;
209 }
210 if (minRTT) {
211 *minRTT = reportBlock->minRTT;
212 }
213 if (maxRTT) {
214 *maxRTT = reportBlock->maxRTT;
215 }
216 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000217}
218
stefan@webrtc.org8ca8a712013-04-23 16:48:32 +0000219uint16_t RTCPReceiver::RTT() const {
220 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
221 if (!_receivedReportBlockMap.empty()) {
222 return 0;
223 }
224 return _rtt;
225}
226
227int RTCPReceiver::SetRTT(uint16_t rtt) {
228 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
229 if (!_receivedReportBlockMap.empty()) {
230 return -1;
231 }
232 _rtt = rtt;
233 return 0;
234}
235
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000236int32_t
237RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs,
238 uint32_t *ReceivedNTPfrac,
239 uint32_t *RTCPArrivalTimeSecs,
240 uint32_t *RTCPArrivalTimeFrac,
241 uint32_t *rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000242{
243 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
244 if(ReceivedNTPsecs)
245 {
246 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
247 }
248 if(ReceivedNTPfrac)
249 {
250 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
251 }
252 if(RTCPArrivalTimeFrac)
253 {
254 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
255 }
256 if(RTCPArrivalTimeSecs)
257 {
258 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
259 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000260 if (rtcp_timestamp) {
261 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
262 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000263 return 0;
264}
265
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000266int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000267RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
268{
269 if(senderInfo == NULL)
270 {
271 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
272 return -1;
273 }
274 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
275 if(_lastReceivedSRNTPsecs == 0)
276 {
277 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
278 return -1;
279 }
280 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
281 return 0;
282}
283
284// statistics
285// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000286int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000287 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000288 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000289 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
290
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000291 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000292 _receivedReportBlockMap.begin();
293
294 while (it != _receivedReportBlockMap.end()) {
295 receiveBlocks->push_back(it->second->remoteReceiveBlock);
296 it++;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000297 }
298 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000299}
300
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000301int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000302RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
303 RTCPUtility::RTCPParserV2* rtcpParser)
304{
305 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
306
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000307 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000308
309 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
310 while (pktType != RTCPUtility::kRtcpNotValidCode)
311 {
312 // Each "case" is responsible for iterate the parser to the
313 // next top level packet.
314 switch (pktType)
315 {
316 case RTCPUtility::kRtcpSrCode:
317 case RTCPUtility::kRtcpRrCode:
318 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
319 break;
320 case RTCPUtility::kRtcpSdesCode:
321 HandleSDES(*rtcpParser);
322 break;
323 case RTCPUtility::kRtcpXrVoipMetricCode:
324 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
325 break;
326 case RTCPUtility::kRtcpByeCode:
327 HandleBYE(*rtcpParser);
328 break;
329 case RTCPUtility::kRtcpRtpfbNackCode:
330 HandleNACK(*rtcpParser, rtcpPacketInformation);
331 break;
332 case RTCPUtility::kRtcpRtpfbTmmbrCode:
333 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
334 break;
335 case RTCPUtility::kRtcpRtpfbTmmbnCode:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000336 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000337 break;
338 case RTCPUtility::kRtcpRtpfbSrReqCode:
339 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
340 break;
341 case RTCPUtility::kRtcpPsfbPliCode:
342 HandlePLI(*rtcpParser, rtcpPacketInformation);
343 break;
344 case RTCPUtility::kRtcpPsfbSliCode:
345 HandleSLI(*rtcpParser, rtcpPacketInformation);
346 break;
347 case RTCPUtility::kRtcpPsfbRpsiCode:
348 HandleRPSI(*rtcpParser, rtcpPacketInformation);
349 break;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000350 case RTCPUtility::kRtcpExtendedIjCode:
351 HandleIJ(*rtcpParser, rtcpPacketInformation);
352 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000353 case RTCPUtility::kRtcpPsfbFirCode:
354 HandleFIR(*rtcpParser, rtcpPacketInformation);
355 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000356 case RTCPUtility::kRtcpPsfbAppCode:
357 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
358 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000359 case RTCPUtility::kRtcpAppCode:
360 // generic application messages
361 HandleAPP(*rtcpParser, rtcpPacketInformation);
362 break;
363 case RTCPUtility::kRtcpAppItemCode:
364 // generic application messages
365 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
366 break;
367 default:
368 rtcpParser->Iterate();
369 break;
370 }
371 pktType = rtcpParser->PacketType();
372 }
373 return 0;
374}
375
376// no need for critsect we have _criticalSectionRTCPReceiver
377void
378RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
379 RTCPPacketInformation& rtcpPacketInformation)
380{
381 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
382 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
383
384 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
385
386 // SR.SenderSSRC
387 // The synchronization source identifier for the originator of this SR packet
388
389 // rtcpPacket.RR.SenderSSRC
390 // The source of the packet sender, same as of SR? or is this a CE?
391
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000392 const uint32_t remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
393 const uint8_t numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
niklase@google.com470e71d2011-07-07 08:21:25 +0000394
395 rtcpPacketInformation.remoteSSRC = remoteSSRC;
396
397 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
398 if (!ptrReceiveInfo)
399 {
400 rtcpParser.Iterate();
401 return;
402 }
403
404 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
405 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000406 TRACE_EVENT_INSTANT2("webrtc_rtp", "SR",
407 "remote_ssrc", remoteSSRC,
408 "ssrc", _SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000409
410 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
411 {
412 // only signal that we have received a SR when we accept one
413 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
414
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000415 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
416 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
417 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
418
niklase@google.com470e71d2011-07-07 08:21:25 +0000419 // 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
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +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 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000437 TRACE_EVENT_INSTANT2("webrtc_rtp", "RR",
438 "remote_ssrc", remoteSSRC,
439 "ssrc", _SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000440
441 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
442 }
443 UpdateReceiveInformation(*ptrReceiveInfo);
444
445 rtcpPacketType = rtcpParser.Iterate();
446
447 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
448 {
449 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
450 rtcpPacketType = rtcpParser.Iterate();
451 }
452}
453
454// no need for critsect we have _criticalSectionRTCPReceiver
455void
456RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
457 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000458 const uint32_t remoteSSRC,
459 const uint8_t numberOfReportBlocks) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000460 // This will be called once per report block in the RTCP packet.
461 // We filter out all report blocks that are not for us.
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.
niklase@google.com470e71d2011-07-07 08:21:25 +0000465
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000466 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
467 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000468
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000469 // Filter out all report blocks that are not for us.
470 if (rtcpPacket.ReportBlockItem.SSRC != _SSRC) {
471 // This block is not for us ignore it.
472 return;
473 }
474
475 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
476 // _criticalSectionRTCPReceiver.
477 _criticalSectionRTCPReceiver->Leave();
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000478 uint32_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000479 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
480 _criticalSectionRTCPReceiver->Enter();
481
482 RTCPReportBlockInformation* reportBlock =
483 CreateReportBlockInformation(remoteSSRC);
484 if (reportBlock == NULL) {
485 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
486 "\tfailed to CreateReportBlockInformation(%u)", remoteSSRC);
487 return;
488 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000489
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000490 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000491 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000492 TRACE_COUNTER_ID1("webrtc_rtp", "RRFractionLost", rb.SSRC, rb.FractionLost);
493 TRACE_COUNTER_ID1("webrtc_rtp", "RRCumulativeNumOfPacketLost",
494 rb.SSRC, rb.CumulativeNumOfPacketsLost);
495 TRACE_COUNTER_ID1("webrtc_rtp", "RRJitter", rb.SSRC, rb.Jitter);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000496 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
497 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
498 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
499 reportBlock->remoteReceiveBlock.cumulativeLost =
500 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000501 if (rb.ExtendedHighestSequenceNumber >
502 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
503 // We have successfully delivered new RTP packets to the remote side after
504 // the last RR was sent from the remote side.
505 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000506 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000507 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
508 rb.ExtendedHighestSequenceNumber;
509 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
510 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
511 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
512
513 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
514 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
515 }
516
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000517 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000518 rtcpPacket.ReportBlockItem.DelayLastSR;
519
520 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000521 uint32_t lastReceivedRRNTPsecs = 0;
522 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000523
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000524 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000525
526 // time when we received this in MS
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000527 uint32_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
528 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000529
530 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000531 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000532 d /= 65536;
533 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
534
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000535 int32_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000536
537 if (sendTimeMS > 0) {
538 RTT = receiveTimeMS - d - sendTimeMS;
539 if (RTT <= 0) {
540 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000541 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000542 if (RTT > reportBlock->maxRTT) {
543 // store max RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000544 reportBlock->maxRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000545 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000546 if (reportBlock->minRTT == 0) {
547 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000548 reportBlock->minRTT = (uint16_t) RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000549 } else if (RTT < reportBlock->minRTT) {
550 // Store min RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000551 reportBlock->minRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000552 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000553 // store last RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000554 reportBlock->RTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000555
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000556 // store average RTT
557 if (reportBlock->numAverageCalcs != 0) {
558 float ac = static_cast<float> (reportBlock->numAverageCalcs);
559 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
560 + ((1 / (ac + 1)) * RTT);
561 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
562 } else {
563 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000564 reportBlock->avgRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000565 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000566 reportBlock->numAverageCalcs++;
567 }
568
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000569 TRACE_COUNTER_ID1("webrtc_rtp", "RR_RTT", rb.SSRC, RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000570
571 // rtcpPacketInformation
572 rtcpPacketInformation.AddReportInfo(
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000573 reportBlock->remoteReceiveBlock.fractionLost, (uint16_t) RTT,
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000574 reportBlock->remoteReceiveBlock.extendedHighSeqNum,
575 reportBlock->remoteReceiveBlock.jitter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000576}
577
578RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000579RTCPReceiver::CreateReportBlockInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000580 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000581
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000582 std::map<uint32_t, RTCPReportBlockInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000583 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000584
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000585 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
586 if (it != _receivedReportBlockMap.end()) {
587 ptrReportBlockInfo = it->second;
588 } else {
589 ptrReportBlockInfo = new RTCPReportBlockInformation;
590 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
591 }
592 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000593}
594
595RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000596RTCPReceiver::GetReportBlockInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000597 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000598
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000599 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000600 _receivedReportBlockMap.find(remoteSSRC);
601
602 if (it == _receivedReportBlockMap.end()) {
603 return NULL;
604 }
605 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000606}
607
608RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000609RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000610 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000611
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000612 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000613 _receivedCnameMap.find(remoteSSRC);
614
615 if (it != _receivedCnameMap.end()) {
616 return it->second;
617 }
618 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000619 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000620 _receivedCnameMap[remoteSSRC] = cnameInfo;
621 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000622}
623
624RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000625RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000626 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000627
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000628 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000629 _receivedCnameMap.find(remoteSSRC);
630
631 if (it == _receivedCnameMap.end()) {
632 return NULL;
633 }
634 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000635}
636
637RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000638RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000639 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000640
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000641 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000642 _receivedInfoMap.find(remoteSSRC);
643
644 if (it != _receivedInfoMap.end()) {
645 return it->second;
646 }
647 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
648 _receivedInfoMap[remoteSSRC] = receiveInfo;
649 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000650}
651
652RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000653RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000654 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000655
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000656 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000657 _receivedInfoMap.find(remoteSSRC);
658 if (it == _receivedInfoMap.end()) {
659 return NULL;
660 }
661 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000662}
663
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000664void RTCPReceiver::UpdateReceiveInformation(
665 RTCPReceiveInformation& receiveInformation) {
666 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000667 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000668}
669
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000670bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
671 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
672 if (_lastReceivedRrMs == 0)
673 return false;
674
675 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000676 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000677 // Reset the timer to only trigger one log.
678 _lastReceivedRrMs = 0;
679 return true;
680 }
681 return false;
682}
683
684bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
685 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
686 if (_lastIncreasedSequenceNumberMs == 0)
687 return false;
688
689 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000690 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000691 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000692 // Reset the timer to only trigger one log.
693 _lastIncreasedSequenceNumberMs = 0;
694 return true;
695 }
696 return false;
697}
698
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000699bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
700 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000701
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000702 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000703 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000704
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000705 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000706 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000707
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000708 while (receiveInfoIt != _receivedInfoMap.end()) {
709 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
710 if (receiveInfo == NULL) {
711 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000712 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000713 // time since last received rtcp packet
714 // when we dont have a lastTimeReceived and the object is marked
715 // readyForDelete it's removed from the map
716 if (receiveInfo->lastTimeReceived) {
717 /// use audio define since we don't know what interval the remote peer is
718 // using
719 if ((timeNow - receiveInfo->lastTimeReceived) >
720 5 * RTCP_INTERVAL_AUDIO_MS) {
721 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000722 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000723 // prevent that we call this over and over again
724 receiveInfo->lastTimeReceived = 0;
725 // send new TMMBN to all channels using the default codec
726 updateBoundingSet = true;
727 }
728 receiveInfoIt++;
729 } else if (receiveInfo->readyForDelete) {
730 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000731 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000732 receiveInfoItemToBeErased = receiveInfoIt;
733 receiveInfoIt++;
734 delete receiveInfoItemToBeErased->second;
735 _receivedInfoMap.erase(receiveInfoItemToBeErased);
736 } else {
737 receiveInfoIt++;
738 }
739 }
740 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000741}
742
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000743int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000744 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000745
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000746 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000747 _receivedInfoMap.find(_remoteSSRC);
748
749 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000750 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000751 }
752 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
753 if (receiveInfo == NULL) {
754 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
755 "%s failed to get RTCPReceiveInformation",
756 __FUNCTION__);
757 return -1;
758 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000759 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000760 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000761 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000762 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000763 i++) {
764 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == _SSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000765 // owner of bounding set
766 tmmbrOwner = true;
767 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000768 boundingSetRec->SetEntry(i,
769 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
770 receiveInfo->TmmbnBoundingSet.PacketOH(i),
771 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000772 }
773 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000774 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000775}
776
777// no need for critsect we have _criticalSectionRTCPReceiver
778void
779RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
780{
781 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
782 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
783 {
784 HandleSDESChunk(rtcpParser);
785 pktType = rtcpParser.Iterate();
786 }
787}
788
789// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000790void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
791 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
792 RTCPCnameInformation* cnameInfo =
793 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
794 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000795
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000796 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
797 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000798}
799
800// no need for critsect we have _criticalSectionRTCPReceiver
801void
802RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
803 RTCPPacketInformation& rtcpPacketInformation)
804{
805 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000806 if (_SSRC != rtcpPacket.NACK.MediaSSRC)
807 {
808 // Not to us.
809 rtcpParser.Iterate();
810 return;
811 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000812 rtcpPacketInformation.ResetNACKPacketIdArray();
813
814 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
815 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
816 {
817 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
818 pktType = rtcpParser.Iterate();
819 }
820}
821
822// no need for critsect we have _criticalSectionRTCPReceiver
823void
824RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
825 RTCPPacketInformation& rtcpPacketInformation)
826{
827 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
828
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000829 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
niklase@google.com470e71d2011-07-07 08:21:25 +0000830 if(bitMask)
831 {
832 for(int i=1; i <= 16; ++i)
833 {
834 if(bitMask & 0x01)
835 {
836 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
837 }
838 bitMask = bitMask >>1;
839 }
840 }
841
842 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
843}
844
845// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000846void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
847 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000848
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000849 // clear our lists
850 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000851 std::map<uint32_t, RTCPReportBlockInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000852 reportBlockInfoIt = _receivedReportBlockMap.find(
853 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000854
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000855 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
856 delete reportBlockInfoIt->second;
857 _receivedReportBlockMap.erase(reportBlockInfoIt);
858 }
859 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000860 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000861 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000862
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000863 if (receiveInfoIt != _receivedInfoMap.end()) {
864 receiveInfoIt->second->readyForDelete = true;
865 }
866
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000867 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000868 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
869
870 if (cnameInfoIt != _receivedCnameMap.end()) {
871 delete cnameInfoIt->second;
872 _receivedCnameMap.erase(cnameInfoIt);
873 }
874 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000875}
876
877// no need for critsect we have _criticalSectionRTCPReceiver
878void
879RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
880 RTCPPacketInformation& rtcpPacketInformation)
881{
882 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
883
884 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
885
886 if(rtcpPacket.XRVOIPMetricItem.SSRC == _SSRC)
887 {
888 // Store VoIP metrics block if it's about me
889 // from OriginatorSSRC do we filter it?
890 // rtcpPacket.XR.OriginatorSSRC;
891
892 RTCPVoIPMetric receivedVoIPMetrics;
893 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
894 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
895 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
896 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
897 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
898 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
899 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
900 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
901 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
902 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
903 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
904 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
905 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
906 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
907 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
908 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
909 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
910 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
911 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
912 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
913
914 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
915
916 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
917 }
918 rtcpParser.Iterate();
919}
920
921// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000922void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
923 RTCPPacketInformation& rtcpPacketInformation) {
924 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
925 if (_SSRC == rtcpPacket.PLI.MediaSSRC) {
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000926 TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
927
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000928 // Received a signal that we need to send a new key frame.
929 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
930 }
931 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000932}
933
934// no need for critsect we have _criticalSectionRTCPReceiver
935void
936RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
937 RTCPPacketInformation& rtcpPacketInformation)
938{
939 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
940
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000941 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000942 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
943 if (ptrReceiveInfo == NULL)
944 {
945 // This remote SSRC must be saved before.
946 rtcpParser.Iterate();
947 return;
948 }
949 if(rtcpPacket.TMMBR.MediaSSRC)
950 {
951 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
952 // in relay mode this is a valid number
953 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
954 }
955
956 // Use packet length to calc max number of TMMBR blocks
957 // each TMMBR block is 8 bytes
958 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
959
960 // sanity
961 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
962 {
963 assert(false);
964 rtcpParser.Iterate();
965 return;
966 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000967 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +0000968
969 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
970 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
971 {
972 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
973 pktType = rtcpParser.Iterate();
974 }
975}
976
977// no need for critsect we have _criticalSectionRTCPReceiver
978void
979RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
980 const RTCPUtility::RTCPPacket& rtcpPacket,
981 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000982 const uint32_t senderSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000983{
984 if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
985 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
986 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000987 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000988 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +0000989 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
990 }
991}
992
993// no need for critsect we have _criticalSectionRTCPReceiver
994void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000995RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
996 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +0000997{
998 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
999 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
1000 if (ptrReceiveInfo == NULL)
1001 {
1002 // This remote SSRC must be saved before.
1003 rtcpParser.Iterate();
1004 return;
1005 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +00001006 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +00001007 // Use packet length to calc max number of TMMBN blocks
1008 // each TMMBN block is 8 bytes
1009 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1010
1011 // sanity
1012 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1013 {
1014 assert(false);
1015 rtcpParser.Iterate();
1016 return;
1017 }
1018
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001019 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001020
1021 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1022 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1023 {
1024 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1025 pktType = rtcpParser.Iterate();
1026 }
1027}
1028
1029// no need for critsect we have _criticalSectionRTCPReceiver
1030void
1031RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1032 RTCPPacketInformation& rtcpPacketInformation)
1033{
1034 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1035 rtcpParser.Iterate();
1036}
1037
1038// no need for critsect we have _criticalSectionRTCPReceiver
1039void
1040RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1041 const RTCPUtility::RTCPPacket& rtcpPacket)
1042{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001043 receiveInfo.TmmbnBoundingSet.AddEntry(
1044 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1045 rtcpPacket.TMMBNItem.MeasuredOverhead,
1046 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001047}
1048
1049// no need for critsect we have _criticalSectionRTCPReceiver
1050void
1051RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1052 RTCPPacketInformation& rtcpPacketInformation)
1053{
1054 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001055 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1056 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1057 {
1058 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1059 pktType = rtcpParser.Iterate();
1060 }
1061}
1062
1063// no need for critsect we have _criticalSectionRTCPReceiver
1064void
1065RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1066 RTCPPacketInformation& rtcpPacketInformation)
1067{
1068 // in theory there could be multiple slices lost
1069 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1070 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1071}
1072
1073void
1074RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1075 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1076{
1077 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001078 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1079 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1080 {
1081 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1082 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1083 {
1084 // to us unknown
1085 // continue
1086 rtcpParser.Iterate();
1087 return;
1088 }
1089 rtcpPacketInformation.rpsiPictureId = 0;
1090
1091 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001092 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1093 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001094 {
1095 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1096 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1097 }
1098 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1099 }
1100}
1101
1102// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001103void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1104 RTCPPacketInformation& rtcpPacketInformation) {
1105 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1106 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1107 pktType = rtcpParser.Iterate();
1108 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1109 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1110 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001111 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001112 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001113}
1114
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001115// no need for critsect we have _criticalSectionRTCPReceiver
1116void
1117RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1118 RTCPPacketInformation& rtcpPacketInformation)
1119{
1120 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1121
1122 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1123 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1124 {
1125 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1126 pktType = rtcpParser.Iterate();
1127 }
1128}
1129
1130void
1131RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1132 RTCPPacketInformation& rtcpPacketInformation)
1133{
1134 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1135 rtcpPacketInformation.interArrivalJitter =
1136 rtcpPacket.ExtendedJitterReportItem.Jitter;
1137}
1138
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001139void RTCPReceiver::HandleREMBItem(
1140 RTCPUtility::RTCPParserV2& rtcpParser,
1141 RTCPPacketInformation& rtcpPacketInformation) {
1142 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1143 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1144 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1145 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001146}
1147
1148// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001149void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1150 RTCPPacketInformation& rtcpPacketInformation) {
1151 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1152 RTCPReceiveInformation* ptrReceiveInfo =
1153 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001154
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001155 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1156 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1157 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1158 pktType = rtcpParser.Iterate();
1159 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001160}
1161
1162// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001163void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1164 const RTCPUtility::RTCPPacket& rtcpPacket,
1165 RTCPPacketInformation& rtcpPacketInformation) {
1166 // Is it our sender that is requested to generate a new keyframe
1167 if (_SSRC != rtcpPacket.FIRItem.SSRC) {
1168 return;
1169 }
1170 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1171 // we don't know who this originate from
1172 if (receiveInfo) {
1173 // check if we have reported this FIRSequenceNumber before
1174 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1175 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001176 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001177 // sanity; don't go crazy with the callbacks
1178 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1179 receiveInfo->lastFIRRequest = now;
1180 receiveInfo->lastFIRSequenceNumber =
1181 rtcpPacket.FIRItem.CommandSequenceNumber;
1182 // received signal that we need to send a new key frame
1183 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1184 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001185 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001186 } else {
1187 // received signal that we need to send a new key frame
1188 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1189 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001190}
1191
1192void
1193RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1194 RTCPPacketInformation& rtcpPacketInformation)
1195{
1196 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1197
1198 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1199 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1200 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1201
1202 rtcpParser.Iterate();
1203}
1204
1205void
1206RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1207 RTCPPacketInformation& rtcpPacketInformation)
1208{
1209 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1210
1211 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1212
1213 rtcpParser.Iterate();
1214}
1215
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001216int32_t RTCPReceiver::UpdateTMMBR() {
1217 int32_t numBoundingSet = 0;
1218 uint32_t bitrate = 0;
1219 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001220
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001221 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001222 if (size > 0) {
1223 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1224 // Get candidate set from receiver.
1225 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1226 } else {
1227 // Candidate set empty.
1228 VerifyAndAllocateCandidateSet(0); // resets candidate set
1229 }
1230 // Find bounding set
1231 TMMBRSet* boundingSet = NULL;
1232 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1233 if (numBoundingSet == -1) {
1234 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1235 "Failed to find TMMBR bounding set.");
1236 return -1;
1237 }
1238 // Set bounding set
1239 // Inform remote clients about the new bandwidth
1240 // inform the remote client
1241 _rtpRtcp.SetTMMBN(boundingSet);
1242
1243 // might trigger a TMMBN
1244 if (numBoundingSet == 0) {
1245 // owner of max bitrate request has timed out
1246 // empty bounding set has been sent
1247 return 0;
1248 }
1249 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001250 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001251 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001252 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1253 if (_cbRtcpBandwidthObserver) {
1254 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1255 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1256 "Set TMMBR request:%d kbps", bitrate);
1257 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001258 }
1259 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001260}
1261
1262// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001263void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001264 RTCPPacketInformation& rtcpPacketInformation) {
1265 // Process TMMBR and REMB first to avoid multiple callbacks
1266 // to OnNetworkChanged.
1267 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1268 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1269 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001270
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001271 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1272 UpdateTMMBR();
1273 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001274 unsigned int local_ssrc = 0;
1275 {
1276 // We don't want to hold this critsect when triggering the callbacks below.
1277 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1278 local_ssrc = _SSRC;
1279 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001280 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1281 _rtpRtcp.OnRequestSendReport();
1282 }
1283 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001284 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001285 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1286 "SIG [RTCP] Incoming NACK length:%d",
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001287 rtcpPacketInformation.nackSequenceNumbers.size());
1288 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001289 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001290 }
1291 {
1292 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001293
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001294 // We need feedback that we have received a report block(s) so that we
1295 // can generate a new packet in a conference relay scenario, one received
1296 // report can generate several RTCP packets, based on number relayed/mixed
1297 // a send report block should go out to all receivers.
1298 if (_cbRtcpIntraFrameObserver) {
1299 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1300 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1301 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1302 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1303 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1304 rtcpPacketInformation.remoteSSRC);
1305 } else {
1306 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1307 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1308 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001309 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001310 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001311 }
1312 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1313 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001314 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001315 }
1316 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1317 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001318 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001319 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001320 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001321 if (_cbRtcpBandwidthObserver) {
1322 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1323 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1324 "SIG [RTCP] Incoming REMB:%d",
1325 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1326 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1327 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1328 }
1329 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1330 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
1331 rtcpPacketInformation.reportBlock) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001332 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001333 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
1334 rtcpPacketInformation.remoteSSRC,
1335 rtcpPacketInformation.fractionLost,
1336 rtcpPacketInformation.roundTripTime,
1337 rtcpPacketInformation.lastReceivedExtendedHighSeqNum,
1338 now);
1339 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001340 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001341 if(_cbRtcpFeedback) {
solenberg@webrtc.org91811e22013-06-25 20:36:14 +00001342 if(!(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001343 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1344 rtcpPacketInformation.remoteSSRC);
1345 }
1346 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1347 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1348 rtcpPacketInformation.VoIPMetric);
1349 }
1350 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1351 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1352 rtcpPacketInformation.applicationSubType,
1353 rtcpPacketInformation.applicationName,
1354 rtcpPacketInformation.applicationLength,
1355 rtcpPacketInformation.applicationData);
1356 }
1357 }
1358 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001359}
1360
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001361int32_t RTCPReceiver::CNAME(const uint32_t remoteSSRC,
1362 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001363 assert(cName);
1364
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001365 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1366 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001367 if (cnameInfo == NULL) {
1368 return -1;
1369 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001370 cName[RTCP_CNAME_SIZE - 1] = 0;
1371 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1372 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001373}
1374
1375// no callbacks allowed inside this function
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001376int32_t RTCPReceiver::TMMBRReceived(const uint32_t size,
1377 const uint32_t accNumCandidates,
1378 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001379 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001380
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001381 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001382 receiveInfoIt = _receivedInfoMap.begin();
1383 if (receiveInfoIt == _receivedInfoMap.end()) {
1384 return -1;
1385 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001386 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001387 if (candidateSet) {
1388 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1389 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1390 if (receiveInfo == NULL) {
1391 return 0;
1392 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001393 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001394 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001395 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001396 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001397 num++;
1398 }
1399 }
1400 receiveInfoIt++;
1401 }
1402 } else {
1403 while (receiveInfoIt != _receivedInfoMap.end()) {
1404 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1405 if(receiveInfo == NULL) {
1406 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1407 "%s failed to get RTCPReceiveInformation",
1408 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001409 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001410 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001411 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001412 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001413 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001414 }
1415 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001416}
1417
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001418} // namespace webrtc