blob: 9ab1fb69b2d22d3d5e1c8162cce8a5926bca8620 [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()),
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000049 main_ssrc_(0),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000050 _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
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000159void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
160 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000161 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);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000164 old_ssrc = main_ssrc_;
165 main_ssrc_ = main_ssrc;
166 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000167 }
168 {
169 CriticalSectionScoped lock(_criticalSectionFeedbacks);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000170 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
171 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000172 }
173 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000174}
175
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000176int32_t RTCPReceiver::ResetRTT(const uint32_t remoteSSRC) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000177 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
178 RTCPReportBlockInformation* reportBlock =
179 GetReportBlockInformation(remoteSSRC);
180 if (reportBlock == NULL) {
181 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
182 "\tfailed to GetReportBlockInformation(%u)", remoteSSRC);
183 return -1;
184 }
185 reportBlock->RTT = 0;
186 reportBlock->avgRTT = 0;
187 reportBlock->minRTT = 0;
188 reportBlock->maxRTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000189 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000190}
191
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000192int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000193 uint16_t* RTT,
194 uint16_t* avgRTT,
195 uint16_t* minRTT,
196 uint16_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000197 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000198
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000199 RTCPReportBlockInformation* reportBlock =
200 GetReportBlockInformation(remoteSSRC);
201
202 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000203 return -1;
204 }
205 if (RTT) {
206 *RTT = reportBlock->RTT;
207 }
208 if (avgRTT) {
209 *avgRTT = reportBlock->avgRTT;
210 }
211 if (minRTT) {
212 *minRTT = reportBlock->minRTT;
213 }
214 if (maxRTT) {
215 *maxRTT = reportBlock->maxRTT;
216 }
217 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000218}
219
stefan@webrtc.org8ca8a712013-04-23 16:48:32 +0000220uint16_t RTCPReceiver::RTT() const {
221 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
222 if (!_receivedReportBlockMap.empty()) {
223 return 0;
224 }
225 return _rtt;
226}
227
228int RTCPReceiver::SetRTT(uint16_t rtt) {
229 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
230 if (!_receivedReportBlockMap.empty()) {
231 return -1;
232 }
233 _rtt = rtt;
234 return 0;
235}
236
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000237int32_t
238RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs,
239 uint32_t *ReceivedNTPfrac,
240 uint32_t *RTCPArrivalTimeSecs,
241 uint32_t *RTCPArrivalTimeFrac,
242 uint32_t *rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000243{
244 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
245 if(ReceivedNTPsecs)
246 {
247 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
248 }
249 if(ReceivedNTPfrac)
250 {
251 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
252 }
253 if(RTCPArrivalTimeFrac)
254 {
255 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
256 }
257 if(RTCPArrivalTimeSecs)
258 {
259 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
260 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000261 if (rtcp_timestamp) {
262 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
263 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000264 return 0;
265}
266
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000267int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000268RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
269{
270 if(senderInfo == NULL)
271 {
272 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
273 return -1;
274 }
275 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
276 if(_lastReceivedSRNTPsecs == 0)
277 {
278 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
279 return -1;
280 }
281 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
282 return 0;
283}
284
285// statistics
286// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000287int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000288 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000289 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000290 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
291
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000292 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000293 _receivedReportBlockMap.begin();
294
295 while (it != _receivedReportBlockMap.end()) {
296 receiveBlocks->push_back(it->second->remoteReceiveBlock);
297 it++;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000298 }
299 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000300}
301
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000302int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000303RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
304 RTCPUtility::RTCPParserV2* rtcpParser)
305{
306 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
307
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000308 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000309
310 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
311 while (pktType != RTCPUtility::kRtcpNotValidCode)
312 {
313 // Each "case" is responsible for iterate the parser to the
314 // next top level packet.
315 switch (pktType)
316 {
317 case RTCPUtility::kRtcpSrCode:
318 case RTCPUtility::kRtcpRrCode:
319 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
320 break;
321 case RTCPUtility::kRtcpSdesCode:
322 HandleSDES(*rtcpParser);
323 break;
324 case RTCPUtility::kRtcpXrVoipMetricCode:
325 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
326 break;
327 case RTCPUtility::kRtcpByeCode:
328 HandleBYE(*rtcpParser);
329 break;
330 case RTCPUtility::kRtcpRtpfbNackCode:
331 HandleNACK(*rtcpParser, rtcpPacketInformation);
332 break;
333 case RTCPUtility::kRtcpRtpfbTmmbrCode:
334 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
335 break;
336 case RTCPUtility::kRtcpRtpfbTmmbnCode:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000337 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000338 break;
339 case RTCPUtility::kRtcpRtpfbSrReqCode:
340 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
341 break;
342 case RTCPUtility::kRtcpPsfbPliCode:
343 HandlePLI(*rtcpParser, rtcpPacketInformation);
344 break;
345 case RTCPUtility::kRtcpPsfbSliCode:
346 HandleSLI(*rtcpParser, rtcpPacketInformation);
347 break;
348 case RTCPUtility::kRtcpPsfbRpsiCode:
349 HandleRPSI(*rtcpParser, rtcpPacketInformation);
350 break;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000351 case RTCPUtility::kRtcpExtendedIjCode:
352 HandleIJ(*rtcpParser, rtcpPacketInformation);
353 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000354 case RTCPUtility::kRtcpPsfbFirCode:
355 HandleFIR(*rtcpParser, rtcpPacketInformation);
356 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000357 case RTCPUtility::kRtcpPsfbAppCode:
358 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
359 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000360 case RTCPUtility::kRtcpAppCode:
361 // generic application messages
362 HandleAPP(*rtcpParser, rtcpPacketInformation);
363 break;
364 case RTCPUtility::kRtcpAppItemCode:
365 // generic application messages
366 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
367 break;
368 default:
369 rtcpParser->Iterate();
370 break;
371 }
372 pktType = rtcpParser->PacketType();
373 }
374 return 0;
375}
376
377// no need for critsect we have _criticalSectionRTCPReceiver
378void
379RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
380 RTCPPacketInformation& rtcpPacketInformation)
381{
382 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
383 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
384
385 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
386
387 // SR.SenderSSRC
388 // The synchronization source identifier for the originator of this SR packet
389
390 // rtcpPacket.RR.SenderSSRC
391 // The source of the packet sender, same as of SR? or is this a CE?
392
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000393 const uint32_t remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
394 const uint8_t numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
niklase@google.com470e71d2011-07-07 08:21:25 +0000395
396 rtcpPacketInformation.remoteSSRC = remoteSSRC;
397
398 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
399 if (!ptrReceiveInfo)
400 {
401 rtcpParser.Iterate();
402 return;
403 }
404
405 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
406 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000407 TRACE_EVENT_INSTANT2("webrtc_rtp", "SR",
408 "remote_ssrc", remoteSSRC,
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000409 "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000410
niklase@google.com470e71d2011-07-07 08:21:25 +0000411 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
412 {
413 // only signal that we have received a SR when we accept one
414 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
415
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000416 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
417 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
418 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
419
niklase@google.com470e71d2011-07-07 08:21:25 +0000420 // We will only store the send report from one source, but
421 // we will store all the receive block
422
423 // Save the NTP time of this report
424 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
425 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
426 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
427 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
428 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
429
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000430 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000431 }
432 else
433 {
434 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
435 }
436 } else
437 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000438 TRACE_EVENT_INSTANT2("webrtc_rtp", "RR",
439 "remote_ssrc", remoteSSRC,
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000440 "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000441
442 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
443 }
444 UpdateReceiveInformation(*ptrReceiveInfo);
445
446 rtcpPacketType = rtcpParser.Iterate();
447
448 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
449 {
450 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
451 rtcpPacketType = rtcpParser.Iterate();
452 }
453}
454
455// no need for critsect we have _criticalSectionRTCPReceiver
456void
457RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
458 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000459 const uint32_t remoteSSRC,
460 const uint8_t numberOfReportBlocks) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000461 // This will be called once per report block in the RTCP packet.
462 // We filter out all report blocks that are not for us.
463 // Each packet has max 31 RR blocks.
464 //
465 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000466
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000467 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
468 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000469
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000470 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000471 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
472 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000473 // This block is not for us ignore it.
474 return;
475 }
476
477 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
478 // _criticalSectionRTCPReceiver.
479 _criticalSectionRTCPReceiver->Leave();
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000480 uint32_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000481 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
482 _criticalSectionRTCPReceiver->Enter();
483
484 RTCPReportBlockInformation* reportBlock =
485 CreateReportBlockInformation(remoteSSRC);
486 if (reportBlock == NULL) {
487 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
488 "\tfailed to CreateReportBlockInformation(%u)", remoteSSRC);
489 return;
490 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000491
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000492 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000493 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
494 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
495 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
496 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
497 reportBlock->remoteReceiveBlock.cumulativeLost =
498 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000499 if (rb.ExtendedHighestSequenceNumber >
500 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
501 // We have successfully delivered new RTP packets to the remote side after
502 // the last RR was sent from the remote side.
503 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000504 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000505 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
506 rb.ExtendedHighestSequenceNumber;
507 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
508 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
509 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
510
511 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
512 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
513 }
514
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000515 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000516 rtcpPacket.ReportBlockItem.DelayLastSR;
517
518 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000519 uint32_t lastReceivedRRNTPsecs = 0;
520 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000521
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000522 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000523
524 // time when we received this in MS
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000525 uint32_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
526 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000527
528 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000529 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000530 d /= 65536;
531 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
532
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000533 int32_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000534
535 if (sendTimeMS > 0) {
536 RTT = receiveTimeMS - d - sendTimeMS;
537 if (RTT <= 0) {
538 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000539 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000540 if (RTT > reportBlock->maxRTT) {
541 // store max RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000542 reportBlock->maxRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000543 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000544 if (reportBlock->minRTT == 0) {
545 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000546 reportBlock->minRTT = (uint16_t) RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000547 } else if (RTT < reportBlock->minRTT) {
548 // Store min RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000549 reportBlock->minRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000550 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000551 // store last RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000552 reportBlock->RTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000553
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000554 // store average RTT
555 if (reportBlock->numAverageCalcs != 0) {
556 float ac = static_cast<float> (reportBlock->numAverageCalcs);
557 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
558 + ((1 / (ac + 1)) * RTT);
559 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
560 } else {
561 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000562 reportBlock->avgRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000563 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000564 reportBlock->numAverageCalcs++;
565 }
566
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000567 TRACE_COUNTER_ID1("webrtc_rtp", "RR_RTT", rb.SSRC, RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000568
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000569 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000570}
571
572RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000573RTCPReceiver::CreateReportBlockInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000574 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000575
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000576 std::map<uint32_t, RTCPReportBlockInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000577 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000578
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000579 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
580 if (it != _receivedReportBlockMap.end()) {
581 ptrReportBlockInfo = it->second;
582 } else {
583 ptrReportBlockInfo = new RTCPReportBlockInformation;
584 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
585 }
586 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000587}
588
589RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000590RTCPReceiver::GetReportBlockInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000591 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000592
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000593 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000594 _receivedReportBlockMap.find(remoteSSRC);
595
596 if (it == _receivedReportBlockMap.end()) {
597 return NULL;
598 }
599 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000600}
601
602RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000603RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000604 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000605
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000606 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000607 _receivedCnameMap.find(remoteSSRC);
608
609 if (it != _receivedCnameMap.end()) {
610 return it->second;
611 }
612 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000613 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000614 _receivedCnameMap[remoteSSRC] = cnameInfo;
615 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000616}
617
618RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000619RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000620 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000621
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000622 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000623 _receivedCnameMap.find(remoteSSRC);
624
625 if (it == _receivedCnameMap.end()) {
626 return NULL;
627 }
628 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000629}
630
631RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000632RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000633 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000634
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000635 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000636 _receivedInfoMap.find(remoteSSRC);
637
638 if (it != _receivedInfoMap.end()) {
639 return it->second;
640 }
641 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
642 _receivedInfoMap[remoteSSRC] = receiveInfo;
643 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000644}
645
646RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000647RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000648 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000649
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000650 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000651 _receivedInfoMap.find(remoteSSRC);
652 if (it == _receivedInfoMap.end()) {
653 return NULL;
654 }
655 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000656}
657
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000658void RTCPReceiver::UpdateReceiveInformation(
659 RTCPReceiveInformation& receiveInformation) {
660 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000661 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000662}
663
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000664bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
665 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
666 if (_lastReceivedRrMs == 0)
667 return false;
668
669 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000670 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000671 // Reset the timer to only trigger one log.
672 _lastReceivedRrMs = 0;
673 return true;
674 }
675 return false;
676}
677
678bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
679 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
680 if (_lastIncreasedSequenceNumberMs == 0)
681 return false;
682
683 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000684 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000685 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000686 // Reset the timer to only trigger one log.
687 _lastIncreasedSequenceNumberMs = 0;
688 return true;
689 }
690 return false;
691}
692
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000693bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
694 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000695
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000696 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000697 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000698
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000699 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000700 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000701
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000702 while (receiveInfoIt != _receivedInfoMap.end()) {
703 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
704 if (receiveInfo == NULL) {
705 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000706 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000707 // time since last received rtcp packet
708 // when we dont have a lastTimeReceived and the object is marked
709 // readyForDelete it's removed from the map
710 if (receiveInfo->lastTimeReceived) {
711 /// use audio define since we don't know what interval the remote peer is
712 // using
713 if ((timeNow - receiveInfo->lastTimeReceived) >
714 5 * RTCP_INTERVAL_AUDIO_MS) {
715 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000716 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000717 // prevent that we call this over and over again
718 receiveInfo->lastTimeReceived = 0;
719 // send new TMMBN to all channels using the default codec
720 updateBoundingSet = true;
721 }
722 receiveInfoIt++;
723 } else if (receiveInfo->readyForDelete) {
724 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000725 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000726 receiveInfoItemToBeErased = receiveInfoIt;
727 receiveInfoIt++;
728 delete receiveInfoItemToBeErased->second;
729 _receivedInfoMap.erase(receiveInfoItemToBeErased);
730 } else {
731 receiveInfoIt++;
732 }
733 }
734 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000735}
736
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000737int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000738 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000739
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000740 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000741 _receivedInfoMap.find(_remoteSSRC);
742
743 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000744 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000745 }
746 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
747 if (receiveInfo == NULL) {
748 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
749 "%s failed to get RTCPReceiveInformation",
750 __FUNCTION__);
751 return -1;
752 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000753 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000754 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000755 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000756 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000757 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000758 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000759 // owner of bounding set
760 tmmbrOwner = true;
761 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000762 boundingSetRec->SetEntry(i,
763 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
764 receiveInfo->TmmbnBoundingSet.PacketOH(i),
765 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000766 }
767 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000768 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000769}
770
771// no need for critsect we have _criticalSectionRTCPReceiver
772void
773RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
774{
775 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
776 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
777 {
778 HandleSDESChunk(rtcpParser);
779 pktType = rtcpParser.Iterate();
780 }
781}
782
783// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000784void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
785 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
786 RTCPCnameInformation* cnameInfo =
787 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
788 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000789
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000790 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
791 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000792}
793
794// no need for critsect we have _criticalSectionRTCPReceiver
795void
796RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
797 RTCPPacketInformation& rtcpPacketInformation)
798{
799 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000800 if (main_ssrc_ != rtcpPacket.NACK.MediaSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000801 {
802 // Not to us.
803 rtcpParser.Iterate();
804 return;
805 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000806 rtcpPacketInformation.ResetNACKPacketIdArray();
807
808 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
809 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
810 {
811 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
812 pktType = rtcpParser.Iterate();
813 }
814}
815
816// no need for critsect we have _criticalSectionRTCPReceiver
817void
818RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
819 RTCPPacketInformation& rtcpPacketInformation)
820{
821 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
822
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000823 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
niklase@google.com470e71d2011-07-07 08:21:25 +0000824 if(bitMask)
825 {
826 for(int i=1; i <= 16; ++i)
827 {
828 if(bitMask & 0x01)
829 {
830 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
831 }
832 bitMask = bitMask >>1;
833 }
834 }
835
836 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
837}
838
839// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000840void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
841 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000842
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000843 // clear our lists
844 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000845 std::map<uint32_t, RTCPReportBlockInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000846 reportBlockInfoIt = _receivedReportBlockMap.find(
847 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000848
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000849 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
850 delete reportBlockInfoIt->second;
851 _receivedReportBlockMap.erase(reportBlockInfoIt);
852 }
853 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000854 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000855 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000856
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000857 if (receiveInfoIt != _receivedInfoMap.end()) {
858 receiveInfoIt->second->readyForDelete = true;
859 }
860
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000861 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000862 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
863
864 if (cnameInfoIt != _receivedCnameMap.end()) {
865 delete cnameInfoIt->second;
866 _receivedCnameMap.erase(cnameInfoIt);
867 }
868 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000869}
870
871// no need for critsect we have _criticalSectionRTCPReceiver
872void
873RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
874 RTCPPacketInformation& rtcpPacketInformation)
875{
876 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
877
878 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
879
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000880 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000881 {
882 // Store VoIP metrics block if it's about me
883 // from OriginatorSSRC do we filter it?
884 // rtcpPacket.XR.OriginatorSSRC;
885
886 RTCPVoIPMetric receivedVoIPMetrics;
887 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
888 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
889 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
890 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
891 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
892 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
893 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
894 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
895 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
896 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
897 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
898 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
899 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
900 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
901 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
902 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
903 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
904 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
905 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
906 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
907
908 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
909
910 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
911 }
912 rtcpParser.Iterate();
913}
914
915// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000916void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
917 RTCPPacketInformation& rtcpPacketInformation) {
918 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000919 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000920 TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
921
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000922 // Received a signal that we need to send a new key frame.
923 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
924 }
925 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000926}
927
928// no need for critsect we have _criticalSectionRTCPReceiver
929void
930RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
931 RTCPPacketInformation& rtcpPacketInformation)
932{
933 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
934
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000935 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000936 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
937 if (ptrReceiveInfo == NULL)
938 {
939 // This remote SSRC must be saved before.
940 rtcpParser.Iterate();
941 return;
942 }
943 if(rtcpPacket.TMMBR.MediaSSRC)
944 {
945 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
946 // in relay mode this is a valid number
947 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
948 }
949
950 // Use packet length to calc max number of TMMBR blocks
951 // each TMMBR block is 8 bytes
952 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
953
954 // sanity
955 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
956 {
957 assert(false);
958 rtcpParser.Iterate();
959 return;
960 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000961 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +0000962
963 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
964 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
965 {
966 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
967 pktType = rtcpParser.Iterate();
968 }
969}
970
971// no need for critsect we have _criticalSectionRTCPReceiver
972void
973RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
974 const RTCPUtility::RTCPPacket& rtcpPacket,
975 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000976 const uint32_t senderSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000977{
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000978 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
niklase@google.com470e71d2011-07-07 08:21:25 +0000979 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
980 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000981 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000982 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +0000983 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
984 }
985}
986
987// no need for critsect we have _criticalSectionRTCPReceiver
988void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000989RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
990 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +0000991{
992 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
993 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
994 if (ptrReceiveInfo == NULL)
995 {
996 // This remote SSRC must be saved before.
997 rtcpParser.Iterate();
998 return;
999 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +00001000 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +00001001 // Use packet length to calc max number of TMMBN blocks
1002 // each TMMBN block is 8 bytes
1003 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1004
1005 // sanity
1006 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1007 {
1008 assert(false);
1009 rtcpParser.Iterate();
1010 return;
1011 }
1012
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001013 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001014
1015 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1016 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1017 {
1018 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1019 pktType = rtcpParser.Iterate();
1020 }
1021}
1022
1023// no need for critsect we have _criticalSectionRTCPReceiver
1024void
1025RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1026 RTCPPacketInformation& rtcpPacketInformation)
1027{
1028 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1029 rtcpParser.Iterate();
1030}
1031
1032// no need for critsect we have _criticalSectionRTCPReceiver
1033void
1034RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1035 const RTCPUtility::RTCPPacket& rtcpPacket)
1036{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001037 receiveInfo.TmmbnBoundingSet.AddEntry(
1038 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1039 rtcpPacket.TMMBNItem.MeasuredOverhead,
1040 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001041}
1042
1043// no need for critsect we have _criticalSectionRTCPReceiver
1044void
1045RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1046 RTCPPacketInformation& rtcpPacketInformation)
1047{
1048 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001049 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1050 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1051 {
1052 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1053 pktType = rtcpParser.Iterate();
1054 }
1055}
1056
1057// no need for critsect we have _criticalSectionRTCPReceiver
1058void
1059RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1060 RTCPPacketInformation& rtcpPacketInformation)
1061{
1062 // in theory there could be multiple slices lost
1063 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1064 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1065}
1066
1067void
1068RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1069 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1070{
1071 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001072 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1073 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1074 {
1075 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1076 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1077 {
1078 // to us unknown
1079 // continue
1080 rtcpParser.Iterate();
1081 return;
1082 }
1083 rtcpPacketInformation.rpsiPictureId = 0;
1084
1085 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001086 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1087 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001088 {
1089 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1090 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1091 }
1092 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1093 }
1094}
1095
1096// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001097void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1098 RTCPPacketInformation& rtcpPacketInformation) {
1099 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1100 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1101 pktType = rtcpParser.Iterate();
1102 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1103 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1104 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001105 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001106 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001107}
1108
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001109// no need for critsect we have _criticalSectionRTCPReceiver
1110void
1111RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1112 RTCPPacketInformation& rtcpPacketInformation)
1113{
1114 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1115
1116 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1117 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1118 {
1119 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1120 pktType = rtcpParser.Iterate();
1121 }
1122}
1123
1124void
1125RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1126 RTCPPacketInformation& rtcpPacketInformation)
1127{
1128 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1129 rtcpPacketInformation.interArrivalJitter =
1130 rtcpPacket.ExtendedJitterReportItem.Jitter;
1131}
1132
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001133void RTCPReceiver::HandleREMBItem(
1134 RTCPUtility::RTCPParserV2& rtcpParser,
1135 RTCPPacketInformation& rtcpPacketInformation) {
1136 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1137 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1138 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1139 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001140}
1141
1142// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001143void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1144 RTCPPacketInformation& rtcpPacketInformation) {
1145 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1146 RTCPReceiveInformation* ptrReceiveInfo =
1147 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001148
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001149 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1150 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1151 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1152 pktType = rtcpParser.Iterate();
1153 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001154}
1155
1156// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001157void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1158 const RTCPUtility::RTCPPacket& rtcpPacket,
1159 RTCPPacketInformation& rtcpPacketInformation) {
1160 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001161 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001162 return;
1163 }
1164 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1165 // we don't know who this originate from
1166 if (receiveInfo) {
1167 // check if we have reported this FIRSequenceNumber before
1168 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1169 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001170 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001171 // sanity; don't go crazy with the callbacks
1172 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1173 receiveInfo->lastFIRRequest = now;
1174 receiveInfo->lastFIRSequenceNumber =
1175 rtcpPacket.FIRItem.CommandSequenceNumber;
1176 // received signal that we need to send a new key frame
1177 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1178 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001179 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001180 } else {
1181 // received signal that we need to send a new key frame
1182 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1183 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001184}
1185
1186void
1187RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1188 RTCPPacketInformation& rtcpPacketInformation)
1189{
1190 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1191
1192 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1193 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1194 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1195
1196 rtcpParser.Iterate();
1197}
1198
1199void
1200RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1201 RTCPPacketInformation& rtcpPacketInformation)
1202{
1203 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1204
1205 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1206
1207 rtcpParser.Iterate();
1208}
1209
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001210int32_t RTCPReceiver::UpdateTMMBR() {
1211 int32_t numBoundingSet = 0;
1212 uint32_t bitrate = 0;
1213 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001214
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001215 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001216 if (size > 0) {
1217 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1218 // Get candidate set from receiver.
1219 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1220 } else {
1221 // Candidate set empty.
1222 VerifyAndAllocateCandidateSet(0); // resets candidate set
1223 }
1224 // Find bounding set
1225 TMMBRSet* boundingSet = NULL;
1226 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1227 if (numBoundingSet == -1) {
1228 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1229 "Failed to find TMMBR bounding set.");
1230 return -1;
1231 }
1232 // Set bounding set
1233 // Inform remote clients about the new bandwidth
1234 // inform the remote client
1235 _rtpRtcp.SetTMMBN(boundingSet);
1236
1237 // might trigger a TMMBN
1238 if (numBoundingSet == 0) {
1239 // owner of max bitrate request has timed out
1240 // empty bounding set has been sent
1241 return 0;
1242 }
1243 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001244 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001245 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001246 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1247 if (_cbRtcpBandwidthObserver) {
1248 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1249 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1250 "Set TMMBR request:%d kbps", bitrate);
1251 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001252 }
1253 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001254}
1255
1256// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001257void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001258 RTCPPacketInformation& rtcpPacketInformation) {
1259 // Process TMMBR and REMB first to avoid multiple callbacks
1260 // to OnNetworkChanged.
1261 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1262 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1263 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001264
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001265 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1266 UpdateTMMBR();
1267 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001268 unsigned int local_ssrc = 0;
1269 {
1270 // We don't want to hold this critsect when triggering the callbacks below.
1271 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001272 local_ssrc = main_ssrc_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001273 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001274 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1275 _rtpRtcp.OnRequestSendReport();
1276 }
1277 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001278 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001279 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1280 "SIG [RTCP] Incoming NACK length:%d",
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001281 rtcpPacketInformation.nackSequenceNumbers.size());
1282 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001283 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001284 }
1285 {
1286 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001287
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001288 // We need feedback that we have received a report block(s) so that we
1289 // can generate a new packet in a conference relay scenario, one received
1290 // report can generate several RTCP packets, based on number relayed/mixed
1291 // a send report block should go out to all receivers.
1292 if (_cbRtcpIntraFrameObserver) {
1293 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1294 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1295 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1296 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1297 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1298 rtcpPacketInformation.remoteSSRC);
1299 } else {
1300 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1301 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1302 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001303 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001304 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001305 }
1306 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1307 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001308 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001309 }
1310 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1311 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001312 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001313 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001314 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001315 if (_cbRtcpBandwidthObserver) {
1316 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1317 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1318 "SIG [RTCP] Incoming REMB:%d",
1319 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1320 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1321 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1322 }
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001323 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1324 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001325 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001326 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001327 rtcpPacketInformation.report_blocks,
1328 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001329 now);
1330 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001331 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001332 if(_cbRtcpFeedback) {
solenberg@webrtc.org91811e22013-06-25 20:36:14 +00001333 if(!(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001334 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1335 rtcpPacketInformation.remoteSSRC);
1336 }
1337 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1338 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1339 rtcpPacketInformation.VoIPMetric);
1340 }
1341 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1342 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1343 rtcpPacketInformation.applicationSubType,
1344 rtcpPacketInformation.applicationName,
1345 rtcpPacketInformation.applicationLength,
1346 rtcpPacketInformation.applicationData);
1347 }
1348 }
1349 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001350}
1351
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001352int32_t RTCPReceiver::CNAME(const uint32_t remoteSSRC,
1353 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001354 assert(cName);
1355
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001356 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1357 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001358 if (cnameInfo == NULL) {
1359 return -1;
1360 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001361 cName[RTCP_CNAME_SIZE - 1] = 0;
1362 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1363 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001364}
1365
1366// no callbacks allowed inside this function
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001367int32_t RTCPReceiver::TMMBRReceived(const uint32_t size,
1368 const uint32_t accNumCandidates,
1369 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001370 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001371
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001372 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001373 receiveInfoIt = _receivedInfoMap.begin();
1374 if (receiveInfoIt == _receivedInfoMap.end()) {
1375 return -1;
1376 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001377 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001378 if (candidateSet) {
1379 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1380 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1381 if (receiveInfo == NULL) {
1382 return 0;
1383 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001384 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001385 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001386 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001387 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001388 num++;
1389 }
1390 }
1391 receiveInfoIt++;
1392 }
1393 } else {
1394 while (receiveInfoIt != _receivedInfoMap.end()) {
1395 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1396 if(receiveInfo == NULL) {
1397 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1398 "%s failed to get RTCPReceiveInformation",
1399 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001400 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001401 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001402 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001403 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001404 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001405 }
1406 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001407}
1408
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001409} // namespace webrtc