blob: 871a089a8348d9c970a59d3e6f65ce077bded05e [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000011#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
pbos@webrtc.org12dc1a32013-08-05 16:22:53 +000013#include <assert.h> //assert
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000014#include <string.h> //memset
niklase@google.com470e71d2011-07-07 08:21:25 +000015
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000016#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
17#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
18#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19#include "webrtc/system_wrappers/interface/trace.h"
20#include "webrtc/system_wrappers/interface/trace_event.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000021
22namespace
23{
24 const float FRAC = 4.294967296E9;
25}
26
27namespace webrtc {
28using namespace RTCPUtility;
29using namespace RTCPHelp;
30
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000031// The number of RTCP time intervals needed to trigger a timeout.
32const int kRrTimeoutIntervals = 3;
33
pbos@webrtc.org2f446732013-04-08 11:08:41 +000034RTCPReceiver::RTCPReceiver(const int32_t id, Clock* clock,
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000035 ModuleRtpRtcpImpl* owner)
36 : TMMBRHelp(),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000037 _id(id),
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +000038 _clock(clock),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000039 _method(kRtcpOff),
40 _lastReceived(0),
41 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000042 _criticalSectionFeedbacks(
43 CriticalSectionWrapper::CreateCriticalSection()),
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +000044 _cbRtcpFeedback(NULL),
45 _cbRtcpBandwidthObserver(NULL),
46 _cbRtcpIntraFrameObserver(NULL),
47 _criticalSectionRTCPReceiver(
48 CriticalSectionWrapper::CreateCriticalSection()),
49 _SSRC(0),
50 _remoteSSRC(0),
51 _remoteSenderInfo(),
52 _lastReceivedSRNTPsecs(0),
53 _lastReceivedSRNTPfrac(0),
54 _receivedInfoMap(),
55 _packetTimeOutMS(0),
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000056 _lastReceivedRrMs(0),
stefan@webrtc.org8ca8a712013-04-23 16:48:32 +000057 _lastIncreasedSequenceNumberMs(0),
58 _rtt(0) {
niklase@google.com470e71d2011-07-07 08:21:25 +000059 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
60 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
61}
62
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000063RTCPReceiver::~RTCPReceiver() {
64 delete _criticalSectionRTCPReceiver;
65 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000066
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000067 while (!_receivedReportBlockMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000068 std::map<uint32_t, RTCPReportBlockInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000069 _receivedReportBlockMap.begin();
70 delete first->second;
71 _receivedReportBlockMap.erase(first);
72 }
73 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000074 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000075 _receivedInfoMap.begin();
76 delete first->second;
77 _receivedInfoMap.erase(first);
78 }
79 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000080 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000081 _receivedCnameMap.begin();
82 delete first->second;
83 _receivedCnameMap.erase(first);
84 }
85 WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, _id,
86 "%s deleted", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +000087}
88
89void
pbos@webrtc.org2f446732013-04-08 11:08:41 +000090RTCPReceiver::ChangeUniqueId(const int32_t id)
niklase@google.com470e71d2011-07-07 08:21:25 +000091{
92 _id = id;
93}
94
95RTCPMethod
96RTCPReceiver::Status() const
97{
98 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
99 return _method;
100}
101
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000102int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000103RTCPReceiver::SetRTCPStatus(const RTCPMethod method)
104{
105 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
106 _method = method;
107 return 0;
108}
109
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000110int64_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000111RTCPReceiver::LastReceived()
112{
113 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
114 return _lastReceived;
115}
116
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000117int64_t
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000118RTCPReceiver::LastReceivedReceiverReport() const {
119 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000120 int64_t last_received_rr = -1;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000121 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
122 it != _receivedInfoMap.end(); ++it) {
123 if (it->second->lastTimeReceived > last_received_rr) {
124 last_received_rr = it->second->lastTimeReceived;
125 }
126 }
127 return last_received_rr;
128}
129
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000130int32_t
131RTCPReceiver::SetRemoteSSRC( const uint32_t ssrc)
niklase@google.com470e71d2011-07-07 08:21:25 +0000132{
133 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
134
135 // new SSRC reset old reports
136 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
137 _lastReceivedSRNTPsecs = 0;
138 _lastReceivedSRNTPfrac = 0;
139
140 _remoteSSRC = ssrc;
141 return 0;
142}
143
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
niklase@google.com470e71d2011-07-07 08:21:25 +0000154
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000155void RTCPReceiver::SetSSRC(const uint32_t ssrc) {
156 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);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000159 old_ssrc = _SSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000160 _SSRC = ssrc;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000161 }
162 {
163 CriticalSectionScoped lock(_criticalSectionFeedbacks);
164 if (_cbRtcpIntraFrameObserver && old_ssrc != ssrc) {
165 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, ssrc);
166 }
167 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000168}
169
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000170int32_t RTCPReceiver::ResetRTT(const uint32_t remoteSSRC) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000171 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
172 RTCPReportBlockInformation* reportBlock =
173 GetReportBlockInformation(remoteSSRC);
174 if (reportBlock == NULL) {
175 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
176 "\tfailed to GetReportBlockInformation(%u)", remoteSSRC);
177 return -1;
178 }
179 reportBlock->RTT = 0;
180 reportBlock->avgRTT = 0;
181 reportBlock->minRTT = 0;
182 reportBlock->maxRTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000183 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000184}
185
tnakamura@webrtc.orgaa4d96a2013-07-16 19:25:04 +0000186int32_t RTCPReceiver::RTT(const uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000187 uint16_t* RTT,
188 uint16_t* avgRTT,
189 uint16_t* minRTT,
190 uint16_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000191 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000192
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000193 RTCPReportBlockInformation* reportBlock =
194 GetReportBlockInformation(remoteSSRC);
195
196 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000197 return -1;
198 }
199 if (RTT) {
200 *RTT = reportBlock->RTT;
201 }
202 if (avgRTT) {
203 *avgRTT = reportBlock->avgRTT;
204 }
205 if (minRTT) {
206 *minRTT = reportBlock->minRTT;
207 }
208 if (maxRTT) {
209 *maxRTT = reportBlock->maxRTT;
210 }
211 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000212}
213
stefan@webrtc.org8ca8a712013-04-23 16:48:32 +0000214uint16_t RTCPReceiver::RTT() const {
215 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
216 if (!_receivedReportBlockMap.empty()) {
217 return 0;
218 }
219 return _rtt;
220}
221
222int RTCPReceiver::SetRTT(uint16_t rtt) {
223 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
224 if (!_receivedReportBlockMap.empty()) {
225 return -1;
226 }
227 _rtt = rtt;
228 return 0;
229}
230
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000231int32_t
232RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs,
233 uint32_t *ReceivedNTPfrac,
234 uint32_t *RTCPArrivalTimeSecs,
235 uint32_t *RTCPArrivalTimeFrac,
236 uint32_t *rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000237{
238 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
239 if(ReceivedNTPsecs)
240 {
241 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
242 }
243 if(ReceivedNTPfrac)
244 {
245 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
246 }
247 if(RTCPArrivalTimeFrac)
248 {
249 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
250 }
251 if(RTCPArrivalTimeSecs)
252 {
253 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
254 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000255 if (rtcp_timestamp) {
256 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
257 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000258 return 0;
259}
260
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000261int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000262RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const
263{
264 if(senderInfo == NULL)
265 {
266 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id, "%s invalid argument", __FUNCTION__);
267 return -1;
268 }
269 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
270 if(_lastReceivedSRNTPsecs == 0)
271 {
272 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id, "%s No received SR", __FUNCTION__);
273 return -1;
274 }
275 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
276 return 0;
277}
278
279// statistics
280// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000281int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000282 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000283 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000284 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
285
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000286 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000287 _receivedReportBlockMap.begin();
288
289 while (it != _receivedReportBlockMap.end()) {
290 receiveBlocks->push_back(it->second->remoteReceiveBlock);
291 it++;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000292 }
293 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000294}
295
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000296int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000297RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
298 RTCPUtility::RTCPParserV2* rtcpParser)
299{
300 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
301
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000302 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000303
304 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
305 while (pktType != RTCPUtility::kRtcpNotValidCode)
306 {
307 // Each "case" is responsible for iterate the parser to the
308 // next top level packet.
309 switch (pktType)
310 {
311 case RTCPUtility::kRtcpSrCode:
312 case RTCPUtility::kRtcpRrCode:
313 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
314 break;
315 case RTCPUtility::kRtcpSdesCode:
316 HandleSDES(*rtcpParser);
317 break;
318 case RTCPUtility::kRtcpXrVoipMetricCode:
319 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
320 break;
321 case RTCPUtility::kRtcpByeCode:
322 HandleBYE(*rtcpParser);
323 break;
324 case RTCPUtility::kRtcpRtpfbNackCode:
325 HandleNACK(*rtcpParser, rtcpPacketInformation);
326 break;
327 case RTCPUtility::kRtcpRtpfbTmmbrCode:
328 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
329 break;
330 case RTCPUtility::kRtcpRtpfbTmmbnCode:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000331 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000332 break;
333 case RTCPUtility::kRtcpRtpfbSrReqCode:
334 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
335 break;
336 case RTCPUtility::kRtcpPsfbPliCode:
337 HandlePLI(*rtcpParser, rtcpPacketInformation);
338 break;
339 case RTCPUtility::kRtcpPsfbSliCode:
340 HandleSLI(*rtcpParser, rtcpPacketInformation);
341 break;
342 case RTCPUtility::kRtcpPsfbRpsiCode:
343 HandleRPSI(*rtcpParser, rtcpPacketInformation);
344 break;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000345 case RTCPUtility::kRtcpExtendedIjCode:
346 HandleIJ(*rtcpParser, rtcpPacketInformation);
347 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000348 case RTCPUtility::kRtcpPsfbFirCode:
349 HandleFIR(*rtcpParser, rtcpPacketInformation);
350 break;
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000351 case RTCPUtility::kRtcpPsfbAppCode:
352 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
353 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000354 case RTCPUtility::kRtcpAppCode:
355 // generic application messages
356 HandleAPP(*rtcpParser, rtcpPacketInformation);
357 break;
358 case RTCPUtility::kRtcpAppItemCode:
359 // generic application messages
360 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
361 break;
362 default:
363 rtcpParser->Iterate();
364 break;
365 }
366 pktType = rtcpParser->PacketType();
367 }
368 return 0;
369}
370
371// no need for critsect we have _criticalSectionRTCPReceiver
372void
373RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
374 RTCPPacketInformation& rtcpPacketInformation)
375{
376 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
377 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
378
379 assert((rtcpPacketType == RTCPUtility::kRtcpRrCode) || (rtcpPacketType == RTCPUtility::kRtcpSrCode));
380
381 // SR.SenderSSRC
382 // The synchronization source identifier for the originator of this SR packet
383
384 // rtcpPacket.RR.SenderSSRC
385 // The source of the packet sender, same as of SR? or is this a CE?
386
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000387 const uint32_t remoteSSRC = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.SenderSSRC:rtcpPacket.SR.SenderSSRC;
388 const uint8_t numberOfReportBlocks = (rtcpPacketType == RTCPUtility::kRtcpRrCode) ? rtcpPacket.RR.NumberOfReportBlocks:rtcpPacket.SR.NumberOfReportBlocks;
niklase@google.com470e71d2011-07-07 08:21:25 +0000389
390 rtcpPacketInformation.remoteSSRC = remoteSSRC;
391
392 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
393 if (!ptrReceiveInfo)
394 {
395 rtcpParser.Iterate();
396 return;
397 }
398
399 if (rtcpPacketType == RTCPUtility::kRtcpSrCode)
400 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000401 TRACE_EVENT_INSTANT2("webrtc_rtp", "SR",
402 "remote_ssrc", remoteSSRC,
403 "ssrc", _SSRC);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000404
niklase@google.com470e71d2011-07-07 08:21:25 +0000405 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
406 {
407 // only signal that we have received a SR when we accept one
408 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
409
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000410 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
411 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
412 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
413
niklase@google.com470e71d2011-07-07 08:21:25 +0000414 // We will only store the send report from one source, but
415 // we will store all the receive block
416
417 // Save the NTP time of this report
418 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
419 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
420 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
421 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
422 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
423
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000424 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000425 }
426 else
427 {
428 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
429 }
430 } else
431 {
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000432 TRACE_EVENT_INSTANT2("webrtc_rtp", "RR",
433 "remote_ssrc", remoteSSRC,
434 "ssrc", _SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000435
436 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
437 }
438 UpdateReceiveInformation(*ptrReceiveInfo);
439
440 rtcpPacketType = rtcpParser.Iterate();
441
442 while (rtcpPacketType == RTCPUtility::kRtcpReportBlockItemCode)
443 {
444 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC, numberOfReportBlocks);
445 rtcpPacketType = rtcpParser.Iterate();
446 }
447}
448
449// no need for critsect we have _criticalSectionRTCPReceiver
450void
451RTCPReceiver::HandleReportBlock(const RTCPUtility::RTCPPacket& rtcpPacket,
452 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000453 const uint32_t remoteSSRC,
454 const uint8_t numberOfReportBlocks) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000455 // This will be called once per report block in the RTCP packet.
456 // We filter out all report blocks that are not for us.
457 // Each packet has max 31 RR blocks.
458 //
459 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000460
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000461 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
462 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000463
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000464 // Filter out all report blocks that are not for us.
465 if (rtcpPacket.ReportBlockItem.SSRC != _SSRC) {
466 // This block is not for us ignore it.
467 return;
468 }
469
470 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
471 // _criticalSectionRTCPReceiver.
472 _criticalSectionRTCPReceiver->Leave();
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000473 uint32_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000474 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
475 _criticalSectionRTCPReceiver->Enter();
476
477 RTCPReportBlockInformation* reportBlock =
478 CreateReportBlockInformation(remoteSSRC);
479 if (reportBlock == NULL) {
480 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
481 "\tfailed to CreateReportBlockInformation(%u)", remoteSSRC);
482 return;
483 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000484
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000485 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000486 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
487 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
488 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
489 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
490 reportBlock->remoteReceiveBlock.cumulativeLost =
491 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000492 if (rb.ExtendedHighestSequenceNumber >
493 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
494 // We have successfully delivered new RTP packets to the remote side after
495 // the last RR was sent from the remote side.
496 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000497 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000498 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
499 rb.ExtendedHighestSequenceNumber;
500 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
501 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
502 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
503
504 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
505 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
506 }
507
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000508 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000509 rtcpPacket.ReportBlockItem.DelayLastSR;
510
511 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000512 uint32_t lastReceivedRRNTPsecs = 0;
513 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000514
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000515 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000516
517 // time when we received this in MS
stefan@webrtc.orgb8e7f4c2013-04-12 11:56:23 +0000518 uint32_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
519 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000520
521 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000522 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000523 d /= 65536;
524 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
525
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000526 int32_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000527
528 if (sendTimeMS > 0) {
529 RTT = receiveTimeMS - d - sendTimeMS;
530 if (RTT <= 0) {
531 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000532 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000533 if (RTT > reportBlock->maxRTT) {
534 // store max RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000535 reportBlock->maxRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000536 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000537 if (reportBlock->minRTT == 0) {
538 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000539 reportBlock->minRTT = (uint16_t) RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000540 } else if (RTT < reportBlock->minRTT) {
541 // Store min RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000542 reportBlock->minRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000543 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000544 // store last RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000545 reportBlock->RTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000546
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000547 // store average RTT
548 if (reportBlock->numAverageCalcs != 0) {
549 float ac = static_cast<float> (reportBlock->numAverageCalcs);
550 float newAverage = ((ac / (ac + 1)) * reportBlock->avgRTT)
551 + ((1 / (ac + 1)) * RTT);
552 reportBlock->avgRTT = static_cast<int> (newAverage + 0.5f);
553 } else {
554 // first RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000555 reportBlock->avgRTT = (uint16_t) RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000556 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000557 reportBlock->numAverageCalcs++;
558 }
559
hclam@chromium.org806dc3b2013-04-09 19:54:10 +0000560 TRACE_COUNTER_ID1("webrtc_rtp", "RR_RTT", rb.SSRC, RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000561
562 // rtcpPacketInformation
563 rtcpPacketInformation.AddReportInfo(
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000564 reportBlock->remoteReceiveBlock.fractionLost, (uint16_t) RTT,
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000565 reportBlock->remoteReceiveBlock.extendedHighSeqNum,
566 reportBlock->remoteReceiveBlock.jitter);
niklase@google.com470e71d2011-07-07 08:21:25 +0000567}
568
569RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000570RTCPReceiver::CreateReportBlockInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000571 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000572
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000573 std::map<uint32_t, RTCPReportBlockInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000574 _receivedReportBlockMap.find(remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000575
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000576 RTCPReportBlockInformation* ptrReportBlockInfo = NULL;
577 if (it != _receivedReportBlockMap.end()) {
578 ptrReportBlockInfo = it->second;
579 } else {
580 ptrReportBlockInfo = new RTCPReportBlockInformation;
581 _receivedReportBlockMap[remoteSSRC] = ptrReportBlockInfo;
582 }
583 return ptrReportBlockInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000584}
585
586RTCPReportBlockInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000587RTCPReceiver::GetReportBlockInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000588 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000589
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000590 std::map<uint32_t, RTCPReportBlockInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000591 _receivedReportBlockMap.find(remoteSSRC);
592
593 if (it == _receivedReportBlockMap.end()) {
594 return NULL;
595 }
596 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000597}
598
599RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000600RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000601 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000602
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000603 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000604 _receivedCnameMap.find(remoteSSRC);
605
606 if (it != _receivedCnameMap.end()) {
607 return it->second;
608 }
609 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000610 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000611 _receivedCnameMap[remoteSSRC] = cnameInfo;
612 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000613}
614
615RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000616RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000617 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000618
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000619 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000620 _receivedCnameMap.find(remoteSSRC);
621
622 if (it == _receivedCnameMap.end()) {
623 return NULL;
624 }
625 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000626}
627
628RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000629RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000630 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000631
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000632 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000633 _receivedInfoMap.find(remoteSSRC);
634
635 if (it != _receivedInfoMap.end()) {
636 return it->second;
637 }
638 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
639 _receivedInfoMap[remoteSSRC] = receiveInfo;
640 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000641}
642
643RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000644RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000645 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000646
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000647 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000648 _receivedInfoMap.find(remoteSSRC);
649 if (it == _receivedInfoMap.end()) {
650 return NULL;
651 }
652 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000653}
654
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000655void RTCPReceiver::UpdateReceiveInformation(
656 RTCPReceiveInformation& receiveInformation) {
657 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000658 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000659}
660
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000661bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
662 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
663 if (_lastReceivedRrMs == 0)
664 return false;
665
666 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000667 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000668 // Reset the timer to only trigger one log.
669 _lastReceivedRrMs = 0;
670 return true;
671 }
672 return false;
673}
674
675bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
676 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
677 if (_lastIncreasedSequenceNumberMs == 0)
678 return false;
679
680 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000681 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000682 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000683 // Reset the timer to only trigger one log.
684 _lastIncreasedSequenceNumberMs = 0;
685 return true;
686 }
687 return false;
688}
689
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000690bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
691 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000692
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000693 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000694 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000695
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000696 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000697 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000698
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000699 while (receiveInfoIt != _receivedInfoMap.end()) {
700 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
701 if (receiveInfo == NULL) {
702 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000703 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000704 // time since last received rtcp packet
705 // when we dont have a lastTimeReceived and the object is marked
706 // readyForDelete it's removed from the map
707 if (receiveInfo->lastTimeReceived) {
708 /// use audio define since we don't know what interval the remote peer is
709 // using
710 if ((timeNow - receiveInfo->lastTimeReceived) >
711 5 * RTCP_INTERVAL_AUDIO_MS) {
712 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000713 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000714 // prevent that we call this over and over again
715 receiveInfo->lastTimeReceived = 0;
716 // send new TMMBN to all channels using the default codec
717 updateBoundingSet = true;
718 }
719 receiveInfoIt++;
720 } else if (receiveInfo->readyForDelete) {
721 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000722 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000723 receiveInfoItemToBeErased = receiveInfoIt;
724 receiveInfoIt++;
725 delete receiveInfoItemToBeErased->second;
726 _receivedInfoMap.erase(receiveInfoItemToBeErased);
727 } else {
728 receiveInfoIt++;
729 }
730 }
731 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000732}
733
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000734int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000735 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000736
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000737 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000738 _receivedInfoMap.find(_remoteSSRC);
739
740 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000741 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000742 }
743 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
744 if (receiveInfo == NULL) {
745 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
746 "%s failed to get RTCPReceiveInformation",
747 __FUNCTION__);
748 return -1;
749 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000750 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000751 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000752 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000753 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000754 i++) {
755 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == _SSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000756 // owner of bounding set
757 tmmbrOwner = true;
758 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000759 boundingSetRec->SetEntry(i,
760 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
761 receiveInfo->TmmbnBoundingSet.PacketOH(i),
762 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000763 }
764 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000765 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000766}
767
768// no need for critsect we have _criticalSectionRTCPReceiver
769void
770RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser)
771{
772 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
773 while (pktType == RTCPUtility::kRtcpSdesChunkCode)
774 {
775 HandleSDESChunk(rtcpParser);
776 pktType = rtcpParser.Iterate();
777 }
778}
779
780// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000781void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
782 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
783 RTCPCnameInformation* cnameInfo =
784 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
785 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000786
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000787 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
788 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000789}
790
791// no need for critsect we have _criticalSectionRTCPReceiver
792void
793RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
794 RTCPPacketInformation& rtcpPacketInformation)
795{
796 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000797 if (_SSRC != rtcpPacket.NACK.MediaSSRC)
798 {
799 // Not to us.
800 rtcpParser.Iterate();
801 return;
802 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000803 rtcpPacketInformation.ResetNACKPacketIdArray();
804
805 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
806 while (pktType == RTCPUtility::kRtcpRtpfbNackItemCode)
807 {
808 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
809 pktType = rtcpParser.Iterate();
810 }
811}
812
813// no need for critsect we have _criticalSectionRTCPReceiver
814void
815RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
816 RTCPPacketInformation& rtcpPacketInformation)
817{
818 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
819
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000820 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
niklase@google.com470e71d2011-07-07 08:21:25 +0000821 if(bitMask)
822 {
823 for(int i=1; i <= 16; ++i)
824 {
825 if(bitMask & 0x01)
826 {
827 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
828 }
829 bitMask = bitMask >>1;
830 }
831 }
832
833 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
834}
835
836// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000837void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
838 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000839
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000840 // clear our lists
841 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000842 std::map<uint32_t, RTCPReportBlockInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000843 reportBlockInfoIt = _receivedReportBlockMap.find(
844 rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000845
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000846 if (reportBlockInfoIt != _receivedReportBlockMap.end()) {
847 delete reportBlockInfoIt->second;
848 _receivedReportBlockMap.erase(reportBlockInfoIt);
849 }
850 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000851 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000852 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000853
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000854 if (receiveInfoIt != _receivedInfoMap.end()) {
855 receiveInfoIt->second->readyForDelete = true;
856 }
857
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000858 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000859 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
860
861 if (cnameInfoIt != _receivedCnameMap.end()) {
862 delete cnameInfoIt->second;
863 _receivedCnameMap.erase(cnameInfoIt);
864 }
865 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000866}
867
868// no need for critsect we have _criticalSectionRTCPReceiver
869void
870RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
871 RTCPPacketInformation& rtcpPacketInformation)
872{
873 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
874
875 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
876
877 if(rtcpPacket.XRVOIPMetricItem.SSRC == _SSRC)
878 {
879 // Store VoIP metrics block if it's about me
880 // from OriginatorSSRC do we filter it?
881 // rtcpPacket.XR.OriginatorSSRC;
882
883 RTCPVoIPMetric receivedVoIPMetrics;
884 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
885 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
886 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
887 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
888 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
889 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
890 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
891 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
892 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
893 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
894 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
895 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
896 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
897 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
898 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
899 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
900 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
901 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
902 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
903 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
904
905 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
906
907 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
908 }
909 rtcpParser.Iterate();
910}
911
912// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000913void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
914 RTCPPacketInformation& rtcpPacketInformation) {
915 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
916 if (_SSRC == rtcpPacket.PLI.MediaSSRC) {
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000917 TRACE_EVENT_INSTANT0("webrtc_rtp", "PLI");
918
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000919 // Received a signal that we need to send a new key frame.
920 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
921 }
922 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000923}
924
925// no need for critsect we have _criticalSectionRTCPReceiver
926void
927RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
928 RTCPPacketInformation& rtcpPacketInformation)
929{
930 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
931
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000932 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000933 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
934 if (ptrReceiveInfo == NULL)
935 {
936 // This remote SSRC must be saved before.
937 rtcpParser.Iterate();
938 return;
939 }
940 if(rtcpPacket.TMMBR.MediaSSRC)
941 {
942 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
943 // in relay mode this is a valid number
944 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
945 }
946
947 // Use packet length to calc max number of TMMBR blocks
948 // each TMMBR block is 8 bytes
949 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
950
951 // sanity
952 if(maxNumOfTMMBRBlocks > 200) // we can't have more than what's in one packet
953 {
954 assert(false);
955 rtcpParser.Iterate();
956 return;
957 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000958 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +0000959
960 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
961 while (pktType == RTCPUtility::kRtcpRtpfbTmmbrItemCode)
962 {
963 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
964 pktType = rtcpParser.Iterate();
965 }
966}
967
968// no need for critsect we have _criticalSectionRTCPReceiver
969void
970RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
971 const RTCPUtility::RTCPPacket& rtcpPacket,
972 RTCPPacketInformation& rtcpPacketInformation,
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000973 const uint32_t senderSSRC)
niklase@google.com470e71d2011-07-07 08:21:25 +0000974{
975 if (_SSRC == rtcpPacket.TMMBRItem.SSRC &&
976 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0)
977 {
pwestin@webrtc.org0644b1d2011-12-01 15:42:31 +0000978 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000979 _clock->TimeInMilliseconds());
niklase@google.com470e71d2011-07-07 08:21:25 +0000980 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
981 }
982}
983
984// no need for critsect we have _criticalSectionRTCPReceiver
985void
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000986RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
987 RTCPPacketInformation& rtcpPacketInformation)
niklase@google.com470e71d2011-07-07 08:21:25 +0000988{
989 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
990 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
991 if (ptrReceiveInfo == NULL)
992 {
993 // This remote SSRC must be saved before.
994 rtcpParser.Iterate();
995 return;
996 }
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000997 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +0000998 // Use packet length to calc max number of TMMBN blocks
999 // each TMMBN block is 8 bytes
1000 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1001
1002 // sanity
1003 if(maxNumOfTMMBNBlocks > 200) // we cant have more than what's in one packet
1004 {
1005 assert(false);
1006 rtcpParser.Iterate();
1007 return;
1008 }
1009
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001010 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001011
1012 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1013 while (pktType == RTCPUtility::kRtcpRtpfbTmmbnItemCode)
1014 {
1015 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1016 pktType = rtcpParser.Iterate();
1017 }
1018}
1019
1020// no need for critsect we have _criticalSectionRTCPReceiver
1021void
1022RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1023 RTCPPacketInformation& rtcpPacketInformation)
1024{
1025 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1026 rtcpParser.Iterate();
1027}
1028
1029// no need for critsect we have _criticalSectionRTCPReceiver
1030void
1031RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1032 const RTCPUtility::RTCPPacket& rtcpPacket)
1033{
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001034 receiveInfo.TmmbnBoundingSet.AddEntry(
1035 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1036 rtcpPacket.TMMBNItem.MeasuredOverhead,
1037 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001038}
1039
1040// no need for critsect we have _criticalSectionRTCPReceiver
1041void
1042RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1043 RTCPPacketInformation& rtcpPacketInformation)
1044{
1045 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001046 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1047 while (pktType == RTCPUtility::kRtcpPsfbSliItemCode)
1048 {
1049 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1050 pktType = rtcpParser.Iterate();
1051 }
1052}
1053
1054// no need for critsect we have _criticalSectionRTCPReceiver
1055void
1056RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1057 RTCPPacketInformation& rtcpPacketInformation)
1058{
1059 // in theory there could be multiple slices lost
1060 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1061 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
1062}
1063
1064void
1065RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1066 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1067{
1068 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001069 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1070 if(pktType == RTCPUtility::kRtcpPsfbRpsiCode)
1071 {
1072 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1073 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1074 {
1075 // to us unknown
1076 // continue
1077 rtcpParser.Iterate();
1078 return;
1079 }
1080 rtcpPacketInformation.rpsiPictureId = 0;
1081
1082 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001083 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1084 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001085 {
1086 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1087 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1088 }
1089 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1090 }
1091}
1092
1093// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001094void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1095 RTCPPacketInformation& rtcpPacketInformation) {
1096 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1097 if (pktType == RTCPUtility::kRtcpPsfbRembCode) {
1098 pktType = rtcpParser.Iterate();
1099 if (pktType == RTCPUtility::kRtcpPsfbRembItemCode) {
1100 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1101 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001102 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001103 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001104}
1105
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001106// no need for critsect we have _criticalSectionRTCPReceiver
1107void
1108RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1109 RTCPPacketInformation& rtcpPacketInformation)
1110{
1111 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1112
1113 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1114 while (pktType == RTCPUtility::kRtcpExtendedIjItemCode)
1115 {
1116 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1117 pktType = rtcpParser.Iterate();
1118 }
1119}
1120
1121void
1122RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1123 RTCPPacketInformation& rtcpPacketInformation)
1124{
1125 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1126 rtcpPacketInformation.interArrivalJitter =
1127 rtcpPacket.ExtendedJitterReportItem.Jitter;
1128}
1129
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001130void RTCPReceiver::HandleREMBItem(
1131 RTCPUtility::RTCPParserV2& rtcpParser,
1132 RTCPPacketInformation& rtcpPacketInformation) {
1133 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1134 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1135 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1136 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001137}
1138
1139// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001140void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1141 RTCPPacketInformation& rtcpPacketInformation) {
1142 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1143 RTCPReceiveInformation* ptrReceiveInfo =
1144 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001145
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001146 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1147 while (pktType == RTCPUtility::kRtcpPsfbFirItemCode) {
1148 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1149 pktType = rtcpParser.Iterate();
1150 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001151}
1152
1153// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001154void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1155 const RTCPUtility::RTCPPacket& rtcpPacket,
1156 RTCPPacketInformation& rtcpPacketInformation) {
1157 // Is it our sender that is requested to generate a new keyframe
1158 if (_SSRC != rtcpPacket.FIRItem.SSRC) {
1159 return;
1160 }
1161 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1162 // we don't know who this originate from
1163 if (receiveInfo) {
1164 // check if we have reported this FIRSequenceNumber before
1165 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1166 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001167 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001168 // sanity; don't go crazy with the callbacks
1169 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1170 receiveInfo->lastFIRRequest = now;
1171 receiveInfo->lastFIRSequenceNumber =
1172 rtcpPacket.FIRItem.CommandSequenceNumber;
1173 // received signal that we need to send a new key frame
1174 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1175 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001176 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001177 } else {
1178 // received signal that we need to send a new key frame
1179 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1180 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001181}
1182
1183void
1184RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1185 RTCPPacketInformation& rtcpPacketInformation)
1186{
1187 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1188
1189 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1190 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1191 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
1192
1193 rtcpParser.Iterate();
1194}
1195
1196void
1197RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1198 RTCPPacketInformation& rtcpPacketInformation)
1199{
1200 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1201
1202 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
1203
1204 rtcpParser.Iterate();
1205}
1206
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001207int32_t RTCPReceiver::UpdateTMMBR() {
1208 int32_t numBoundingSet = 0;
1209 uint32_t bitrate = 0;
1210 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001211
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001212 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001213 if (size > 0) {
1214 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1215 // Get candidate set from receiver.
1216 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1217 } else {
1218 // Candidate set empty.
1219 VerifyAndAllocateCandidateSet(0); // resets candidate set
1220 }
1221 // Find bounding set
1222 TMMBRSet* boundingSet = NULL;
1223 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1224 if (numBoundingSet == -1) {
1225 WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, _id,
1226 "Failed to find TMMBR bounding set.");
1227 return -1;
1228 }
1229 // Set bounding set
1230 // Inform remote clients about the new bandwidth
1231 // inform the remote client
1232 _rtpRtcp.SetTMMBN(boundingSet);
1233
1234 // might trigger a TMMBN
1235 if (numBoundingSet == 0) {
1236 // owner of max bitrate request has timed out
1237 // empty bounding set has been sent
1238 return 0;
1239 }
1240 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001241 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001242 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001243 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1244 if (_cbRtcpBandwidthObserver) {
1245 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
1246 WEBRTC_TRACE(kTraceStream, kTraceRtpRtcp, _id,
1247 "Set TMMBR request:%d kbps", bitrate);
1248 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001249 }
1250 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001251}
1252
1253// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001254void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001255 RTCPPacketInformation& rtcpPacketInformation) {
1256 // Process TMMBR and REMB first to avoid multiple callbacks
1257 // to OnNetworkChanged.
1258 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
1259 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1260 "SIG [RTCP] Incoming TMMBR to id:%d", _id);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001261
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001262 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1263 UpdateTMMBR();
1264 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001265 unsigned int local_ssrc = 0;
1266 {
1267 // We don't want to hold this critsect when triggering the callbacks below.
1268 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1269 local_ssrc = _SSRC;
1270 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001271 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
1272 _rtpRtcp.OnRequestSendReport();
1273 }
1274 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001275 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001276 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1277 "SIG [RTCP] Incoming NACK length:%d",
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001278 rtcpPacketInformation.nackSequenceNumbers.size());
1279 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001280 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001281 }
1282 {
1283 CriticalSectionScoped lock(_criticalSectionFeedbacks);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001284
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001285 // We need feedback that we have received a report block(s) so that we
1286 // can generate a new packet in a conference relay scenario, one received
1287 // report can generate several RTCP packets, based on number relayed/mixed
1288 // a send report block should go out to all receivers.
1289 if (_cbRtcpIntraFrameObserver) {
1290 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1291 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1292 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
1293 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1294 "SIG [RTCP] Incoming PLI from SSRC:0x%x",
1295 rtcpPacketInformation.remoteSSRC);
1296 } else {
1297 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1298 "SIG [RTCP] Incoming FIR from SSRC:0x%x",
1299 rtcpPacketInformation.remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001300 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001301 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001302 }
1303 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1304 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001305 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001306 }
1307 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1308 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001309 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001310 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001311 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001312 if (_cbRtcpBandwidthObserver) {
1313 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
1314 WEBRTC_TRACE(kTraceStateInfo, kTraceRtpRtcp, _id,
1315 "SIG [RTCP] Incoming REMB:%d",
1316 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1317 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1318 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1319 }
1320 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr ||
1321 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr) &&
1322 rtcpPacketInformation.reportBlock) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001323 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001324 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
1325 rtcpPacketInformation.remoteSSRC,
1326 rtcpPacketInformation.fractionLost,
1327 rtcpPacketInformation.roundTripTime,
1328 rtcpPacketInformation.lastReceivedExtendedHighSeqNum,
1329 now);
1330 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001331 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001332 if(_cbRtcpFeedback) {
solenberg@webrtc.org91811e22013-06-25 20:36:14 +00001333 if(!(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001334 _cbRtcpFeedback->OnReceiveReportReceived(_id,
1335 rtcpPacketInformation.remoteSSRC);
1336 }
1337 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpXrVoipMetric) {
1338 _cbRtcpFeedback->OnXRVoIPMetricReceived(_id,
1339 rtcpPacketInformation.VoIPMetric);
1340 }
1341 if(rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpApp) {
1342 _cbRtcpFeedback->OnApplicationDataReceived(_id,
1343 rtcpPacketInformation.applicationSubType,
1344 rtcpPacketInformation.applicationName,
1345 rtcpPacketInformation.applicationLength,
1346 rtcpPacketInformation.applicationData);
1347 }
1348 }
1349 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001350}
1351
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001352int32_t RTCPReceiver::CNAME(const uint32_t remoteSSRC,
1353 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001354 assert(cName);
1355
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001356 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1357 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001358 if (cnameInfo == NULL) {
1359 return -1;
1360 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001361 cName[RTCP_CNAME_SIZE - 1] = 0;
1362 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1363 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001364}
1365
1366// no callbacks allowed inside this function
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001367int32_t RTCPReceiver::TMMBRReceived(const uint32_t size,
1368 const uint32_t accNumCandidates,
1369 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001370 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001371
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001372 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001373 receiveInfoIt = _receivedInfoMap.begin();
1374 if (receiveInfoIt == _receivedInfoMap.end()) {
1375 return -1;
1376 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001377 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001378 if (candidateSet) {
1379 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1380 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1381 if (receiveInfo == NULL) {
1382 return 0;
1383 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001384 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001385 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001386 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001387 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001388 num++;
1389 }
1390 }
1391 receiveInfoIt++;
1392 }
1393 } else {
1394 while (receiveInfoIt != _receivedInfoMap.end()) {
1395 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1396 if(receiveInfo == NULL) {
1397 WEBRTC_TRACE(kTraceError, kTraceRtpRtcp, _id,
1398 "%s failed to get RTCPReceiveInformation",
1399 __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +00001400 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001401 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001402 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001403 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001404 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001405 }
1406 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001407}
1408
tnakamura@webrtc.orgaa4d96a2013-07-16 19:25:04 +00001409int32_t
1410RTCPReceiver::SetPacketTimeout(const uint32_t timeoutMS)
1411{
1412 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1413 _packetTimeOutMS = timeoutMS;
1414 return 0;
1415}
1416
1417void RTCPReceiver::PacketTimeout()
1418{
1419 if(_packetTimeOutMS == 0)
1420 {
1421 // not configured
1422 return;
1423 }
1424
1425 bool packetTimeOut = false;
1426 {
1427 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1428 if(_lastReceived == 0)
1429 {
1430 // not active
1431 return;
1432 }
1433
1434 int64_t now = _clock->TimeInMilliseconds();
1435 if(now - _lastReceived > _packetTimeOutMS)
1436 {
1437 packetTimeOut = true;
1438 _lastReceived = 0; // only one callback
1439 }
1440 }
1441 CriticalSectionScoped lock(_criticalSectionFeedbacks);
1442 if(packetTimeOut && _cbRtcpFeedback)
1443 {
1444 _cbRtcpFeedback->OnRTCPPacketTimeout(_id);
1445 }
1446}
1447
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001448} // namespace webrtc