blob: 6bc0044916add2e403f23745545b829d7a464ee4 [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
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <assert.h> //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
wu@webrtc.org822fbd82013-08-15 23:38:54 +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
wu@webrtc.org822fbd82013-08-15 23:38:54 +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);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000409
niklase@google.com470e71d2011-07-07 08:21:25 +0000410 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;
492 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
493 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
494 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
495 reportBlock->remoteReceiveBlock.cumulativeLost =
496 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000497 if (rb.ExtendedHighestSequenceNumber >
498 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
499 // We have successfully delivered new RTP packets to the remote side after
500 // the last RR was sent from the remote side.
501 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000502 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000503 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
504 rb.ExtendedHighestSequenceNumber;
505 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
506 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
507 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
508
509 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
510 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
511 }
512
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000513 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000514 rtcpPacket.ReportBlockItem.DelayLastSR;
515
516 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000517 uint32_t lastReceivedRRNTPsecs = 0;
518 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000519
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000520 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000521
522 // time when we received this in MS
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000523 uint32_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
524 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000525
526 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000527 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000528 d /= 65536;
529 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
530
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000531 int32_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000532
533 if (sendTimeMS > 0) {
534 RTT = receiveTimeMS - d - sendTimeMS;
535 if (RTT <= 0) {
536 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000537 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000538 if (RTT > reportBlock->maxRTT) {
539 // store max RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000540 reportBlock->maxRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000541 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000542 if (reportBlock->minRTT == 0) {
543 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000544 reportBlock->minRTT = (uint16_t) RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000545 } else if (RTT < reportBlock->minRTT) {
546 // Store min RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000547 reportBlock->minRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000548 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000549 // store last RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000550 reportBlock->RTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000551
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000552 // store average RTT
553 if (reportBlock->numAverageCalcs != 0) {
554 float ac = static_cast<float> (reportBlock->numAverageCalcs);
555 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
556 + ((1 / (ac + 1)) * RTT);
557 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
558 } else {
559 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000560 reportBlock->avgRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000561 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000562 reportBlock->numAverageCalcs++;
563 }
564
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000565 TRACE_COUNTER_ID1("webrtc_rtp", "RR_RTT", rb.SSRC, RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000566
567 // rtcpPacketInformation
568 rtcpPacketInformation.AddReportInfo(
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000569 reportBlock->remoteReceiveBlock.fractionLost, (uint16_t) RTT,
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000570 reportBlock->remoteReceiveBlock.extendedHighSeqNum,
571 reportBlock->remoteReceiveBlock.jitter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000572}
573
574RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000575RTCPReceiver::CreateReportBlockInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000576 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000577
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000578 std::map<uint32_t, RTCPReportBlockInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000579 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000580
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000581 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
582 if (it != _receivedReportBlockMap.end()) {
583 ptrReportBlockInfo = it->second;
584 } else {
585 ptrReportBlockInfo = new RTCPReportBlockInformation;
586 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
587 }
588 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000589}
590
591RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000592RTCPReceiver::GetReportBlockInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000593 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000594
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000595 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000596 _receivedReportBlockMap.find(remoteSSRC);
597
598 if (it == _receivedReportBlockMap.end()) {
599 return NULL;
600 }
601 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000602}
603
604RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000605RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000606 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000607
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000608 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000609 _receivedCnameMap.find(remoteSSRC);
610
611 if (it != _receivedCnameMap.end()) {
612 return it->second;
613 }
614 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000615 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000616 _receivedCnameMap[remoteSSRC] = cnameInfo;
617 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000618}
619
620RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000621RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000622 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000623
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000624 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000625 _receivedCnameMap.find(remoteSSRC);
626
627 if (it == _receivedCnameMap.end()) {
628 return NULL;
629 }
630 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000631}
632
633RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000634RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000635 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000636
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000637 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000638 _receivedInfoMap.find(remoteSSRC);
639
640 if (it != _receivedInfoMap.end()) {
641 return it->second;
642 }
643 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
644 _receivedInfoMap[remoteSSRC] = receiveInfo;
645 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000646}
647
648RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000649RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000650 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000651
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000652 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000653 _receivedInfoMap.find(remoteSSRC);
654 if (it == _receivedInfoMap.end()) {
655 return NULL;
656 }
657 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000658}
659
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000660void RTCPReceiver::UpdateReceiveInformation(
661 RTCPReceiveInformation& receiveInformation) {
662 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000663 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000664}
665
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000666bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
667 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
668 if (_lastReceivedRrMs == 0)
669 return false;
670
671 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000672 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000673 // Reset the timer to only trigger one log.
674 _lastReceivedRrMs = 0;
675 return true;
676 }
677 return false;
678}
679
680bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
681 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
682 if (_lastIncreasedSequenceNumberMs == 0)
683 return false;
684
685 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000686 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000687 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000688 // Reset the timer to only trigger one log.
689 _lastIncreasedSequenceNumberMs = 0;
690 return true;
691 }
692 return false;
693}
694
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000695bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
696 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000697
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000698 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000699 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000700
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000701 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000702 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000703
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000704 while (receiveInfoIt != _receivedInfoMap.end()) {
705 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
706 if (receiveInfo == NULL) {
707 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000708 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000709 // time since last received rtcp packet
710 // when we dont have a lastTimeReceived and the object is marked
711 // readyForDelete it's removed from the map
712 if (receiveInfo->lastTimeReceived) {
713 /// use audio define since we don't know what interval the remote peer is
714 // using
715 if ((timeNow - receiveInfo->lastTimeReceived) >
716 5 * RTCP_INTERVAL_AUDIO_MS) {
717 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000718 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000719 // prevent that we call this over and over again
720 receiveInfo->lastTimeReceived = 0;
721 // send new TMMBN to all channels using the default codec
722 updateBoundingSet = true;
723 }
724 receiveInfoIt++;
725 } else if (receiveInfo->readyForDelete) {
726 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000727 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000728 receiveInfoItemToBeErased = receiveInfoIt;
729 receiveInfoIt++;
730 delete receiveInfoItemToBeErased->second;
731 _receivedInfoMap.erase(receiveInfoItemToBeErased);
732 } else {
733 receiveInfoIt++;
734 }
735 }
736 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000737}
738
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000739int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000740 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000741
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000742 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000743 _receivedInfoMap.find(_remoteSSRC);
744
745 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000746 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000747 }
748 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
749 if (receiveInfo == NULL) {
750 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
751 "%s failed to get RTCPReceiveInformation",
752 __FUNCTION__);
753 return -1;
754 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000755 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000756 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000757 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000758 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000759 i++) {
760 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == _SSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000761 // owner of bounding set
762 tmmbrOwner = true;
763 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000764 boundingSetRec->SetEntry(i,
765 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
766 receiveInfo->TmmbnBoundingSet.PacketOH(i),
767 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000768 }
769 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000770 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000771}
772
773// no need for critsect we have _criticalSectionRTCPReceiver
774void
775RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
776{
777 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
778 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
779 {
780 HandleSDESChunk(rtcpParser);
781 pktType = rtcpParser.Iterate();
782 }
783}
784
785// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000786void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
787 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
788 RTCPCnameInformation* cnameInfo =
789 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
790 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000791
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000792 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
793 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000794}
795
796// no need for critsect we have _criticalSectionRTCPReceiver
797void
798RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
799 RTCPPacketInformation& rtcpPacketInformation)
800{
801 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000802 if (_SSRC != rtcpPacket.NACK.MediaSSRC)
803 {
804 // Not to us.
805 rtcpParser.Iterate();
806 return;
807 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000808 rtcpPacketInformation.ResetNACKPacketIdArray();
809
810 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
811 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
812 {
813 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
814 pktType = rtcpParser.Iterate();
815 }
816}
817
818// no need for critsect we have _criticalSectionRTCPReceiver
819void
820RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
821 RTCPPacketInformation& rtcpPacketInformation)
822{
823 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
824
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000825 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
niklase@google.com470e71d2011-07-07 08:21:25 +0000826 if(bitMask)
827 {
828 for(int i=1; i <= 16; ++i)
829 {
830 if(bitMask & 0x01)
831 {
832 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
833 }
834 bitMask = bitMask >>1;
835 }
836 }
837
838 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
839}
840
841// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000842void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
843 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000844
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000845 // clear our lists
846 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000847 std::map<uint32_t, RTCPReportBlockInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000848 reportBlockInfoIt = _receivedReportBlockMap.find(
849 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000850
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000851 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
852 delete reportBlockInfoIt->second;
853 _receivedReportBlockMap.erase(reportBlockInfoIt);
854 }
855 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000856 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000857 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000858
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000859 if (receiveInfoIt != _receivedInfoMap.end()) {
860 receiveInfoIt->second->readyForDelete = true;
861 }
862
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000863 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000864 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
865
866 if (cnameInfoIt != _receivedCnameMap.end()) {
867 delete cnameInfoIt->second;
868 _receivedCnameMap.erase(cnameInfoIt);
869 }
870 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000871}
872
873// no need for critsect we have _criticalSectionRTCPReceiver
874void
875RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
876 RTCPPacketInformation& rtcpPacketInformation)
877{
878 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
879
880 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
881
882 if(rtcpPacket.XRVOIPMetricItem.SSRC == _SSRC)
883 {
884 // Store VoIP metrics block if it's about me
885 // from OriginatorSSRC do we filter it?
886 // rtcpPacket.XR.OriginatorSSRC;
887
888 RTCPVoIPMetric receivedVoIPMetrics;
889 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
890 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
891 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
892 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
893 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
894 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
895 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
896 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
897 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
898 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
899 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
900 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
901 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
902 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
903 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
904 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
905 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
906 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
907 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
908 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
909
910 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
911
912 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
913 }
914 rtcpParser.Iterate();
915}
916
917// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000918void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
919 RTCPPacketInformation& rtcpPacketInformation) {
920 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
921 if (_SSRC == rtcpPacket.PLI.MediaSSRC) {
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000922 TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
923
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000924 // Received a signal that we need to send a new key frame.
925 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
926 }
927 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000928}
929
930// no need for critsect we have _criticalSectionRTCPReceiver
931void
932RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
933 RTCPPacketInformation& rtcpPacketInformation)
934{
935 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
936
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000937 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000938 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
939 if (ptrReceiveInfo == NULL)
940 {
941 // This remote SSRC must be saved before.
942 rtcpParser.Iterate();
943 return;
944 }
945 if(rtcpPacket.TMMBR.MediaSSRC)
946 {
947 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
948 // in relay mode this is a valid number
949 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
950 }
951
952 // Use packet length to calc max number of TMMBR blocks
953 // each TMMBR block is 8 bytes
954 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
955
956 // sanity
957 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
958 {
959 assert(false);
960 rtcpParser.Iterate();
961 return;
962 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000963 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +0000964
965 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
966 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
967 {
968 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
969 pktType = rtcpParser.Iterate();
970 }
971}
972
973// no need for critsect we have _criticalSectionRTCPReceiver
974void
975RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
976 const RTCPUtility::RTCPPacket& rtcpPacket,
977 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000978 const uint32_t senderSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000979{
980 if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
981 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
982 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000983 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000984 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +0000985 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
986 }
987}
988
989// no need for critsect we have _criticalSectionRTCPReceiver
990void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000991RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
992 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +0000993{
994 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
995 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
996 if (ptrReceiveInfo == NULL)
997 {
998 // This remote SSRC must be saved before.
999 rtcpParser.Iterate();
1000 return;
1001 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +00001002 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +00001003 // Use packet length to calc max number of TMMBN blocks
1004 // each TMMBN block is 8 bytes
1005 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1006
1007 // sanity
1008 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1009 {
1010 assert(false);
1011 rtcpParser.Iterate();
1012 return;
1013 }
1014
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001015 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001016
1017 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1018 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1019 {
1020 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1021 pktType = rtcpParser.Iterate();
1022 }
1023}
1024
1025// no need for critsect we have _criticalSectionRTCPReceiver
1026void
1027RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1028 RTCPPacketInformation& rtcpPacketInformation)
1029{
1030 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1031 rtcpParser.Iterate();
1032}
1033
1034// no need for critsect we have _criticalSectionRTCPReceiver
1035void
1036RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1037 const RTCPUtility::RTCPPacket& rtcpPacket)
1038{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001039 receiveInfo.TmmbnBoundingSet.AddEntry(
1040 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1041 rtcpPacket.TMMBNItem.MeasuredOverhead,
1042 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001043}
1044
1045// no need for critsect we have _criticalSectionRTCPReceiver
1046void
1047RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1048 RTCPPacketInformation& rtcpPacketInformation)
1049{
1050 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001051 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1052 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1053 {
1054 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1055 pktType = rtcpParser.Iterate();
1056 }
1057}
1058
1059// no need for critsect we have _criticalSectionRTCPReceiver
1060void
1061RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1062 RTCPPacketInformation& rtcpPacketInformation)
1063{
1064 // in theory there could be multiple slices lost
1065 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1066 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1067}
1068
1069void
1070RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1071 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1072{
1073 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001074 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1075 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1076 {
1077 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1078 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1079 {
1080 // to us unknown
1081 // continue
1082 rtcpParser.Iterate();
1083 return;
1084 }
1085 rtcpPacketInformation.rpsiPictureId = 0;
1086
1087 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001088 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1089 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001090 {
1091 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1092 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1093 }
1094 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1095 }
1096}
1097
1098// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001099void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1100 RTCPPacketInformation& rtcpPacketInformation) {
1101 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1102 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1103 pktType = rtcpParser.Iterate();
1104 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1105 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1106 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001107 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001108 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001109}
1110
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001111// no need for critsect we have _criticalSectionRTCPReceiver
1112void
1113RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1114 RTCPPacketInformation& rtcpPacketInformation)
1115{
1116 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1117
1118 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1119 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1120 {
1121 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1122 pktType = rtcpParser.Iterate();
1123 }
1124}
1125
1126void
1127RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1128 RTCPPacketInformation& rtcpPacketInformation)
1129{
1130 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1131 rtcpPacketInformation.interArrivalJitter =
1132 rtcpPacket.ExtendedJitterReportItem.Jitter;
1133}
1134
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001135void RTCPReceiver::HandleREMBItem(
1136 RTCPUtility::RTCPParserV2& rtcpParser,
1137 RTCPPacketInformation& rtcpPacketInformation) {
1138 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1139 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1140 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1141 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001142}
1143
1144// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001145void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1146 RTCPPacketInformation& rtcpPacketInformation) {
1147 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1148 RTCPReceiveInformation* ptrReceiveInfo =
1149 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001150
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001151 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1152 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1153 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1154 pktType = rtcpParser.Iterate();
1155 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001156}
1157
1158// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001159void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1160 const RTCPUtility::RTCPPacket& rtcpPacket,
1161 RTCPPacketInformation& rtcpPacketInformation) {
1162 // Is it our sender that is requested to generate a new keyframe
1163 if (_SSRC != rtcpPacket.FIRItem.SSRC) {
1164 return;
1165 }
1166 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1167 // we don't know who this originate from
1168 if (receiveInfo) {
1169 // check if we have reported this FIRSequenceNumber before
1170 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1171 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001172 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001173 // sanity; don't go crazy with the callbacks
1174 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1175 receiveInfo->lastFIRRequest = now;
1176 receiveInfo->lastFIRSequenceNumber =
1177 rtcpPacket.FIRItem.CommandSequenceNumber;
1178 // received signal that we need to send a new key frame
1179 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1180 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001181 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001182 } else {
1183 // received signal that we need to send a new key frame
1184 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1185 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001186}
1187
1188void
1189RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1190 RTCPPacketInformation& rtcpPacketInformation)
1191{
1192 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1193
1194 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1195 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1196 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1197
1198 rtcpParser.Iterate();
1199}
1200
1201void
1202RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1203 RTCPPacketInformation& rtcpPacketInformation)
1204{
1205 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1206
1207 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1208
1209 rtcpParser.Iterate();
1210}
1211
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001212int32_t RTCPReceiver::UpdateTMMBR() {
1213 int32_t numBoundingSet = 0;
1214 uint32_t bitrate = 0;
1215 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001216
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001217 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001218 if (size > 0) {
1219 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1220 // Get candidate set from receiver.
1221 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1222 } else {
1223 // Candidate set empty.
1224 VerifyAndAllocateCandidateSet(0); // resets candidate set
1225 }
1226 // Find bounding set
1227 TMMBRSet* boundingSet = NULL;
1228 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1229 if (numBoundingSet == -1) {
1230 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1231 "Failed to find TMMBR bounding set.");
1232 return -1;
1233 }
1234 // Set bounding set
1235 // Inform remote clients about the new bandwidth
1236 // inform the remote client
1237 _rtpRtcp.SetTMMBN(boundingSet);
1238
1239 // might trigger a TMMBN
1240 if (numBoundingSet == 0) {
1241 // owner of max bitrate request has timed out
1242 // empty bounding set has been sent
1243 return 0;
1244 }
1245 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001246 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001247 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001248 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1249 if (_cbRtcpBandwidthObserver) {
1250 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1251 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1252 "Set TMMBR request:%d kbps", bitrate);
1253 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001254 }
1255 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001256}
1257
1258// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001259void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001260 RTCPPacketInformation& rtcpPacketInformation) {
1261 // Process TMMBR and REMB first to avoid multiple callbacks
1262 // to OnNetworkChanged.
1263 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1264 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1265 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001266
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001267 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1268 UpdateTMMBR();
1269 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001270 unsigned int local_ssrc = 0;
1271 {
1272 // We don't want to hold this critsect when triggering the callbacks below.
1273 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1274 local_ssrc = _SSRC;
1275 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001276 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1277 _rtpRtcp.OnRequestSendReport();
1278 }
1279 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001280 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001281 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1282 "SIG [RTCP] Incoming NACK length:%d",
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001283 rtcpPacketInformation.nackSequenceNumbers.size());
1284 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001285 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001286 }
1287 {
1288 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001289
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001290 // We need feedback that we have received a report block(s) so that we
1291 // can generate a new packet in a conference relay scenario, one received
1292 // report can generate several RTCP packets, based on number relayed/mixed
1293 // a send report block should go out to all receivers.
1294 if (_cbRtcpIntraFrameObserver) {
1295 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1296 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1297 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1298 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1299 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1300 rtcpPacketInformation.remoteSSRC);
1301 } else {
1302 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1303 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1304 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001305 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001306 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001307 }
1308 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1309 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001310 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001311 }
1312 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1313 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001314 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001315 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001316 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001317 if (_cbRtcpBandwidthObserver) {
1318 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1319 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1320 "SIG [RTCP] Incoming REMB:%d",
1321 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1322 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1323 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1324 }
1325 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1326 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
1327 rtcpPacketInformation.reportBlock) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001328 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001329 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
1330 rtcpPacketInformation.remoteSSRC,
1331 rtcpPacketInformation.fractionLost,
1332 rtcpPacketInformation.roundTripTime,
1333 rtcpPacketInformation.lastReceivedExtendedHighSeqNum,
1334 now);
1335 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001336 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001337 if(_cbRtcpFeedback) {
solenberg@webrtc.org91811e22013-06-25 20:36:14 +00001338 if(!(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001339 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1340 rtcpPacketInformation.remoteSSRC);
1341 }
1342 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1343 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1344 rtcpPacketInformation.VoIPMetric);
1345 }
1346 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1347 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1348 rtcpPacketInformation.applicationSubType,
1349 rtcpPacketInformation.applicationName,
1350 rtcpPacketInformation.applicationLength,
1351 rtcpPacketInformation.applicationData);
1352 }
1353 }
1354 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001355}
1356
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001357int32_t RTCPReceiver::CNAME(const uint32_t remoteSSRC,
1358 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001359 assert(cName);
1360
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001361 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1362 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001363 if (cnameInfo == NULL) {
1364 return -1;
1365 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001366 cName[RTCP_CNAME_SIZE - 1] = 0;
1367 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1368 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001369}
1370
1371// no callbacks allowed inside this function
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001372int32_t RTCPReceiver::TMMBRReceived(const uint32_t size,
1373 const uint32_t accNumCandidates,
1374 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001375 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001376
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001377 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001378 receiveInfoIt = _receivedInfoMap.begin();
1379 if (receiveInfoIt == _receivedInfoMap.end()) {
1380 return -1;
1381 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001382 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001383 if (candidateSet) {
1384 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1385 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1386 if (receiveInfo == NULL) {
1387 return 0;
1388 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001389 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001390 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001391 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001392 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001393 num++;
1394 }
1395 }
1396 receiveInfoIt++;
1397 }
1398 } else {
1399 while (receiveInfoIt != _receivedInfoMap.end()) {
1400 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1401 if(receiveInfo == NULL) {
1402 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1403 "%s failed to get RTCPReceiveInformation",
1404 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001405 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001406 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001407 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001408 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001409 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001410 }
1411 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001412}
1413
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001414} // namespace webrtc