blob: fb7adf6b34b41566ae97958ee45877afe0742716 [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
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000016#include <algorithm>
17
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000018#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
19#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
20#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
21#include "webrtc/system_wrappers/interface/trace.h"
22#include "webrtc/system_wrappers/interface/trace_event.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000023
niklase@google.com470e71d2011-07-07 08:21:25 +000024namespace webrtc {
25using namespace RTCPUtility;
26using namespace RTCPHelp;
27
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000028// The number of RTCP time intervals needed to trigger a timeout.
29const int kRrTimeoutIntervals = 3;
30
pbos@webrtc.org2f446732013-04-08 11:08:41 +000031RTCPReceiver::RTCPReceiver(const int32_t id, Clock* clock,
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000032 ModuleRtpRtcpImpl* owner)
33 : TMMBRHelp(),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000034 _id(id),
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +000035 _clock(clock),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000036 _method(kRtcpOff),
37 _lastReceived(0),
38 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000039 _criticalSectionFeedbacks(
40 CriticalSectionWrapper::CreateCriticalSection()),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000041 _cbRtcpFeedback(NULL),
42 _cbRtcpBandwidthObserver(NULL),
43 _cbRtcpIntraFrameObserver(NULL),
44 _criticalSectionRTCPReceiver(
45 CriticalSectionWrapper::CreateCriticalSection()),
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000046 main_ssrc_(0),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000047 _remoteSSRC(0),
48 _remoteSenderInfo(),
49 _lastReceivedSRNTPsecs(0),
50 _lastReceivedSRNTPfrac(0),
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000051 _lastReceivedXRNTPsecs(0),
52 _lastReceivedXRNTPfrac(0),
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +000053 xr_rr_rtt_ms_(0),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000054 _receivedInfoMap(),
55 _packetTimeOutMS(0),
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000056 _lastReceivedRrMs(0),
asapersson@webrtc.org766154a2013-11-04 08:35:50 +000057 _lastIncreasedSequenceNumberMs(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +000058 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
59 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
60}
61
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000062RTCPReceiver::~RTCPReceiver() {
63 delete _criticalSectionRTCPReceiver;
64 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000065
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000066 while (!_receivedReportBlockMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000067 std::map<uint32_t, RTCPReportBlockInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000068 _receivedReportBlockMap.begin();
69 delete first->second;
70 _receivedReportBlockMap.erase(first);
71 }
72 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000073 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000074 _receivedInfoMap.begin();
75 delete first->second;
76 _receivedInfoMap.erase(first);
77 }
78 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000079 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000080 _receivedCnameMap.begin();
81 delete first->second;
82 _receivedCnameMap.erase(first);
83 }
84 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id,
85 "%s deleted", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +000086}
87
88void
pbos@webrtc.org2f446732013-04-08 11:08:41 +000089RTCPReceiver::ChangeUniqueId(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +000090{
91 _id = id;
92}
93
94RTCPMethod
95RTCPReceiver::Status() const
96{
97 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
98 return _method;
99}
100
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000101int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000102RTCPReceiver::SetRTCPStatus(const RTCPMethod method)
103{
104 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
105 _method = method;
106 return 0;
107}
108
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000109int64_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000110RTCPReceiver::LastReceived()
111{
112 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
113 return _lastReceived;
114}
115
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000116int64_t
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000117RTCPReceiver::LastReceivedReceiverReport() const {
118 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000119 int64_t last_received_rr = -1;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000120 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
121 it != _receivedInfoMap.end(); ++it) {
122 if (it->second->lastTimeReceived > last_received_rr) {
123 last_received_rr = it->second->lastTimeReceived;
124 }
125 }
126 return last_received_rr;
127}
128
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000129int32_t
130RTCPReceiver::SetRemoteSSRC( const uint32_t ssrc)
niklase@google.com470e71d2011-07-07 08:21:25 +0000131{
132 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
133
134 // new SSRC reset old reports
135 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
136 _lastReceivedSRNTPsecs = 0;
137 _lastReceivedSRNTPfrac = 0;
138
139 _remoteSSRC = ssrc;
140 return 0;
141}
142
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000143uint32_t RTCPReceiver::RemoteSSRC() const {
144 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
145 return _remoteSSRC;
146}
147
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000148void RTCPReceiver::RegisterRtcpObservers(
149 RtcpIntraFrameObserver* intra_frame_callback,
150 RtcpBandwidthObserver* bandwidth_callback,
151 RtcpFeedback* feedback_callback) {
152 CriticalSectionScoped lock(_criticalSectionFeedbacks);
153 _cbRtcpIntraFrameObserver = intra_frame_callback;
154 _cbRtcpBandwidthObserver = bandwidth_callback;
155 _cbRtcpFeedback = feedback_callback;
niklase@google.com470e71d2011-07-07 08:21:25 +0000156}
157
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000158void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
159 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000160 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000161 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000162 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000163 old_ssrc = main_ssrc_;
164 main_ssrc_ = main_ssrc;
165 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000166 }
167 {
168 CriticalSectionScoped lock(_criticalSectionFeedbacks);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000169 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
170 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000171 }
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
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000219bool RTCPReceiver::GetAndResetXrRrRtt(uint16_t* rtt_ms) {
220 assert(rtt_ms);
221 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
222 if (xr_rr_rtt_ms_ == 0) {
223 return false;
224 }
225 *rtt_ms = xr_rr_rtt_ms_;
226 xr_rr_rtt_ms_ = 0;
227 return true;
228}
229
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000230int32_t
231RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs,
232 uint32_t *ReceivedNTPfrac,
233 uint32_t *RTCPArrivalTimeSecs,
234 uint32_t *RTCPArrivalTimeFrac,
235 uint32_t *rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000236{
237 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
238 if(ReceivedNTPsecs)
239 {
240 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
241 }
242 if(ReceivedNTPfrac)
243 {
244 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
245 }
246 if(RTCPArrivalTimeFrac)
247 {
248 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
249 }
250 if(RTCPArrivalTimeSecs)
251 {
252 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
253 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000254 if (rtcp_timestamp) {
255 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
256 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000257 return 0;
258}
259
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000260bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
261 RtcpReceiveTimeInfo* info) const {
262 assert(info);
263 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
264 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
265 return false;
266 }
267
268 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
269 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
270
271 // Get the delay since last received report (RFC 3611).
272 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
273 _lastReceivedXRNTPfrac);
274
275 uint32_t ntp_sec = 0;
276 uint32_t ntp_frac = 0;
277 _clock->CurrentNtp(ntp_sec, ntp_frac);
278 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
279
280 info->delaySinceLastRR = now - receive_time;
281 return true;
282}
283
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000284int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000285RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
286{
287 if(senderInfo == NULL)
288 {
289 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
290 return -1;
291 }
292 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
293 if(_lastReceivedSRNTPsecs == 0)
294 {
295 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
296 return -1;
297 }
298 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
299 return 0;
300}
301
302// statistics
303// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000304int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000305 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000306 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000307 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
308
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000309 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000310 _receivedReportBlockMap.begin();
311
312 while (it != _receivedReportBlockMap.end()) {
313 receiveBlocks->push_back(it->second->remoteReceiveBlock);
314 it++;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000315 }
316 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000317}
318
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000319int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000320RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
321 RTCPUtility::RTCPParserV2* rtcpParser)
322{
323 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
324
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000325 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000326
327 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
328 while (pktType != RTCPUtility::kRtcpNotValidCode)
329 {
330 // Each "case" is responsible for iterate the parser to the
331 // next top level packet.
332 switch (pktType)
333 {
334 case RTCPUtility::kRtcpSrCode:
335 case RTCPUtility::kRtcpRrCode:
336 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
337 break;
338 case RTCPUtility::kRtcpSdesCode:
339 HandleSDES(*rtcpParser);
340 break;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000341 case RTCPUtility::kRtcpXrHeaderCode:
342 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
343 break;
344 case RTCPUtility::kRtcpXrReceiverReferenceTimeCode:
345 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
346 break;
347 case RTCPUtility::kRtcpXrDlrrReportBlockCode:
348 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
349 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000350 case RTCPUtility::kRtcpXrVoipMetricCode:
351 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
352 break;
353 case RTCPUtility::kRtcpByeCode:
354 HandleBYE(*rtcpParser);
355 break;
356 case RTCPUtility::kRtcpRtpfbNackCode:
357 HandleNACK(*rtcpParser, rtcpPacketInformation);
358 break;
359 case RTCPUtility::kRtcpRtpfbTmmbrCode:
360 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
361 break;
362 case RTCPUtility::kRtcpRtpfbTmmbnCode:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000363 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000364 break;
365 case RTCPUtility::kRtcpRtpfbSrReqCode:
366 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
367 break;
368 case RTCPUtility::kRtcpPsfbPliCode:
369 HandlePLI(*rtcpParser, rtcpPacketInformation);
370 break;
371 case RTCPUtility::kRtcpPsfbSliCode:
372 HandleSLI(*rtcpParser, rtcpPacketInformation);
373 break;
374 case RTCPUtility::kRtcpPsfbRpsiCode:
375 HandleRPSI(*rtcpParser, rtcpPacketInformation);
376 break;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000377 case RTCPUtility::kRtcpExtendedIjCode:
378 HandleIJ(*rtcpParser, rtcpPacketInformation);
379 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000380 case RTCPUtility::kRtcpPsfbFirCode:
381 HandleFIR(*rtcpParser, rtcpPacketInformation);
382 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000383 case RTCPUtility::kRtcpPsfbAppCode:
384 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
385 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000386 case RTCPUtility::kRtcpAppCode:
387 // generic application messages
388 HandleAPP(*rtcpParser, rtcpPacketInformation);
389 break;
390 case RTCPUtility::kRtcpAppItemCode:
391 // generic application messages
392 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
393 break;
394 default:
395 rtcpParser->Iterate();
396 break;
397 }
398 pktType = rtcpParser->PacketType();
399 }
400 return 0;
401}
402
403// no need for critsect we have _criticalSectionRTCPReceiver
404void
405RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
406 RTCPPacketInformation& rtcpPacketInformation)
407{
408 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
409 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
410
411 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
412
413 // SR.SenderSSRC
414 // The synchronization source identifier for the originator of this SR packet
415
416 // rtcpPacket.RR.SenderSSRC
417 // The source of the packet sender, same as of SR? or is this a CE?
418
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000419 const uint32_t remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
420 const uint8_t numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
niklase@google.com470e71d2011-07-07 08:21:25 +0000421
422 rtcpPacketInformation.remoteSSRC = remoteSSRC;
423
424 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
425 if (!ptrReceiveInfo)
426 {
427 rtcpParser.Iterate();
428 return;
429 }
430
431 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
432 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000433 TRACE_EVENT_INSTANT2("webrtc_rtp", "SR",
434 "remote_ssrc", remoteSSRC,
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000435 "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000436
niklase@google.com470e71d2011-07-07 08:21:25 +0000437 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
438 {
439 // only signal that we have received a SR when we accept one
440 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
441
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000442 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
443 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
444 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
445
niklase@google.com470e71d2011-07-07 08:21:25 +0000446 // We will only store the send report from one source, but
447 // we will store all the receive block
448
449 // Save the NTP time of this report
450 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
451 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
452 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
453 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
454 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
455
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000456 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000457 }
458 else
459 {
460 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
461 }
462 } else
463 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000464 TRACE_EVENT_INSTANT2("webrtc_rtp", "RR",
465 "remote_ssrc", remoteSSRC,
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000466 "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000467
468 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
469 }
470 UpdateReceiveInformation(*ptrReceiveInfo);
471
472 rtcpPacketType = rtcpParser.Iterate();
473
474 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
475 {
476 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
477 rtcpPacketType = rtcpParser.Iterate();
478 }
479}
480
481// no need for critsect we have _criticalSectionRTCPReceiver
482void
483RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
484 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000485 const uint32_t remoteSSRC,
486 const uint8_t numberOfReportBlocks) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000487 // This will be called once per report block in the RTCP packet.
488 // We filter out all report blocks that are not for us.
489 // Each packet has max 31 RR blocks.
490 //
491 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000492
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000493 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
494 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000495
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000496 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000497 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
498 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000499 // This block is not for us ignore it.
500 return;
501 }
502
503 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
504 // _criticalSectionRTCPReceiver.
505 _criticalSectionRTCPReceiver->Leave();
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000506 uint32_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000507 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
508 _criticalSectionRTCPReceiver->Enter();
509
510 RTCPReportBlockInformation* reportBlock =
511 CreateReportBlockInformation(remoteSSRC);
512 if (reportBlock == NULL) {
513 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
514 "\tfailed to CreateReportBlockInformation(%u)", remoteSSRC);
515 return;
516 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000517
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000518 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000519 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
520 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
521 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
522 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
523 reportBlock->remoteReceiveBlock.cumulativeLost =
524 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000525 if (rb.ExtendedHighestSequenceNumber >
526 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
527 // We have successfully delivered new RTP packets to the remote side after
528 // the last RR was sent from the remote side.
529 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000530 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000531 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
532 rb.ExtendedHighestSequenceNumber;
533 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
534 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
535 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
536
537 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
538 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
539 }
540
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000541 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000542 rtcpPacket.ReportBlockItem.DelayLastSR;
543
544 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000545 uint32_t lastReceivedRRNTPsecs = 0;
546 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000547
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000548 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000549
550 // time when we received this in MS
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000551 uint32_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
552 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000553
554 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000555 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000556 d /= 65536;
557 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
558
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000559 int32_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000560
561 if (sendTimeMS > 0) {
562 RTT = receiveTimeMS - d - sendTimeMS;
563 if (RTT <= 0) {
564 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000565 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000566 if (RTT > reportBlock->maxRTT) {
567 // store max RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000568 reportBlock->maxRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000569 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000570 if (reportBlock->minRTT == 0) {
571 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000572 reportBlock->minRTT = (uint16_t) RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000573 } else if (RTT < reportBlock->minRTT) {
574 // Store min RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000575 reportBlock->minRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000576 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000577 // store last RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000578 reportBlock->RTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000579
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000580 // store average RTT
581 if (reportBlock->numAverageCalcs != 0) {
582 float ac = static_cast<float> (reportBlock->numAverageCalcs);
583 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
584 + ((1 / (ac + 1)) * RTT);
585 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
586 } else {
587 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000588 reportBlock->avgRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000589 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000590 reportBlock->numAverageCalcs++;
591 }
592
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000593 TRACE_COUNTER_ID1("webrtc_rtp", "RR_RTT", rb.SSRC, RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000594
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000595 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000596}
597
598RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000599RTCPReceiver::CreateReportBlockInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000600 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000601
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000602 std::map<uint32_t, RTCPReportBlockInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000603 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000604
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000605 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
606 if (it != _receivedReportBlockMap.end()) {
607 ptrReportBlockInfo = it->second;
608 } else {
609 ptrReportBlockInfo = new RTCPReportBlockInformation;
610 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
611 }
612 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000613}
614
615RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000616RTCPReceiver::GetReportBlockInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000617 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000618
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000619 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000620 _receivedReportBlockMap.find(remoteSSRC);
621
622 if (it == _receivedReportBlockMap.end()) {
623 return NULL;
624 }
625 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000626}
627
628RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000629RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000630 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000631
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000632 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000633 _receivedCnameMap.find(remoteSSRC);
634
635 if (it != _receivedCnameMap.end()) {
636 return it->second;
637 }
638 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000639 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000640 _receivedCnameMap[remoteSSRC] = cnameInfo;
641 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000642}
643
644RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000645RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000646 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000647
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000648 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000649 _receivedCnameMap.find(remoteSSRC);
650
651 if (it == _receivedCnameMap.end()) {
652 return NULL;
653 }
654 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000655}
656
657RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000658RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000659 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000660
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000661 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000662 _receivedInfoMap.find(remoteSSRC);
663
664 if (it != _receivedInfoMap.end()) {
665 return it->second;
666 }
667 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
668 _receivedInfoMap[remoteSSRC] = receiveInfo;
669 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000670}
671
672RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000673RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000674 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000675
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000676 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000677 _receivedInfoMap.find(remoteSSRC);
678 if (it == _receivedInfoMap.end()) {
679 return NULL;
680 }
681 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000682}
683
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000684void RTCPReceiver::UpdateReceiveInformation(
685 RTCPReceiveInformation& receiveInformation) {
686 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000687 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000688}
689
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000690bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
691 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
692 if (_lastReceivedRrMs == 0)
693 return false;
694
695 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000696 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000697 // Reset the timer to only trigger one log.
698 _lastReceivedRrMs = 0;
699 return true;
700 }
701 return false;
702}
703
704bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
705 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
706 if (_lastIncreasedSequenceNumberMs == 0)
707 return false;
708
709 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000710 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000711 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000712 // Reset the timer to only trigger one log.
713 _lastIncreasedSequenceNumberMs = 0;
714 return true;
715 }
716 return false;
717}
718
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000719bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
720 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000721
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000722 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000723 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000724
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000725 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000726 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000727
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000728 while (receiveInfoIt != _receivedInfoMap.end()) {
729 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
730 if (receiveInfo == NULL) {
731 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000732 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000733 // time since last received rtcp packet
734 // when we dont have a lastTimeReceived and the object is marked
735 // readyForDelete it's removed from the map
736 if (receiveInfo->lastTimeReceived) {
737 /// use audio define since we don't know what interval the remote peer is
738 // using
739 if ((timeNow - receiveInfo->lastTimeReceived) >
740 5 * RTCP_INTERVAL_AUDIO_MS) {
741 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000742 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000743 // prevent that we call this over and over again
744 receiveInfo->lastTimeReceived = 0;
745 // send new TMMBN to all channels using the default codec
746 updateBoundingSet = true;
747 }
748 receiveInfoIt++;
749 } else if (receiveInfo->readyForDelete) {
750 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000751 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000752 receiveInfoItemToBeErased = receiveInfoIt;
753 receiveInfoIt++;
754 delete receiveInfoItemToBeErased->second;
755 _receivedInfoMap.erase(receiveInfoItemToBeErased);
756 } else {
757 receiveInfoIt++;
758 }
759 }
760 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000761}
762
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000763int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000764 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000765
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000766 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000767 _receivedInfoMap.find(_remoteSSRC);
768
769 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000770 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000771 }
772 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
773 if (receiveInfo == NULL) {
774 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
775 "%s failed to get RTCPReceiveInformation",
776 __FUNCTION__);
777 return -1;
778 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000779 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000780 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000781 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000782 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000783 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000784 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000785 // owner of bounding set
786 tmmbrOwner = true;
787 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000788 boundingSetRec->SetEntry(i,
789 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
790 receiveInfo->TmmbnBoundingSet.PacketOH(i),
791 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000792 }
793 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000794 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000795}
796
797// no need for critsect we have _criticalSectionRTCPReceiver
798void
799RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
800{
801 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
802 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
803 {
804 HandleSDESChunk(rtcpParser);
805 pktType = rtcpParser.Iterate();
806 }
807}
808
809// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000810void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
811 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
812 RTCPCnameInformation* cnameInfo =
813 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
814 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000815
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000816 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
817 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000818}
819
820// no need for critsect we have _criticalSectionRTCPReceiver
821void
822RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
823 RTCPPacketInformation& rtcpPacketInformation)
824{
825 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000826 if (main_ssrc_ != rtcpPacket.NACK.MediaSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000827 {
828 // Not to us.
829 rtcpParser.Iterate();
830 return;
831 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000832 rtcpPacketInformation.ResetNACKPacketIdArray();
833
834 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
835 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
836 {
837 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
838 pktType = rtcpParser.Iterate();
839 }
840}
841
842// no need for critsect we have _criticalSectionRTCPReceiver
843void
844RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
845 RTCPPacketInformation& rtcpPacketInformation)
846{
847 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
848
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000849 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
niklase@google.com470e71d2011-07-07 08:21:25 +0000850 if(bitMask)
851 {
852 for(int i=1; i <= 16; ++i)
853 {
854 if(bitMask & 0x01)
855 {
856 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
857 }
858 bitMask = bitMask >>1;
859 }
860 }
861
862 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
863}
864
865// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000866void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
867 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000868
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000869 // clear our lists
870 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000871 std::map<uint32_t, RTCPReportBlockInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000872 reportBlockInfoIt = _receivedReportBlockMap.find(
873 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000874
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000875 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
876 delete reportBlockInfoIt->second;
877 _receivedReportBlockMap.erase(reportBlockInfoIt);
878 }
879 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000880 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000881 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000882
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000883 if (receiveInfoIt != _receivedInfoMap.end()) {
884 receiveInfoIt->second->readyForDelete = true;
885 }
886
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000887 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000888 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
889
890 if (cnameInfoIt != _receivedCnameMap.end()) {
891 delete cnameInfoIt->second;
892 _receivedCnameMap.erase(cnameInfoIt);
893 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000894 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000895 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000896}
897
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000898void RTCPReceiver::HandleXrHeader(
899 RTCPUtility::RTCPParserV2& parser,
900 RTCPPacketInformation& rtcpPacketInformation) {
901 const RTCPUtility::RTCPPacket& packet = parser.Packet();
902
903 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
904
905 parser.Iterate();
906}
907
908void RTCPReceiver::HandleXrReceiveReferenceTime(
909 RTCPUtility::RTCPParserV2& parser,
910 RTCPPacketInformation& rtcpPacketInformation) {
911 const RTCPUtility::RTCPPacket& packet = parser.Packet();
912
913 _remoteXRReceiveTimeInfo.sourceSSRC =
914 rtcpPacketInformation.xr_originator_ssrc;
915
916 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
917 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
918 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
919
920 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
921
922 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
923
924 parser.Iterate();
925}
926
927void RTCPReceiver::HandleXrDlrrReportBlock(
928 RTCPUtility::RTCPParserV2& parser,
929 RTCPPacketInformation& rtcpPacketInformation) {
930 const RTCPUtility::RTCPPacket& packet = parser.Packet();
931 // Iterate through sub-block(s), if any.
932 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
933
934 while (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) {
935 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
936 packet_type = parser.Iterate();
937 }
938}
939
940void RTCPReceiver::HandleXrDlrrReportBlockItem(
941 const RTCPUtility::RTCPPacket& packet,
942 RTCPPacketInformation& rtcpPacketInformation) {
943 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
944 registered_ssrcs_.end()) {
945 // Not to us.
946 return;
947 }
948
949 rtcpPacketInformation.xr_dlrr_item = true;
950
951 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
952 // _criticalSectionRTCPReceiver.
953 _criticalSectionRTCPReceiver->Leave();
954
955 int64_t send_time_ms;
956 bool found = _rtpRtcp.SendTimeOfXrRrReport(
957 packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
958
959 _criticalSectionRTCPReceiver->Enter();
960
961 if (!found) {
962 return;
963 }
964
965 // The DelayLastRR field is in units of 1/65536 sec.
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000966 uint32_t delay_rr_ms =
967 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
968 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000969
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000970 int32_t rtt = _clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
971
972 xr_rr_rtt_ms_ = static_cast<uint16_t>(std::max(rtt, 1));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000973
974 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
975}
976
niklase@google.com470e71d2011-07-07 08:21:25 +0000977// no need for critsect we have _criticalSectionRTCPReceiver
978void
979RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
980 RTCPPacketInformation& rtcpPacketInformation)
981{
982 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
983
984 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
985
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000986 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000987 {
988 // Store VoIP metrics block if it's about me
989 // from OriginatorSSRC do we filter it?
990 // rtcpPacket.XR.OriginatorSSRC;
991
992 RTCPVoIPMetric receivedVoIPMetrics;
993 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
994 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
995 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
996 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
997 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
998 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
999 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
1000 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
1001 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
1002 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
1003 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
1004 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
1005 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
1006 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
1007 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
1008 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
1009 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
1010 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
1011 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
1012 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
1013
1014 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
1015
1016 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
1017 }
1018 rtcpParser.Iterate();
1019}
1020
1021// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001022void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
1023 RTCPPacketInformation& rtcpPacketInformation) {
1024 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001025 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +00001026 TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
1027
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001028 // Received a signal that we need to send a new key frame.
1029 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
1030 }
1031 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001032}
1033
1034// no need for critsect we have _criticalSectionRTCPReceiver
1035void
1036RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
1037 RTCPPacketInformation& rtcpPacketInformation)
1038{
1039 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1040
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001041 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001042 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
1043 if (ptrReceiveInfo == NULL)
1044 {
1045 // This remote SSRC must be saved before.
1046 rtcpParser.Iterate();
1047 return;
1048 }
1049 if(rtcpPacket.TMMBR.MediaSSRC)
1050 {
1051 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1052 // in relay mode this is a valid number
1053 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1054 }
1055
1056 // Use packet length to calc max number of TMMBR blocks
1057 // each TMMBR block is 8 bytes
1058 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
1059
1060 // sanity
1061 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
1062 {
1063 assert(false);
1064 rtcpParser.Iterate();
1065 return;
1066 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001067 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001068
1069 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1070 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
1071 {
1072 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1073 pktType = rtcpParser.Iterate();
1074 }
1075}
1076
1077// no need for critsect we have _criticalSectionRTCPReceiver
1078void
1079RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1080 const RTCPUtility::RTCPPacket& rtcpPacket,
1081 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001082 const uint32_t senderSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +00001083{
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001084 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
niklase@google.com470e71d2011-07-07 08:21:25 +00001085 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
1086 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +00001087 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001088 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +00001089 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1090 }
1091}
1092
1093// no need for critsect we have _criticalSectionRTCPReceiver
1094void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +00001095RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1096 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +00001097{
1098 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1099 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
1100 if (ptrReceiveInfo == NULL)
1101 {
1102 // This remote SSRC must be saved before.
1103 rtcpParser.Iterate();
1104 return;
1105 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +00001106 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +00001107 // Use packet length to calc max number of TMMBN blocks
1108 // each TMMBN block is 8 bytes
1109 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1110
1111 // sanity
1112 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1113 {
1114 assert(false);
1115 rtcpParser.Iterate();
1116 return;
1117 }
1118
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001119 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001120
1121 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1122 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1123 {
1124 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1125 pktType = rtcpParser.Iterate();
1126 }
1127}
1128
1129// no need for critsect we have _criticalSectionRTCPReceiver
1130void
1131RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1132 RTCPPacketInformation& rtcpPacketInformation)
1133{
1134 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1135 rtcpParser.Iterate();
1136}
1137
1138// no need for critsect we have _criticalSectionRTCPReceiver
1139void
1140RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1141 const RTCPUtility::RTCPPacket& rtcpPacket)
1142{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001143 receiveInfo.TmmbnBoundingSet.AddEntry(
1144 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1145 rtcpPacket.TMMBNItem.MeasuredOverhead,
1146 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001147}
1148
1149// no need for critsect we have _criticalSectionRTCPReceiver
1150void
1151RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1152 RTCPPacketInformation& rtcpPacketInformation)
1153{
1154 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001155 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1156 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1157 {
1158 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1159 pktType = rtcpParser.Iterate();
1160 }
1161}
1162
1163// no need for critsect we have _criticalSectionRTCPReceiver
1164void
1165RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1166 RTCPPacketInformation& rtcpPacketInformation)
1167{
1168 // in theory there could be multiple slices lost
1169 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1170 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1171}
1172
1173void
1174RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1175 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1176{
1177 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001178 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1179 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1180 {
1181 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1182 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1183 {
1184 // to us unknown
1185 // continue
1186 rtcpParser.Iterate();
1187 return;
1188 }
1189 rtcpPacketInformation.rpsiPictureId = 0;
1190
1191 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001192 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1193 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001194 {
1195 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1196 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1197 }
1198 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1199 }
1200}
1201
1202// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001203void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1204 RTCPPacketInformation& rtcpPacketInformation) {
1205 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1206 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1207 pktType = rtcpParser.Iterate();
1208 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1209 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1210 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001211 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001212 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001213}
1214
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001215// no need for critsect we have _criticalSectionRTCPReceiver
1216void
1217RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1218 RTCPPacketInformation& rtcpPacketInformation)
1219{
1220 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1221
1222 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1223 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1224 {
1225 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1226 pktType = rtcpParser.Iterate();
1227 }
1228}
1229
1230void
1231RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1232 RTCPPacketInformation& rtcpPacketInformation)
1233{
1234 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1235 rtcpPacketInformation.interArrivalJitter =
1236 rtcpPacket.ExtendedJitterReportItem.Jitter;
1237}
1238
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001239void RTCPReceiver::HandleREMBItem(
1240 RTCPUtility::RTCPParserV2& rtcpParser,
1241 RTCPPacketInformation& rtcpPacketInformation) {
1242 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1243 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1244 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1245 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001246}
1247
1248// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001249void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1250 RTCPPacketInformation& rtcpPacketInformation) {
1251 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1252 RTCPReceiveInformation* ptrReceiveInfo =
1253 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001254
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001255 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1256 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1257 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1258 pktType = rtcpParser.Iterate();
1259 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001260}
1261
1262// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001263void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1264 const RTCPUtility::RTCPPacket& rtcpPacket,
1265 RTCPPacketInformation& rtcpPacketInformation) {
1266 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001267 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001268 return;
1269 }
1270 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1271 // we don't know who this originate from
1272 if (receiveInfo) {
1273 // check if we have reported this FIRSequenceNumber before
1274 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1275 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001276 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001277 // sanity; don't go crazy with the callbacks
1278 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1279 receiveInfo->lastFIRRequest = now;
1280 receiveInfo->lastFIRSequenceNumber =
1281 rtcpPacket.FIRItem.CommandSequenceNumber;
1282 // received signal that we need to send a new key frame
1283 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1284 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001285 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001286 } else {
1287 // received signal that we need to send a new key frame
1288 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1289 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001290}
1291
1292void
1293RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1294 RTCPPacketInformation& rtcpPacketInformation)
1295{
1296 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1297
1298 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1299 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1300 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1301
1302 rtcpParser.Iterate();
1303}
1304
1305void
1306RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1307 RTCPPacketInformation& rtcpPacketInformation)
1308{
1309 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1310
1311 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1312
1313 rtcpParser.Iterate();
1314}
1315
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001316int32_t RTCPReceiver::UpdateTMMBR() {
1317 int32_t numBoundingSet = 0;
1318 uint32_t bitrate = 0;
1319 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001320
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001321 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001322 if (size > 0) {
1323 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1324 // Get candidate set from receiver.
1325 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1326 } else {
1327 // Candidate set empty.
1328 VerifyAndAllocateCandidateSet(0); // resets candidate set
1329 }
1330 // Find bounding set
1331 TMMBRSet* boundingSet = NULL;
1332 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1333 if (numBoundingSet == -1) {
1334 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1335 "Failed to find TMMBR bounding set.");
1336 return -1;
1337 }
1338 // Set bounding set
1339 // Inform remote clients about the new bandwidth
1340 // inform the remote client
1341 _rtpRtcp.SetTMMBN(boundingSet);
1342
1343 // might trigger a TMMBN
1344 if (numBoundingSet == 0) {
1345 // owner of max bitrate request has timed out
1346 // empty bounding set has been sent
1347 return 0;
1348 }
1349 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001350 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001351 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001352 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1353 if (_cbRtcpBandwidthObserver) {
1354 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1355 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1356 "Set TMMBR request:%d kbps", bitrate);
1357 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001358 }
1359 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001360}
1361
1362// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001363void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001364 RTCPPacketInformation& rtcpPacketInformation) {
1365 // Process TMMBR and REMB first to avoid multiple callbacks
1366 // to OnNetworkChanged.
1367 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1368 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1369 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001370
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001371 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1372 UpdateTMMBR();
1373 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001374 unsigned int local_ssrc = 0;
1375 {
1376 // We don't want to hold this critsect when triggering the callbacks below.
1377 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001378 local_ssrc = main_ssrc_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001379 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001380 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1381 _rtpRtcp.OnRequestSendReport();
1382 }
1383 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001384 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001385 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1386 "SIG [RTCP] Incoming NACK length:%d",
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001387 rtcpPacketInformation.nackSequenceNumbers.size());
1388 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001389 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001390 }
1391 {
1392 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001393
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001394 // We need feedback that we have received a report block(s) so that we
1395 // can generate a new packet in a conference relay scenario, one received
1396 // report can generate several RTCP packets, based on number relayed/mixed
1397 // a send report block should go out to all receivers.
1398 if (_cbRtcpIntraFrameObserver) {
1399 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1400 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1401 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1402 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1403 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1404 rtcpPacketInformation.remoteSSRC);
1405 } else {
1406 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1407 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1408 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001409 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001410 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001411 }
1412 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1413 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001414 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001415 }
1416 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1417 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001418 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001419 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001420 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001421 if (_cbRtcpBandwidthObserver) {
1422 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1423 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1424 "SIG [RTCP] Incoming REMB:%d",
1425 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1426 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1427 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1428 }
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001429 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1430 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001431 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001432 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001433 rtcpPacketInformation.report_blocks,
1434 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001435 now);
1436 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001437 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001438 if(_cbRtcpFeedback) {
solenberg@webrtc.org91811e22013-06-25 20:36:14 +00001439 if(!(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001440 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1441 rtcpPacketInformation.remoteSSRC);
1442 }
1443 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1444 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1445 rtcpPacketInformation.VoIPMetric);
1446 }
1447 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1448 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1449 rtcpPacketInformation.applicationSubType,
1450 rtcpPacketInformation.applicationName,
1451 rtcpPacketInformation.applicationLength,
1452 rtcpPacketInformation.applicationData);
1453 }
1454 }
1455 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001456}
1457
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001458int32_t RTCPReceiver::CNAME(const uint32_t remoteSSRC,
1459 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001460 assert(cName);
1461
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001462 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1463 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001464 if (cnameInfo == NULL) {
1465 return -1;
1466 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001467 cName[RTCP_CNAME_SIZE - 1] = 0;
1468 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1469 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001470}
1471
1472// no callbacks allowed inside this function
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001473int32_t RTCPReceiver::TMMBRReceived(const uint32_t size,
1474 const uint32_t accNumCandidates,
1475 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001476 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001477
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001478 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001479 receiveInfoIt = _receivedInfoMap.begin();
1480 if (receiveInfoIt == _receivedInfoMap.end()) {
1481 return -1;
1482 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001483 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001484 if (candidateSet) {
1485 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1486 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1487 if (receiveInfo == NULL) {
1488 return 0;
1489 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001490 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001491 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001492 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001493 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001494 num++;
1495 }
1496 }
1497 receiveInfoIt++;
1498 }
1499 } else {
1500 while (receiveInfoIt != _receivedInfoMap.end()) {
1501 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1502 if(receiveInfo == NULL) {
1503 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1504 "%s failed to get RTCPReceiveInformation",
1505 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001506 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001507 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001508 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001509 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001510 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001511 }
1512 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001513}
1514
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001515} // namespace webrtc