blob: 25fa82c65825d64b5d2838212332f8f5d84f4294 [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),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000053 _receivedInfoMap(),
54 _packetTimeOutMS(0),
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000055 _lastReceivedRrMs(0),
stefan@webrtc.org8ca8a712013-04-23 16:48:32 +000056 _lastIncreasedSequenceNumberMs(0),
57 _rtt(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
stefan@webrtc.org8ca8a712013-04-23 16:48:32 +0000219uint16_t RTCPReceiver::RTT() const {
220 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
221 if (!_receivedReportBlockMap.empty()) {
222 return 0;
223 }
224 return _rtt;
225}
226
227int RTCPReceiver::SetRTT(uint16_t rtt) {
228 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
229 if (!_receivedReportBlockMap.empty()) {
230 return -1;
231 }
232 _rtt = rtt;
233 return 0;
234}
235
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000236int32_t
237RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs,
238 uint32_t *ReceivedNTPfrac,
239 uint32_t *RTCPArrivalTimeSecs,
240 uint32_t *RTCPArrivalTimeFrac,
241 uint32_t *rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000242{
243 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
244 if(ReceivedNTPsecs)
245 {
246 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
247 }
248 if(ReceivedNTPfrac)
249 {
250 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
251 }
252 if(RTCPArrivalTimeFrac)
253 {
254 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
255 }
256 if(RTCPArrivalTimeSecs)
257 {
258 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
259 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000260 if (rtcp_timestamp) {
261 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
262 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000263 return 0;
264}
265
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000266bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
267 RtcpReceiveTimeInfo* info) const {
268 assert(info);
269 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
270 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
271 return false;
272 }
273
274 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
275 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
276
277 // Get the delay since last received report (RFC 3611).
278 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
279 _lastReceivedXRNTPfrac);
280
281 uint32_t ntp_sec = 0;
282 uint32_t ntp_frac = 0;
283 _clock->CurrentNtp(ntp_sec, ntp_frac);
284 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
285
286 info->delaySinceLastRR = now - receive_time;
287 return true;
288}
289
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000290int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000291RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
292{
293 if(senderInfo == NULL)
294 {
295 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
296 return -1;
297 }
298 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
299 if(_lastReceivedSRNTPsecs == 0)
300 {
301 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
302 return -1;
303 }
304 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
305 return 0;
306}
307
308// statistics
309// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000310int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000311 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000312 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000313 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
314
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000315 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000316 _receivedReportBlockMap.begin();
317
318 while (it != _receivedReportBlockMap.end()) {
319 receiveBlocks->push_back(it->second->remoteReceiveBlock);
320 it++;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000321 }
322 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000323}
324
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000325int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000326RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
327 RTCPUtility::RTCPParserV2* rtcpParser)
328{
329 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
330
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000331 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000332
333 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
334 while (pktType != RTCPUtility::kRtcpNotValidCode)
335 {
336 // Each "case" is responsible for iterate the parser to the
337 // next top level packet.
338 switch (pktType)
339 {
340 case RTCPUtility::kRtcpSrCode:
341 case RTCPUtility::kRtcpRrCode:
342 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
343 break;
344 case RTCPUtility::kRtcpSdesCode:
345 HandleSDES(*rtcpParser);
346 break;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000347 case RTCPUtility::kRtcpXrHeaderCode:
348 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
349 break;
350 case RTCPUtility::kRtcpXrReceiverReferenceTimeCode:
351 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
352 break;
353 case RTCPUtility::kRtcpXrDlrrReportBlockCode:
354 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
355 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000356 case RTCPUtility::kRtcpXrVoipMetricCode:
357 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
358 break;
359 case RTCPUtility::kRtcpByeCode:
360 HandleBYE(*rtcpParser);
361 break;
362 case RTCPUtility::kRtcpRtpfbNackCode:
363 HandleNACK(*rtcpParser, rtcpPacketInformation);
364 break;
365 case RTCPUtility::kRtcpRtpfbTmmbrCode:
366 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
367 break;
368 case RTCPUtility::kRtcpRtpfbTmmbnCode:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000369 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000370 break;
371 case RTCPUtility::kRtcpRtpfbSrReqCode:
372 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
373 break;
374 case RTCPUtility::kRtcpPsfbPliCode:
375 HandlePLI(*rtcpParser, rtcpPacketInformation);
376 break;
377 case RTCPUtility::kRtcpPsfbSliCode:
378 HandleSLI(*rtcpParser, rtcpPacketInformation);
379 break;
380 case RTCPUtility::kRtcpPsfbRpsiCode:
381 HandleRPSI(*rtcpParser, rtcpPacketInformation);
382 break;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000383 case RTCPUtility::kRtcpExtendedIjCode:
384 HandleIJ(*rtcpParser, rtcpPacketInformation);
385 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000386 case RTCPUtility::kRtcpPsfbFirCode:
387 HandleFIR(*rtcpParser, rtcpPacketInformation);
388 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000389 case RTCPUtility::kRtcpPsfbAppCode:
390 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
391 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000392 case RTCPUtility::kRtcpAppCode:
393 // generic application messages
394 HandleAPP(*rtcpParser, rtcpPacketInformation);
395 break;
396 case RTCPUtility::kRtcpAppItemCode:
397 // generic application messages
398 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
399 break;
400 default:
401 rtcpParser->Iterate();
402 break;
403 }
404 pktType = rtcpParser->PacketType();
405 }
406 return 0;
407}
408
409// no need for critsect we have _criticalSectionRTCPReceiver
410void
411RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
412 RTCPPacketInformation& rtcpPacketInformation)
413{
414 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
415 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
416
417 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
418
419 // SR.SenderSSRC
420 // The synchronization source identifier for the originator of this SR packet
421
422 // rtcpPacket.RR.SenderSSRC
423 // The source of the packet sender, same as of SR? or is this a CE?
424
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000425 const uint32_t remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
426 const uint8_t numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
niklase@google.com470e71d2011-07-07 08:21:25 +0000427
428 rtcpPacketInformation.remoteSSRC = remoteSSRC;
429
430 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
431 if (!ptrReceiveInfo)
432 {
433 rtcpParser.Iterate();
434 return;
435 }
436
437 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
438 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000439 TRACE_EVENT_INSTANT2("webrtc_rtp", "SR",
440 "remote_ssrc", remoteSSRC,
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000441 "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000442
niklase@google.com470e71d2011-07-07 08:21:25 +0000443 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
444 {
445 // only signal that we have received a SR when we accept one
446 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
447
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000448 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
449 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
450 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
451
niklase@google.com470e71d2011-07-07 08:21:25 +0000452 // We will only store the send report from one source, but
453 // we will store all the receive block
454
455 // Save the NTP time of this report
456 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
457 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
458 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
459 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
460 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
461
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000462 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000463 }
464 else
465 {
466 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
467 }
468 } else
469 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000470 TRACE_EVENT_INSTANT2("webrtc_rtp", "RR",
471 "remote_ssrc", remoteSSRC,
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000472 "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000473
474 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
475 }
476 UpdateReceiveInformation(*ptrReceiveInfo);
477
478 rtcpPacketType = rtcpParser.Iterate();
479
480 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
481 {
482 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
483 rtcpPacketType = rtcpParser.Iterate();
484 }
485}
486
487// no need for critsect we have _criticalSectionRTCPReceiver
488void
489RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
490 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000491 const uint32_t remoteSSRC,
492 const uint8_t numberOfReportBlocks) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000493 // This will be called once per report block in the RTCP packet.
494 // We filter out all report blocks that are not for us.
495 // Each packet has max 31 RR blocks.
496 //
497 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000498
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000499 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
500 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000501
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000502 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000503 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
504 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000505 // This block is not for us ignore it.
506 return;
507 }
508
509 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
510 // _criticalSectionRTCPReceiver.
511 _criticalSectionRTCPReceiver->Leave();
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000512 uint32_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000513 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
514 _criticalSectionRTCPReceiver->Enter();
515
516 RTCPReportBlockInformation* reportBlock =
517 CreateReportBlockInformation(remoteSSRC);
518 if (reportBlock == NULL) {
519 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
520 "\tfailed to CreateReportBlockInformation(%u)", remoteSSRC);
521 return;
522 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000523
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000524 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000525 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
526 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
527 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
528 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
529 reportBlock->remoteReceiveBlock.cumulativeLost =
530 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000531 if (rb.ExtendedHighestSequenceNumber >
532 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
533 // We have successfully delivered new RTP packets to the remote side after
534 // the last RR was sent from the remote side.
535 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000536 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000537 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
538 rb.ExtendedHighestSequenceNumber;
539 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
540 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
541 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
542
543 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
544 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
545 }
546
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000547 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000548 rtcpPacket.ReportBlockItem.DelayLastSR;
549
550 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000551 uint32_t lastReceivedRRNTPsecs = 0;
552 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000553
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000554 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000555
556 // time when we received this in MS
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000557 uint32_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
558 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000559
560 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000561 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000562 d /= 65536;
563 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
564
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000565 int32_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000566
567 if (sendTimeMS > 0) {
568 RTT = receiveTimeMS - d - sendTimeMS;
569 if (RTT <= 0) {
570 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000571 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000572 if (RTT > reportBlock->maxRTT) {
573 // store max RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000574 reportBlock->maxRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000575 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000576 if (reportBlock->minRTT == 0) {
577 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000578 reportBlock->minRTT = (uint16_t) RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000579 } else if (RTT < reportBlock->minRTT) {
580 // Store min RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000581 reportBlock->minRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000582 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000583 // store last RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000584 reportBlock->RTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000585
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000586 // store average RTT
587 if (reportBlock->numAverageCalcs != 0) {
588 float ac = static_cast<float> (reportBlock->numAverageCalcs);
589 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
590 + ((1 / (ac + 1)) * RTT);
591 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
592 } else {
593 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000594 reportBlock->avgRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000595 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000596 reportBlock->numAverageCalcs++;
597 }
598
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000599 TRACE_COUNTER_ID1("webrtc_rtp", "RR_RTT", rb.SSRC, RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000600
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000601 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000602}
603
604RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000605RTCPReceiver::CreateReportBlockInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000606 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000607
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000608 std::map<uint32_t, RTCPReportBlockInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000609 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000610
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000611 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
612 if (it != _receivedReportBlockMap.end()) {
613 ptrReportBlockInfo = it->second;
614 } else {
615 ptrReportBlockInfo = new RTCPReportBlockInformation;
616 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
617 }
618 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000619}
620
621RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000622RTCPReceiver::GetReportBlockInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000623 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000624
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000625 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000626 _receivedReportBlockMap.find(remoteSSRC);
627
628 if (it == _receivedReportBlockMap.end()) {
629 return NULL;
630 }
631 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000632}
633
634RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000635RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000636 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000637
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000638 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000639 _receivedCnameMap.find(remoteSSRC);
640
641 if (it != _receivedCnameMap.end()) {
642 return it->second;
643 }
644 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000645 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000646 _receivedCnameMap[remoteSSRC] = cnameInfo;
647 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000648}
649
650RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000651RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000652 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000653
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000654 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000655 _receivedCnameMap.find(remoteSSRC);
656
657 if (it == _receivedCnameMap.end()) {
658 return NULL;
659 }
660 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000661}
662
663RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000664RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000665 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000666
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000667 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000668 _receivedInfoMap.find(remoteSSRC);
669
670 if (it != _receivedInfoMap.end()) {
671 return it->second;
672 }
673 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
674 _receivedInfoMap[remoteSSRC] = receiveInfo;
675 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000676}
677
678RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000679RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000680 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000681
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000682 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000683 _receivedInfoMap.find(remoteSSRC);
684 if (it == _receivedInfoMap.end()) {
685 return NULL;
686 }
687 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000688}
689
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000690void RTCPReceiver::UpdateReceiveInformation(
691 RTCPReceiveInformation& receiveInformation) {
692 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000693 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000694}
695
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000696bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
697 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
698 if (_lastReceivedRrMs == 0)
699 return false;
700
701 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000702 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000703 // Reset the timer to only trigger one log.
704 _lastReceivedRrMs = 0;
705 return true;
706 }
707 return false;
708}
709
710bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
711 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
712 if (_lastIncreasedSequenceNumberMs == 0)
713 return false;
714
715 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000716 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000717 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000718 // Reset the timer to only trigger one log.
719 _lastIncreasedSequenceNumberMs = 0;
720 return true;
721 }
722 return false;
723}
724
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000725bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
726 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000727
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000728 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000729 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000730
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000731 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000732 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000733
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000734 while (receiveInfoIt != _receivedInfoMap.end()) {
735 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
736 if (receiveInfo == NULL) {
737 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000738 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000739 // time since last received rtcp packet
740 // when we dont have a lastTimeReceived and the object is marked
741 // readyForDelete it's removed from the map
742 if (receiveInfo->lastTimeReceived) {
743 /// use audio define since we don't know what interval the remote peer is
744 // using
745 if ((timeNow - receiveInfo->lastTimeReceived) >
746 5 * RTCP_INTERVAL_AUDIO_MS) {
747 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000748 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000749 // prevent that we call this over and over again
750 receiveInfo->lastTimeReceived = 0;
751 // send new TMMBN to all channels using the default codec
752 updateBoundingSet = true;
753 }
754 receiveInfoIt++;
755 } else if (receiveInfo->readyForDelete) {
756 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000757 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000758 receiveInfoItemToBeErased = receiveInfoIt;
759 receiveInfoIt++;
760 delete receiveInfoItemToBeErased->second;
761 _receivedInfoMap.erase(receiveInfoItemToBeErased);
762 } else {
763 receiveInfoIt++;
764 }
765 }
766 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000767}
768
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000769int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000770 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000771
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000772 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000773 _receivedInfoMap.find(_remoteSSRC);
774
775 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000776 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000777 }
778 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
779 if (receiveInfo == NULL) {
780 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
781 "%s failed to get RTCPReceiveInformation",
782 __FUNCTION__);
783 return -1;
784 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000785 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000786 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000787 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000788 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000789 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000790 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000791 // owner of bounding set
792 tmmbrOwner = true;
793 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000794 boundingSetRec->SetEntry(i,
795 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
796 receiveInfo->TmmbnBoundingSet.PacketOH(i),
797 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000798 }
799 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000800 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000801}
802
803// no need for critsect we have _criticalSectionRTCPReceiver
804void
805RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
806{
807 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
808 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
809 {
810 HandleSDESChunk(rtcpParser);
811 pktType = rtcpParser.Iterate();
812 }
813}
814
815// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000816void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
817 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
818 RTCPCnameInformation* cnameInfo =
819 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
820 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000821
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000822 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
823 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000824}
825
826// no need for critsect we have _criticalSectionRTCPReceiver
827void
828RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
829 RTCPPacketInformation& rtcpPacketInformation)
830{
831 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000832 if (main_ssrc_ != rtcpPacket.NACK.MediaSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000833 {
834 // Not to us.
835 rtcpParser.Iterate();
836 return;
837 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000838 rtcpPacketInformation.ResetNACKPacketIdArray();
839
840 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
841 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
842 {
843 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
844 pktType = rtcpParser.Iterate();
845 }
846}
847
848// no need for critsect we have _criticalSectionRTCPReceiver
849void
850RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
851 RTCPPacketInformation& rtcpPacketInformation)
852{
853 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
854
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000855 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
niklase@google.com470e71d2011-07-07 08:21:25 +0000856 if(bitMask)
857 {
858 for(int i=1; i <= 16; ++i)
859 {
860 if(bitMask & 0x01)
861 {
862 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
863 }
864 bitMask = bitMask >>1;
865 }
866 }
867
868 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
869}
870
871// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000872void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
873 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000874
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000875 // clear our lists
876 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000877 std::map<uint32_t, RTCPReportBlockInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000878 reportBlockInfoIt = _receivedReportBlockMap.find(
879 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000880
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000881 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
882 delete reportBlockInfoIt->second;
883 _receivedReportBlockMap.erase(reportBlockInfoIt);
884 }
885 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000886 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000887 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000888
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000889 if (receiveInfoIt != _receivedInfoMap.end()) {
890 receiveInfoIt->second->readyForDelete = true;
891 }
892
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000893 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000894 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
895
896 if (cnameInfoIt != _receivedCnameMap.end()) {
897 delete cnameInfoIt->second;
898 _receivedCnameMap.erase(cnameInfoIt);
899 }
900 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000901}
902
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000903void RTCPReceiver::HandleXrHeader(
904 RTCPUtility::RTCPParserV2& parser,
905 RTCPPacketInformation& rtcpPacketInformation) {
906 const RTCPUtility::RTCPPacket& packet = parser.Packet();
907
908 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
909
910 parser.Iterate();
911}
912
913void RTCPReceiver::HandleXrReceiveReferenceTime(
914 RTCPUtility::RTCPParserV2& parser,
915 RTCPPacketInformation& rtcpPacketInformation) {
916 const RTCPUtility::RTCPPacket& packet = parser.Packet();
917
918 _remoteXRReceiveTimeInfo.sourceSSRC =
919 rtcpPacketInformation.xr_originator_ssrc;
920
921 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
922 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
923 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
924
925 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
926
927 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
928
929 parser.Iterate();
930}
931
932void RTCPReceiver::HandleXrDlrrReportBlock(
933 RTCPUtility::RTCPParserV2& parser,
934 RTCPPacketInformation& rtcpPacketInformation) {
935 const RTCPUtility::RTCPPacket& packet = parser.Packet();
936 // Iterate through sub-block(s), if any.
937 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
938
939 while (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) {
940 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
941 packet_type = parser.Iterate();
942 }
943}
944
945void RTCPReceiver::HandleXrDlrrReportBlockItem(
946 const RTCPUtility::RTCPPacket& packet,
947 RTCPPacketInformation& rtcpPacketInformation) {
948 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
949 registered_ssrcs_.end()) {
950 // Not to us.
951 return;
952 }
953
954 rtcpPacketInformation.xr_dlrr_item = true;
955
956 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
957 // _criticalSectionRTCPReceiver.
958 _criticalSectionRTCPReceiver->Leave();
959
960 int64_t send_time_ms;
961 bool found = _rtpRtcp.SendTimeOfXrRrReport(
962 packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
963
964 _criticalSectionRTCPReceiver->Enter();
965
966 if (!found) {
967 return;
968 }
969
970 // The DelayLastRR field is in units of 1/65536 sec.
971// uint32_t delay_rr_ms =
972// (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
973// (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
974
975 // TODO(asapersson): Not yet used.
976// int32_t rtt =_clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
977// rtt = std::max(rtt, 1);
978
979 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
980}
981
niklase@google.com470e71d2011-07-07 08:21:25 +0000982// no need for critsect we have _criticalSectionRTCPReceiver
983void
984RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
985 RTCPPacketInformation& rtcpPacketInformation)
986{
987 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
988
989 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
990
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000991 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000992 {
993 // Store VoIP metrics block if it's about me
994 // from OriginatorSSRC do we filter it?
995 // rtcpPacket.XR.OriginatorSSRC;
996
997 RTCPVoIPMetric receivedVoIPMetrics;
998 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
999 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
1000 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
1001 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
1002 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
1003 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
1004 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
1005 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
1006 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
1007 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
1008 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
1009 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
1010 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
1011 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
1012 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
1013 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
1014 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
1015 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
1016 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
1017 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
1018
1019 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
1020
1021 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
1022 }
1023 rtcpParser.Iterate();
1024}
1025
1026// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001027void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
1028 RTCPPacketInformation& rtcpPacketInformation) {
1029 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001030 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +00001031 TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
1032
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001033 // Received a signal that we need to send a new key frame.
1034 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
1035 }
1036 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001037}
1038
1039// no need for critsect we have _criticalSectionRTCPReceiver
1040void
1041RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
1042 RTCPPacketInformation& rtcpPacketInformation)
1043{
1044 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1045
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001046 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001047 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
1048 if (ptrReceiveInfo == NULL)
1049 {
1050 // This remote SSRC must be saved before.
1051 rtcpParser.Iterate();
1052 return;
1053 }
1054 if(rtcpPacket.TMMBR.MediaSSRC)
1055 {
1056 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1057 // in relay mode this is a valid number
1058 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1059 }
1060
1061 // Use packet length to calc max number of TMMBR blocks
1062 // each TMMBR block is 8 bytes
1063 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
1064
1065 // sanity
1066 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
1067 {
1068 assert(false);
1069 rtcpParser.Iterate();
1070 return;
1071 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001072 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001073
1074 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1075 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
1076 {
1077 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1078 pktType = rtcpParser.Iterate();
1079 }
1080}
1081
1082// no need for critsect we have _criticalSectionRTCPReceiver
1083void
1084RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1085 const RTCPUtility::RTCPPacket& rtcpPacket,
1086 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001087 const uint32_t senderSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +00001088{
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001089 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
niklase@google.com470e71d2011-07-07 08:21:25 +00001090 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
1091 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +00001092 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001093 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +00001094 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1095 }
1096}
1097
1098// no need for critsect we have _criticalSectionRTCPReceiver
1099void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +00001100RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1101 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +00001102{
1103 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1104 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
1105 if (ptrReceiveInfo == NULL)
1106 {
1107 // This remote SSRC must be saved before.
1108 rtcpParser.Iterate();
1109 return;
1110 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +00001111 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +00001112 // Use packet length to calc max number of TMMBN blocks
1113 // each TMMBN block is 8 bytes
1114 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1115
1116 // sanity
1117 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1118 {
1119 assert(false);
1120 rtcpParser.Iterate();
1121 return;
1122 }
1123
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001124 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001125
1126 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1127 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1128 {
1129 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1130 pktType = rtcpParser.Iterate();
1131 }
1132}
1133
1134// no need for critsect we have _criticalSectionRTCPReceiver
1135void
1136RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1137 RTCPPacketInformation& rtcpPacketInformation)
1138{
1139 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1140 rtcpParser.Iterate();
1141}
1142
1143// no need for critsect we have _criticalSectionRTCPReceiver
1144void
1145RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1146 const RTCPUtility::RTCPPacket& rtcpPacket)
1147{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001148 receiveInfo.TmmbnBoundingSet.AddEntry(
1149 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1150 rtcpPacket.TMMBNItem.MeasuredOverhead,
1151 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001152}
1153
1154// no need for critsect we have _criticalSectionRTCPReceiver
1155void
1156RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1157 RTCPPacketInformation& rtcpPacketInformation)
1158{
1159 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001160 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1161 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1162 {
1163 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1164 pktType = rtcpParser.Iterate();
1165 }
1166}
1167
1168// no need for critsect we have _criticalSectionRTCPReceiver
1169void
1170RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1171 RTCPPacketInformation& rtcpPacketInformation)
1172{
1173 // in theory there could be multiple slices lost
1174 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1175 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1176}
1177
1178void
1179RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1180 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1181{
1182 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001183 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1184 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1185 {
1186 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1187 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1188 {
1189 // to us unknown
1190 // continue
1191 rtcpParser.Iterate();
1192 return;
1193 }
1194 rtcpPacketInformation.rpsiPictureId = 0;
1195
1196 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001197 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1198 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001199 {
1200 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1201 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1202 }
1203 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1204 }
1205}
1206
1207// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001208void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1209 RTCPPacketInformation& rtcpPacketInformation) {
1210 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1211 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1212 pktType = rtcpParser.Iterate();
1213 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1214 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1215 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001216 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001217 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001218}
1219
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001220// no need for critsect we have _criticalSectionRTCPReceiver
1221void
1222RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1223 RTCPPacketInformation& rtcpPacketInformation)
1224{
1225 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1226
1227 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1228 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1229 {
1230 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1231 pktType = rtcpParser.Iterate();
1232 }
1233}
1234
1235void
1236RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1237 RTCPPacketInformation& rtcpPacketInformation)
1238{
1239 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1240 rtcpPacketInformation.interArrivalJitter =
1241 rtcpPacket.ExtendedJitterReportItem.Jitter;
1242}
1243
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001244void RTCPReceiver::HandleREMBItem(
1245 RTCPUtility::RTCPParserV2& rtcpParser,
1246 RTCPPacketInformation& rtcpPacketInformation) {
1247 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1248 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1249 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1250 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001251}
1252
1253// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001254void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1255 RTCPPacketInformation& rtcpPacketInformation) {
1256 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1257 RTCPReceiveInformation* ptrReceiveInfo =
1258 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001259
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001260 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1261 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1262 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1263 pktType = rtcpParser.Iterate();
1264 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001265}
1266
1267// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001268void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1269 const RTCPUtility::RTCPPacket& rtcpPacket,
1270 RTCPPacketInformation& rtcpPacketInformation) {
1271 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001272 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001273 return;
1274 }
1275 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1276 // we don't know who this originate from
1277 if (receiveInfo) {
1278 // check if we have reported this FIRSequenceNumber before
1279 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1280 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001281 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001282 // sanity; don't go crazy with the callbacks
1283 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1284 receiveInfo->lastFIRRequest = now;
1285 receiveInfo->lastFIRSequenceNumber =
1286 rtcpPacket.FIRItem.CommandSequenceNumber;
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 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001291 } else {
1292 // received signal that we need to send a new key frame
1293 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1294 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001295}
1296
1297void
1298RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1299 RTCPPacketInformation& rtcpPacketInformation)
1300{
1301 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1302
1303 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1304 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1305 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1306
1307 rtcpParser.Iterate();
1308}
1309
1310void
1311RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1312 RTCPPacketInformation& rtcpPacketInformation)
1313{
1314 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1315
1316 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1317
1318 rtcpParser.Iterate();
1319}
1320
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001321int32_t RTCPReceiver::UpdateTMMBR() {
1322 int32_t numBoundingSet = 0;
1323 uint32_t bitrate = 0;
1324 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001325
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001326 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001327 if (size > 0) {
1328 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1329 // Get candidate set from receiver.
1330 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1331 } else {
1332 // Candidate set empty.
1333 VerifyAndAllocateCandidateSet(0); // resets candidate set
1334 }
1335 // Find bounding set
1336 TMMBRSet* boundingSet = NULL;
1337 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1338 if (numBoundingSet == -1) {
1339 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1340 "Failed to find TMMBR bounding set.");
1341 return -1;
1342 }
1343 // Set bounding set
1344 // Inform remote clients about the new bandwidth
1345 // inform the remote client
1346 _rtpRtcp.SetTMMBN(boundingSet);
1347
1348 // might trigger a TMMBN
1349 if (numBoundingSet == 0) {
1350 // owner of max bitrate request has timed out
1351 // empty bounding set has been sent
1352 return 0;
1353 }
1354 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001355 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001356 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001357 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1358 if (_cbRtcpBandwidthObserver) {
1359 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1360 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1361 "Set TMMBR request:%d kbps", bitrate);
1362 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001363 }
1364 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001365}
1366
1367// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001368void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001369 RTCPPacketInformation& rtcpPacketInformation) {
1370 // Process TMMBR and REMB first to avoid multiple callbacks
1371 // to OnNetworkChanged.
1372 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1373 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1374 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001375
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001376 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1377 UpdateTMMBR();
1378 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001379 unsigned int local_ssrc = 0;
1380 {
1381 // We don't want to hold this critsect when triggering the callbacks below.
1382 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001383 local_ssrc = main_ssrc_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001384 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001385 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1386 _rtpRtcp.OnRequestSendReport();
1387 }
1388 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001389 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001390 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1391 "SIG [RTCP] Incoming NACK length:%d",
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001392 rtcpPacketInformation.nackSequenceNumbers.size());
1393 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001394 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001395 }
1396 {
1397 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001398
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001399 // We need feedback that we have received a report block(s) so that we
1400 // can generate a new packet in a conference relay scenario, one received
1401 // report can generate several RTCP packets, based on number relayed/mixed
1402 // a send report block should go out to all receivers.
1403 if (_cbRtcpIntraFrameObserver) {
1404 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1405 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1406 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1407 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1408 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1409 rtcpPacketInformation.remoteSSRC);
1410 } else {
1411 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1412 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1413 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001414 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001415 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001416 }
1417 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1418 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001419 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001420 }
1421 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1422 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001423 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001424 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001425 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001426 if (_cbRtcpBandwidthObserver) {
1427 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1428 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1429 "SIG [RTCP] Incoming REMB:%d",
1430 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1431 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1432 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1433 }
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001434 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1435 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001436 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001437 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001438 rtcpPacketInformation.report_blocks,
1439 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001440 now);
1441 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001442 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001443 if(_cbRtcpFeedback) {
solenberg@webrtc.org91811e22013-06-25 20:36:14 +00001444 if(!(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001445 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1446 rtcpPacketInformation.remoteSSRC);
1447 }
1448 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1449 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1450 rtcpPacketInformation.VoIPMetric);
1451 }
1452 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1453 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1454 rtcpPacketInformation.applicationSubType,
1455 rtcpPacketInformation.applicationName,
1456 rtcpPacketInformation.applicationLength,
1457 rtcpPacketInformation.applicationData);
1458 }
1459 }
1460 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001461}
1462
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001463int32_t RTCPReceiver::CNAME(const uint32_t remoteSSRC,
1464 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001465 assert(cName);
1466
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001467 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1468 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001469 if (cnameInfo == NULL) {
1470 return -1;
1471 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001472 cName[RTCP_CNAME_SIZE - 1] = 0;
1473 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1474 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001475}
1476
1477// no callbacks allowed inside this function
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001478int32_t RTCPReceiver::TMMBRReceived(const uint32_t size,
1479 const uint32_t accNumCandidates,
1480 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001481 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001482
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001483 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001484 receiveInfoIt = _receivedInfoMap.begin();
1485 if (receiveInfoIt == _receivedInfoMap.end()) {
1486 return -1;
1487 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001488 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001489 if (candidateSet) {
1490 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1491 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1492 if (receiveInfo == NULL) {
1493 return 0;
1494 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001495 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001496 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001497 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001498 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001499 num++;
1500 }
1501 }
1502 receiveInfoIt++;
1503 }
1504 } else {
1505 while (receiveInfoIt != _receivedInfoMap.end()) {
1506 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1507 if(receiveInfo == NULL) {
1508 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1509 "%s failed to get RTCPReceiveInformation",
1510 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001511 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001512 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001513 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001514 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001515 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001516 }
1517 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001518}
1519
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001520} // namespace webrtc