blob: 0771eba8103c37ab6960e450157ba6603972a4b4 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000011#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <assert.h> //assert
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000014#include <string.h> //memset
niklase@google.com470e71d2011-07-07 08:21:25 +000015
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000016#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
17#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
18#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19#include "webrtc/system_wrappers/interface/trace.h"
20#include "webrtc/system_wrappers/interface/trace_event.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000021
niklase@google.com470e71d2011-07-07 08:21:25 +000022namespace webrtc {
23using namespace RTCPUtility;
24using namespace RTCPHelp;
25
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000026// The number of RTCP time intervals needed to trigger a timeout.
27const int kRrTimeoutIntervals = 3;
28
pbos@webrtc.org2f446732013-04-08 11:08:41 +000029RTCPReceiver::RTCPReceiver(const int32_t id, Clock* clock,
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000030 ModuleRtpRtcpImpl* owner)
31 : TMMBRHelp(),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000032 _id(id),
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +000033 _clock(clock),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000034 _method(kRtcpOff),
35 _lastReceived(0),
36 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000037 _criticalSectionFeedbacks(
38 CriticalSectionWrapper::CreateCriticalSection()),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000039 _cbRtcpFeedback(NULL),
40 _cbRtcpBandwidthObserver(NULL),
41 _cbRtcpIntraFrameObserver(NULL),
42 _criticalSectionRTCPReceiver(
43 CriticalSectionWrapper::CreateCriticalSection()),
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000044 main_ssrc_(0),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000045 _remoteSSRC(0),
46 _remoteSenderInfo(),
47 _lastReceivedSRNTPsecs(0),
48 _lastReceivedSRNTPfrac(0),
49 _receivedInfoMap(),
50 _packetTimeOutMS(0),
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000051 _lastReceivedRrMs(0),
stefan@webrtc.org8ca8a712013-04-23 16:48:32 +000052 _lastIncreasedSequenceNumberMs(0),
53 _rtt(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +000054 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
55 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
56}
57
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000058RTCPReceiver::~RTCPReceiver() {
59 delete _criticalSectionRTCPReceiver;
60 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000061
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000062 while (!_receivedReportBlockMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000063 std::map<uint32_t, RTCPReportBlockInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000064 _receivedReportBlockMap.begin();
65 delete first->second;
66 _receivedReportBlockMap.erase(first);
67 }
68 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000069 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000070 _receivedInfoMap.begin();
71 delete first->second;
72 _receivedInfoMap.erase(first);
73 }
74 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000075 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000076 _receivedCnameMap.begin();
77 delete first->second;
78 _receivedCnameMap.erase(first);
79 }
80 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id,
81 "%s deleted", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +000082}
83
84void
pbos@webrtc.org2f446732013-04-08 11:08:41 +000085RTCPReceiver::ChangeUniqueId(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +000086{
87 _id = id;
88}
89
90RTCPMethod
91RTCPReceiver::Status() const
92{
93 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
94 return _method;
95}
96
pbos@webrtc.org2f446732013-04-08 11:08:41 +000097int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +000098RTCPReceiver::SetRTCPStatus(const RTCPMethod method)
99{
100 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
101 _method = method;
102 return 0;
103}
104
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000105int64_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000106RTCPReceiver::LastReceived()
107{
108 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
109 return _lastReceived;
110}
111
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000112int64_t
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000113RTCPReceiver::LastReceivedReceiverReport() const {
114 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000115 int64_t last_received_rr = -1;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000116 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
117 it != _receivedInfoMap.end(); ++it) {
118 if (it->second->lastTimeReceived > last_received_rr) {
119 last_received_rr = it->second->lastTimeReceived;
120 }
121 }
122 return last_received_rr;
123}
124
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000125int32_t
126RTCPReceiver::SetRemoteSSRC( const uint32_t ssrc)
niklase@google.com470e71d2011-07-07 08:21:25 +0000127{
128 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
129
130 // new SSRC reset old reports
131 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
132 _lastReceivedSRNTPsecs = 0;
133 _lastReceivedSRNTPfrac = 0;
134
135 _remoteSSRC = ssrc;
136 return 0;
137}
138
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000139uint32_t RTCPReceiver::RemoteSSRC() const {
140 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
141 return _remoteSSRC;
142}
143
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000144void RTCPReceiver::RegisterRtcpObservers(
145 RtcpIntraFrameObserver* intra_frame_callback,
146 RtcpBandwidthObserver* bandwidth_callback,
147 RtcpFeedback* feedback_callback) {
148 CriticalSectionScoped lock(_criticalSectionFeedbacks);
149 _cbRtcpIntraFrameObserver = intra_frame_callback;
150 _cbRtcpBandwidthObserver = bandwidth_callback;
151 _cbRtcpFeedback = feedback_callback;
niklase@google.com470e71d2011-07-07 08:21:25 +0000152}
153
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000154void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
155 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000156 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000157 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000158 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000159 old_ssrc = main_ssrc_;
160 main_ssrc_ = main_ssrc;
161 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000162 }
163 {
164 CriticalSectionScoped lock(_criticalSectionFeedbacks);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000165 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
166 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000167 }
168 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000169}
170
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000171int32_t RTCPReceiver::ResetRTT(const uint32_t remoteSSRC) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000172 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
173 RTCPReportBlockInformation* reportBlock =
174 GetReportBlockInformation(remoteSSRC);
175 if (reportBlock == NULL) {
176 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
177 "\tfailed to GetReportBlockInformation(%u)", remoteSSRC);
178 return -1;
179 }
180 reportBlock->RTT = 0;
181 reportBlock->avgRTT = 0;
182 reportBlock->minRTT = 0;
183 reportBlock->maxRTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000184 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000185}
186
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000187int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000188 uint16_t* RTT,
189 uint16_t* avgRTT,
190 uint16_t* minRTT,
191 uint16_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000192 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000193
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000194 RTCPReportBlockInformation* reportBlock =
195 GetReportBlockInformation(remoteSSRC);
196
197 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000198 return -1;
199 }
200 if (RTT) {
201 *RTT = reportBlock->RTT;
202 }
203 if (avgRTT) {
204 *avgRTT = reportBlock->avgRTT;
205 }
206 if (minRTT) {
207 *minRTT = reportBlock->minRTT;
208 }
209 if (maxRTT) {
210 *maxRTT = reportBlock->maxRTT;
211 }
212 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000213}
214
stefan@webrtc.org8ca8a712013-04-23 16:48:32 +0000215uint16_t RTCPReceiver::RTT() const {
216 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
217 if (!_receivedReportBlockMap.empty()) {
218 return 0;
219 }
220 return _rtt;
221}
222
223int RTCPReceiver::SetRTT(uint16_t rtt) {
224 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
225 if (!_receivedReportBlockMap.empty()) {
226 return -1;
227 }
228 _rtt = rtt;
229 return 0;
230}
231
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000232int32_t
233RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs,
234 uint32_t *ReceivedNTPfrac,
235 uint32_t *RTCPArrivalTimeSecs,
236 uint32_t *RTCPArrivalTimeFrac,
237 uint32_t *rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000238{
239 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
240 if(ReceivedNTPsecs)
241 {
242 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
243 }
244 if(ReceivedNTPfrac)
245 {
246 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
247 }
248 if(RTCPArrivalTimeFrac)
249 {
250 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
251 }
252 if(RTCPArrivalTimeSecs)
253 {
254 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
255 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000256 if (rtcp_timestamp) {
257 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
258 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000259 return 0;
260}
261
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000262int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000263RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
264{
265 if(senderInfo == NULL)
266 {
267 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
268 return -1;
269 }
270 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
271 if(_lastReceivedSRNTPsecs == 0)
272 {
273 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
274 return -1;
275 }
276 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
277 return 0;
278}
279
280// statistics
281// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000282int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000283 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000284 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000285 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
286
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000287 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000288 _receivedReportBlockMap.begin();
289
290 while (it != _receivedReportBlockMap.end()) {
291 receiveBlocks->push_back(it->second->remoteReceiveBlock);
292 it++;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000293 }
294 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000295}
296
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000297int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000298RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
299 RTCPUtility::RTCPParserV2* rtcpParser)
300{
301 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
302
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000303 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000304
305 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
306 while (pktType != RTCPUtility::kRtcpNotValidCode)
307 {
308 // Each "case" is responsible for iterate the parser to the
309 // next top level packet.
310 switch (pktType)
311 {
312 case RTCPUtility::kRtcpSrCode:
313 case RTCPUtility::kRtcpRrCode:
314 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
315 break;
316 case RTCPUtility::kRtcpSdesCode:
317 HandleSDES(*rtcpParser);
318 break;
319 case RTCPUtility::kRtcpXrVoipMetricCode:
320 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
321 break;
322 case RTCPUtility::kRtcpByeCode:
323 HandleBYE(*rtcpParser);
324 break;
325 case RTCPUtility::kRtcpRtpfbNackCode:
326 HandleNACK(*rtcpParser, rtcpPacketInformation);
327 break;
328 case RTCPUtility::kRtcpRtpfbTmmbrCode:
329 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
330 break;
331 case RTCPUtility::kRtcpRtpfbTmmbnCode:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000332 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 break;
334 case RTCPUtility::kRtcpRtpfbSrReqCode:
335 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
336 break;
337 case RTCPUtility::kRtcpPsfbPliCode:
338 HandlePLI(*rtcpParser, rtcpPacketInformation);
339 break;
340 case RTCPUtility::kRtcpPsfbSliCode:
341 HandleSLI(*rtcpParser, rtcpPacketInformation);
342 break;
343 case RTCPUtility::kRtcpPsfbRpsiCode:
344 HandleRPSI(*rtcpParser, rtcpPacketInformation);
345 break;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000346 case RTCPUtility::kRtcpExtendedIjCode:
347 HandleIJ(*rtcpParser, rtcpPacketInformation);
348 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000349 case RTCPUtility::kRtcpPsfbFirCode:
350 HandleFIR(*rtcpParser, rtcpPacketInformation);
351 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000352 case RTCPUtility::kRtcpPsfbAppCode:
353 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
354 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000355 case RTCPUtility::kRtcpAppCode:
356 // generic application messages
357 HandleAPP(*rtcpParser, rtcpPacketInformation);
358 break;
359 case RTCPUtility::kRtcpAppItemCode:
360 // generic application messages
361 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
362 break;
363 default:
364 rtcpParser->Iterate();
365 break;
366 }
367 pktType = rtcpParser->PacketType();
368 }
369 return 0;
370}
371
372// no need for critsect we have _criticalSectionRTCPReceiver
373void
374RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
375 RTCPPacketInformation& rtcpPacketInformation)
376{
377 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
378 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
379
380 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
381
382 // SR.SenderSSRC
383 // The synchronization source identifier for the originator of this SR packet
384
385 // rtcpPacket.RR.SenderSSRC
386 // The source of the packet sender, same as of SR? or is this a CE?
387
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000388 const uint32_t remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
389 const uint8_t numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
niklase@google.com470e71d2011-07-07 08:21:25 +0000390
391 rtcpPacketInformation.remoteSSRC = remoteSSRC;
392
393 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
394 if (!ptrReceiveInfo)
395 {
396 rtcpParser.Iterate();
397 return;
398 }
399
400 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
401 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000402 TRACE_EVENT_INSTANT2("webrtc_rtp", "SR",
403 "remote_ssrc", remoteSSRC,
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000404 "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000405
niklase@google.com470e71d2011-07-07 08:21:25 +0000406 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
407 {
408 // only signal that we have received a SR when we accept one
409 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
410
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000411 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
412 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
413 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
414
niklase@google.com470e71d2011-07-07 08:21:25 +0000415 // We will only store the send report from one source, but
416 // we will store all the receive block
417
418 // Save the NTP time of this report
419 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
420 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
421 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
422 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
423 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
424
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000425 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000426 }
427 else
428 {
429 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
430 }
431 } else
432 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000433 TRACE_EVENT_INSTANT2("webrtc_rtp", "RR",
434 "remote_ssrc", remoteSSRC,
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000435 "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000436
437 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
438 }
439 UpdateReceiveInformation(*ptrReceiveInfo);
440
441 rtcpPacketType = rtcpParser.Iterate();
442
443 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
444 {
445 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
446 rtcpPacketType = rtcpParser.Iterate();
447 }
448}
449
450// no need for critsect we have _criticalSectionRTCPReceiver
451void
452RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
453 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000454 const uint32_t remoteSSRC,
455 const uint8_t numberOfReportBlocks) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000456 // This will be called once per report block in the RTCP packet.
457 // We filter out all report blocks that are not for us.
458 // Each packet has max 31 RR blocks.
459 //
460 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000461
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000462 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
463 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000464
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000465 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000466 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
467 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000468 // This block is not for us ignore it.
469 return;
470 }
471
472 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
473 // _criticalSectionRTCPReceiver.
474 _criticalSectionRTCPReceiver->Leave();
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000475 uint32_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000476 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
477 _criticalSectionRTCPReceiver->Enter();
478
479 RTCPReportBlockInformation* reportBlock =
480 CreateReportBlockInformation(remoteSSRC);
481 if (reportBlock == NULL) {
482 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
483 "\tfailed to CreateReportBlockInformation(%u)", remoteSSRC);
484 return;
485 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000486
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000487 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000488 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
489 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
490 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
491 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
492 reportBlock->remoteReceiveBlock.cumulativeLost =
493 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000494 if (rb.ExtendedHighestSequenceNumber >
495 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
496 // We have successfully delivered new RTP packets to the remote side after
497 // the last RR was sent from the remote side.
498 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000499 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000500 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
501 rb.ExtendedHighestSequenceNumber;
502 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
503 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
504 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
505
506 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
507 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
508 }
509
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000510 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000511 rtcpPacket.ReportBlockItem.DelayLastSR;
512
513 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000514 uint32_t lastReceivedRRNTPsecs = 0;
515 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000516
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000517 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000518
519 // time when we received this in MS
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000520 uint32_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
521 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000522
523 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000524 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000525 d /= 65536;
526 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
527
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000528 int32_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000529
530 if (sendTimeMS > 0) {
531 RTT = receiveTimeMS - d - sendTimeMS;
532 if (RTT <= 0) {
533 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000534 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000535 if (RTT > reportBlock->maxRTT) {
536 // store max RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000537 reportBlock->maxRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000538 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000539 if (reportBlock->minRTT == 0) {
540 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000541 reportBlock->minRTT = (uint16_t) RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000542 } else if (RTT < reportBlock->minRTT) {
543 // Store min RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000544 reportBlock->minRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000545 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000546 // store last RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000547 reportBlock->RTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000548
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000549 // store average RTT
550 if (reportBlock->numAverageCalcs != 0) {
551 float ac = static_cast<float> (reportBlock->numAverageCalcs);
552 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
553 + ((1 / (ac + 1)) * RTT);
554 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
555 } else {
556 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000557 reportBlock->avgRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000558 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000559 reportBlock->numAverageCalcs++;
560 }
561
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000562 TRACE_COUNTER_ID1("webrtc_rtp", "RR_RTT", rb.SSRC, RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000563
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000564 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000565}
566
567RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000568RTCPReceiver::CreateReportBlockInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000569 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000570
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000571 std::map<uint32_t, RTCPReportBlockInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000572 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000573
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000574 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
575 if (it != _receivedReportBlockMap.end()) {
576 ptrReportBlockInfo = it->second;
577 } else {
578 ptrReportBlockInfo = new RTCPReportBlockInformation;
579 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
580 }
581 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000582}
583
584RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000585RTCPReceiver::GetReportBlockInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000586 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000587
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000588 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000589 _receivedReportBlockMap.find(remoteSSRC);
590
591 if (it == _receivedReportBlockMap.end()) {
592 return NULL;
593 }
594 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000595}
596
597RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000598RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000599 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000600
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000601 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000602 _receivedCnameMap.find(remoteSSRC);
603
604 if (it != _receivedCnameMap.end()) {
605 return it->second;
606 }
607 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000608 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000609 _receivedCnameMap[remoteSSRC] = cnameInfo;
610 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000611}
612
613RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000614RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000615 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000616
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000617 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000618 _receivedCnameMap.find(remoteSSRC);
619
620 if (it == _receivedCnameMap.end()) {
621 return NULL;
622 }
623 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000624}
625
626RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000627RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000628 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000629
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000630 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000631 _receivedInfoMap.find(remoteSSRC);
632
633 if (it != _receivedInfoMap.end()) {
634 return it->second;
635 }
636 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
637 _receivedInfoMap[remoteSSRC] = receiveInfo;
638 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000639}
640
641RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000642RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000643 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000644
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000645 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000646 _receivedInfoMap.find(remoteSSRC);
647 if (it == _receivedInfoMap.end()) {
648 return NULL;
649 }
650 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000651}
652
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000653void RTCPReceiver::UpdateReceiveInformation(
654 RTCPReceiveInformation& receiveInformation) {
655 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000656 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000657}
658
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000659bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
660 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
661 if (_lastReceivedRrMs == 0)
662 return false;
663
664 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000665 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000666 // Reset the timer to only trigger one log.
667 _lastReceivedRrMs = 0;
668 return true;
669 }
670 return false;
671}
672
673bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
674 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
675 if (_lastIncreasedSequenceNumberMs == 0)
676 return false;
677
678 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000679 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000680 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000681 // Reset the timer to only trigger one log.
682 _lastIncreasedSequenceNumberMs = 0;
683 return true;
684 }
685 return false;
686}
687
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000688bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
689 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000690
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000691 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000692 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000693
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000694 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000695 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000696
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000697 while (receiveInfoIt != _receivedInfoMap.end()) {
698 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
699 if (receiveInfo == NULL) {
700 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000701 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000702 // time since last received rtcp packet
703 // when we dont have a lastTimeReceived and the object is marked
704 // readyForDelete it's removed from the map
705 if (receiveInfo->lastTimeReceived) {
706 /// use audio define since we don't know what interval the remote peer is
707 // using
708 if ((timeNow - receiveInfo->lastTimeReceived) >
709 5 * RTCP_INTERVAL_AUDIO_MS) {
710 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000711 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000712 // prevent that we call this over and over again
713 receiveInfo->lastTimeReceived = 0;
714 // send new TMMBN to all channels using the default codec
715 updateBoundingSet = true;
716 }
717 receiveInfoIt++;
718 } else if (receiveInfo->readyForDelete) {
719 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000720 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000721 receiveInfoItemToBeErased = receiveInfoIt;
722 receiveInfoIt++;
723 delete receiveInfoItemToBeErased->second;
724 _receivedInfoMap.erase(receiveInfoItemToBeErased);
725 } else {
726 receiveInfoIt++;
727 }
728 }
729 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000730}
731
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000732int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000733 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000734
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000735 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000736 _receivedInfoMap.find(_remoteSSRC);
737
738 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000739 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000740 }
741 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
742 if (receiveInfo == NULL) {
743 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
744 "%s failed to get RTCPReceiveInformation",
745 __FUNCTION__);
746 return -1;
747 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000748 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000749 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000750 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000751 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000752 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000753 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000754 // owner of bounding set
755 tmmbrOwner = true;
756 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000757 boundingSetRec->SetEntry(i,
758 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
759 receiveInfo->TmmbnBoundingSet.PacketOH(i),
760 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000761 }
762 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000763 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000764}
765
766// no need for critsect we have _criticalSectionRTCPReceiver
767void
768RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
769{
770 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
771 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
772 {
773 HandleSDESChunk(rtcpParser);
774 pktType = rtcpParser.Iterate();
775 }
776}
777
778// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000779void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
780 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
781 RTCPCnameInformation* cnameInfo =
782 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
783 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000784
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000785 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
786 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000787}
788
789// no need for critsect we have _criticalSectionRTCPReceiver
790void
791RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
792 RTCPPacketInformation& rtcpPacketInformation)
793{
794 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000795 if (main_ssrc_ != rtcpPacket.NACK.MediaSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000796 {
797 // Not to us.
798 rtcpParser.Iterate();
799 return;
800 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000801 rtcpPacketInformation.ResetNACKPacketIdArray();
802
803 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
804 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
805 {
806 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
807 pktType = rtcpParser.Iterate();
808 }
809}
810
811// no need for critsect we have _criticalSectionRTCPReceiver
812void
813RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
814 RTCPPacketInformation& rtcpPacketInformation)
815{
816 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
817
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000818 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
niklase@google.com470e71d2011-07-07 08:21:25 +0000819 if(bitMask)
820 {
821 for(int i=1; i <= 16; ++i)
822 {
823 if(bitMask & 0x01)
824 {
825 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
826 }
827 bitMask = bitMask >>1;
828 }
829 }
830
831 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
832}
833
834// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000835void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
836 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000837
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000838 // clear our lists
839 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000840 std::map<uint32_t, RTCPReportBlockInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000841 reportBlockInfoIt = _receivedReportBlockMap.find(
842 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000843
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000844 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
845 delete reportBlockInfoIt->second;
846 _receivedReportBlockMap.erase(reportBlockInfoIt);
847 }
848 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000849 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000850 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000851
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000852 if (receiveInfoIt != _receivedInfoMap.end()) {
853 receiveInfoIt->second->readyForDelete = true;
854 }
855
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000856 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000857 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
858
859 if (cnameInfoIt != _receivedCnameMap.end()) {
860 delete cnameInfoIt->second;
861 _receivedCnameMap.erase(cnameInfoIt);
862 }
863 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000864}
865
866// no need for critsect we have _criticalSectionRTCPReceiver
867void
868RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
869 RTCPPacketInformation& rtcpPacketInformation)
870{
871 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
872
873 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
874
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000875 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000876 {
877 // Store VoIP metrics block if it's about me
878 // from OriginatorSSRC do we filter it?
879 // rtcpPacket.XR.OriginatorSSRC;
880
881 RTCPVoIPMetric receivedVoIPMetrics;
882 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
883 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
884 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
885 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
886 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
887 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
888 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
889 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
890 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
891 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
892 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
893 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
894 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
895 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
896 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
897 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
898 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
899 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
900 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
901 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
902
903 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
904
905 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
906 }
907 rtcpParser.Iterate();
908}
909
910// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000911void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
912 RTCPPacketInformation& rtcpPacketInformation) {
913 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000914 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000915 TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
916
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000917 // Received a signal that we need to send a new key frame.
918 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
919 }
920 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000921}
922
923// no need for critsect we have _criticalSectionRTCPReceiver
924void
925RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
926 RTCPPacketInformation& rtcpPacketInformation)
927{
928 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
929
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000930 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000931 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
932 if (ptrReceiveInfo == NULL)
933 {
934 // This remote SSRC must be saved before.
935 rtcpParser.Iterate();
936 return;
937 }
938 if(rtcpPacket.TMMBR.MediaSSRC)
939 {
940 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
941 // in relay mode this is a valid number
942 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
943 }
944
945 // Use packet length to calc max number of TMMBR blocks
946 // each TMMBR block is 8 bytes
947 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
948
949 // sanity
950 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
951 {
952 assert(false);
953 rtcpParser.Iterate();
954 return;
955 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000956 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +0000957
958 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
959 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
960 {
961 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
962 pktType = rtcpParser.Iterate();
963 }
964}
965
966// no need for critsect we have _criticalSectionRTCPReceiver
967void
968RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
969 const RTCPUtility::RTCPPacket& rtcpPacket,
970 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000971 const uint32_t senderSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000972{
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000973 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
niklase@google.com470e71d2011-07-07 08:21:25 +0000974 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
975 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000976 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000977 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +0000978 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
979 }
980}
981
982// no need for critsect we have _criticalSectionRTCPReceiver
983void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000984RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
985 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +0000986{
987 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
988 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
989 if (ptrReceiveInfo == NULL)
990 {
991 // This remote SSRC must be saved before.
992 rtcpParser.Iterate();
993 return;
994 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000995 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +0000996 // Use packet length to calc max number of TMMBN blocks
997 // each TMMBN block is 8 bytes
998 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
999
1000 // sanity
1001 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1002 {
1003 assert(false);
1004 rtcpParser.Iterate();
1005 return;
1006 }
1007
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001008 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001009
1010 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1011 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1012 {
1013 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1014 pktType = rtcpParser.Iterate();
1015 }
1016}
1017
1018// no need for critsect we have _criticalSectionRTCPReceiver
1019void
1020RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1021 RTCPPacketInformation& rtcpPacketInformation)
1022{
1023 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1024 rtcpParser.Iterate();
1025}
1026
1027// no need for critsect we have _criticalSectionRTCPReceiver
1028void
1029RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1030 const RTCPUtility::RTCPPacket& rtcpPacket)
1031{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001032 receiveInfo.TmmbnBoundingSet.AddEntry(
1033 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1034 rtcpPacket.TMMBNItem.MeasuredOverhead,
1035 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001036}
1037
1038// no need for critsect we have _criticalSectionRTCPReceiver
1039void
1040RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1041 RTCPPacketInformation& rtcpPacketInformation)
1042{
1043 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001044 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1045 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1046 {
1047 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1048 pktType = rtcpParser.Iterate();
1049 }
1050}
1051
1052// no need for critsect we have _criticalSectionRTCPReceiver
1053void
1054RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1055 RTCPPacketInformation& rtcpPacketInformation)
1056{
1057 // in theory there could be multiple slices lost
1058 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1059 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1060}
1061
1062void
1063RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1064 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1065{
1066 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001067 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1068 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1069 {
1070 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1071 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1072 {
1073 // to us unknown
1074 // continue
1075 rtcpParser.Iterate();
1076 return;
1077 }
1078 rtcpPacketInformation.rpsiPictureId = 0;
1079
1080 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001081 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1082 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001083 {
1084 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1085 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1086 }
1087 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1088 }
1089}
1090
1091// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001092void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1093 RTCPPacketInformation& rtcpPacketInformation) {
1094 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1095 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1096 pktType = rtcpParser.Iterate();
1097 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1098 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1099 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001100 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001101 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001102}
1103
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001104// no need for critsect we have _criticalSectionRTCPReceiver
1105void
1106RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1107 RTCPPacketInformation& rtcpPacketInformation)
1108{
1109 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1110
1111 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1112 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1113 {
1114 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1115 pktType = rtcpParser.Iterate();
1116 }
1117}
1118
1119void
1120RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1121 RTCPPacketInformation& rtcpPacketInformation)
1122{
1123 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1124 rtcpPacketInformation.interArrivalJitter =
1125 rtcpPacket.ExtendedJitterReportItem.Jitter;
1126}
1127
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001128void RTCPReceiver::HandleREMBItem(
1129 RTCPUtility::RTCPParserV2& rtcpParser,
1130 RTCPPacketInformation& rtcpPacketInformation) {
1131 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1132 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1133 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1134 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001135}
1136
1137// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001138void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1139 RTCPPacketInformation& rtcpPacketInformation) {
1140 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1141 RTCPReceiveInformation* ptrReceiveInfo =
1142 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001143
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001144 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1145 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1146 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1147 pktType = rtcpParser.Iterate();
1148 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001149}
1150
1151// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001152void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1153 const RTCPUtility::RTCPPacket& rtcpPacket,
1154 RTCPPacketInformation& rtcpPacketInformation) {
1155 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001156 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001157 return;
1158 }
1159 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1160 // we don't know who this originate from
1161 if (receiveInfo) {
1162 // check if we have reported this FIRSequenceNumber before
1163 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1164 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001165 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001166 // sanity; don't go crazy with the callbacks
1167 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1168 receiveInfo->lastFIRRequest = now;
1169 receiveInfo->lastFIRSequenceNumber =
1170 rtcpPacket.FIRItem.CommandSequenceNumber;
1171 // received signal that we need to send a new key frame
1172 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1173 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001174 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001175 } else {
1176 // received signal that we need to send a new key frame
1177 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1178 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001179}
1180
1181void
1182RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1183 RTCPPacketInformation& rtcpPacketInformation)
1184{
1185 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1186
1187 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1188 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1189 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1190
1191 rtcpParser.Iterate();
1192}
1193
1194void
1195RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1196 RTCPPacketInformation& rtcpPacketInformation)
1197{
1198 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1199
1200 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1201
1202 rtcpParser.Iterate();
1203}
1204
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001205int32_t RTCPReceiver::UpdateTMMBR() {
1206 int32_t numBoundingSet = 0;
1207 uint32_t bitrate = 0;
1208 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001209
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001210 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001211 if (size > 0) {
1212 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1213 // Get candidate set from receiver.
1214 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1215 } else {
1216 // Candidate set empty.
1217 VerifyAndAllocateCandidateSet(0); // resets candidate set
1218 }
1219 // Find bounding set
1220 TMMBRSet* boundingSet = NULL;
1221 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1222 if (numBoundingSet == -1) {
1223 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1224 "Failed to find TMMBR bounding set.");
1225 return -1;
1226 }
1227 // Set bounding set
1228 // Inform remote clients about the new bandwidth
1229 // inform the remote client
1230 _rtpRtcp.SetTMMBN(boundingSet);
1231
1232 // might trigger a TMMBN
1233 if (numBoundingSet == 0) {
1234 // owner of max bitrate request has timed out
1235 // empty bounding set has been sent
1236 return 0;
1237 }
1238 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001239 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001240 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001241 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1242 if (_cbRtcpBandwidthObserver) {
1243 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1244 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1245 "Set TMMBR request:%d kbps", bitrate);
1246 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001247 }
1248 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001249}
1250
1251// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001252void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001253 RTCPPacketInformation& rtcpPacketInformation) {
1254 // Process TMMBR and REMB first to avoid multiple callbacks
1255 // to OnNetworkChanged.
1256 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1257 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1258 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001259
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001260 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1261 UpdateTMMBR();
1262 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001263 unsigned int local_ssrc = 0;
1264 {
1265 // We don't want to hold this critsect when triggering the callbacks below.
1266 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001267 local_ssrc = main_ssrc_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001268 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001269 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1270 _rtpRtcp.OnRequestSendReport();
1271 }
1272 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001273 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001274 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1275 "SIG [RTCP] Incoming NACK length:%d",
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001276 rtcpPacketInformation.nackSequenceNumbers.size());
1277 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001278 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001279 }
1280 {
1281 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001282
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001283 // We need feedback that we have received a report block(s) so that we
1284 // can generate a new packet in a conference relay scenario, one received
1285 // report can generate several RTCP packets, based on number relayed/mixed
1286 // a send report block should go out to all receivers.
1287 if (_cbRtcpIntraFrameObserver) {
1288 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1289 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1290 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1291 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1292 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1293 rtcpPacketInformation.remoteSSRC);
1294 } else {
1295 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1296 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1297 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001298 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001299 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001300 }
1301 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1302 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001303 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001304 }
1305 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1306 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001307 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001308 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001309 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001310 if (_cbRtcpBandwidthObserver) {
1311 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1312 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1313 "SIG [RTCP] Incoming REMB:%d",
1314 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1315 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1316 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1317 }
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001318 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1319 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001320 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001321 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001322 rtcpPacketInformation.report_blocks,
1323 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001324 now);
1325 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001326 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001327 if(_cbRtcpFeedback) {
solenberg@webrtc.org91811e22013-06-25 20:36:14 +00001328 if(!(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001329 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1330 rtcpPacketInformation.remoteSSRC);
1331 }
1332 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1333 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1334 rtcpPacketInformation.VoIPMetric);
1335 }
1336 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1337 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1338 rtcpPacketInformation.applicationSubType,
1339 rtcpPacketInformation.applicationName,
1340 rtcpPacketInformation.applicationLength,
1341 rtcpPacketInformation.applicationData);
1342 }
1343 }
1344 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001345}
1346
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001347int32_t RTCPReceiver::CNAME(const uint32_t remoteSSRC,
1348 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001349 assert(cName);
1350
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001351 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1352 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001353 if (cnameInfo == NULL) {
1354 return -1;
1355 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001356 cName[RTCP_CNAME_SIZE - 1] = 0;
1357 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1358 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001359}
1360
1361// no callbacks allowed inside this function
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001362int32_t RTCPReceiver::TMMBRReceived(const uint32_t size,
1363 const uint32_t accNumCandidates,
1364 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001365 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001366
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001367 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001368 receiveInfoIt = _receivedInfoMap.begin();
1369 if (receiveInfoIt == _receivedInfoMap.end()) {
1370 return -1;
1371 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001372 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001373 if (candidateSet) {
1374 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1375 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1376 if (receiveInfo == NULL) {
1377 return 0;
1378 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001379 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001380 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001381 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001382 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001383 num++;
1384 }
1385 }
1386 receiveInfoIt++;
1387 }
1388 } else {
1389 while (receiveInfoIt != _receivedInfoMap.end()) {
1390 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1391 if(receiveInfo == NULL) {
1392 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1393 "%s failed to get RTCPReceiveInformation",
1394 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001395 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001396 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001397 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001398 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001399 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001400 }
1401 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001402}
1403
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001404} // namespace webrtc