blob: d57432cea469365fa6b989725ced3ec23e6a8782 [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
Peter Boströmfe7a80c2015-04-23 17:53:17 +020013#include <assert.h>
14#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000015
danilchap2f69ce92016-08-16 03:21:38 -070016#include <limits>
17
Peter Boströmfe7a80c2015-04-23 17:53:17 +020018#include "webrtc/base/checks.h"
Peter Boströmebc0b4e2015-10-28 16:39:33 +010019#include "webrtc/base/logging.h"
tommie4f96502015-10-20 23:00:48 -070020#include "webrtc/base/trace_event.h"
Erik Språng6b8d3552015-09-24 15:06:57 +020021#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
tommie4f96502015-10-20 23:00:48 -070022#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000023#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010024#include "webrtc/modules/rtp_rtcp/source/time_util.h"
danilchap13deaad2016-05-24 13:25:27 -070025#include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010026#include "webrtc/system_wrappers/include/ntp_time.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000027
niklase@google.com470e71d2011-07-07 08:21:25 +000028namespace webrtc {
danilchap6a6f0892015-12-10 12:39:08 -080029using RTCPHelp::RTCPPacketInformation;
30using RTCPHelp::RTCPReceiveInformation;
31using RTCPHelp::RTCPReportBlockInformation;
32using RTCPUtility::kBtVoipMetric;
33using RTCPUtility::RTCPCnameInformation;
34using RTCPUtility::RTCPPacketReportBlockItem;
35using RTCPUtility::RTCPPacketTypes;
niklase@google.com470e71d2011-07-07 08:21:25 +000036
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000037// The number of RTCP time intervals needed to trigger a timeout.
38const int kRrTimeoutIntervals = 3;
39
Erik Språng6b8d3552015-09-24 15:06:57 +020040const int64_t kMaxWarningLogIntervalMs = 10000;
41
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000042RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000043 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020044 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000045 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000046 RtcpBandwidthObserver* rtcp_bandwidth_observer,
47 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020048 TransportFeedbackObserver* transport_feedback_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000049 ModuleRtpRtcpImpl* owner)
danilchap13deaad2016-05-24 13:25:27 -070050 : _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020051 receiver_only_(receiver_only),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000052 _lastReceived(0),
53 _rtpRtcp(*owner),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000054 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
55 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020056 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000057 main_ssrc_(0),
58 _remoteSSRC(0),
59 _remoteSenderInfo(),
60 _lastReceivedSRNTPsecs(0),
61 _lastReceivedSRNTPfrac(0),
62 _lastReceivedXRNTPsecs(0),
63 _lastReceivedXRNTPfrac(0),
Danil Chapovalovc1e55c72016-03-09 15:14:35 +010064 xr_rrtr_status_(false),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000065 xr_rr_rtt_ms_(0),
66 _receivedInfoMap(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000067 _lastReceivedRrMs(0),
68 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000069 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020070 packet_type_counter_observer_(packet_type_counter_observer),
71 num_skipped_packets_(0),
72 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000073 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000074}
75
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000076RTCPReceiver::~RTCPReceiver() {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000077 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
78 for (; it != _receivedReportBlockMap.end(); ++it) {
79 ReportBlockInfoMap* info_map = &(it->second);
80 while (!info_map->empty()) {
81 ReportBlockInfoMap::iterator it_info = info_map->begin();
82 delete it_info->second;
83 info_map->erase(it_info);
84 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000085 }
86 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000087 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000088 _receivedInfoMap.begin();
89 delete first->second;
90 _receivedInfoMap.erase(first);
91 }
92 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000093 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000094 _receivedCnameMap.begin();
95 delete first->second;
96 _receivedCnameMap.erase(first);
97 }
niklase@google.com470e71d2011-07-07 08:21:25 +000098}
99
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000100int64_t RTCPReceiver::LastReceived() {
danilchap7c9426c2016-04-14 03:05:31 -0700101 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000102 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000103}
104
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000105int64_t RTCPReceiver::LastReceivedReceiverReport() const {
danilchap7c9426c2016-04-14 03:05:31 -0700106 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000107 int64_t last_received_rr = -1;
108 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
109 it != _receivedInfoMap.end(); ++it) {
danilchap2b616392016-08-18 06:17:42 -0700110 if (it->second->last_time_received_ms > last_received_rr) {
111 last_received_rr = it->second->last_time_received_ms;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000112 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000113 }
114 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000115}
116
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000117void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
danilchap7c9426c2016-04-14 03:05:31 -0700118 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000119
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000120 // new SSRC reset old reports
121 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
122 _lastReceivedSRNTPsecs = 0;
123 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000124
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000125 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000126}
127
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000128uint32_t RTCPReceiver::RemoteSSRC() const {
danilchap7c9426c2016-04-14 03:05:31 -0700129 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000130 return _remoteSSRC;
131}
132
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000133void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
134 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000135 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000136 {
danilchap7c9426c2016-04-14 03:05:31 -0700137 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000138 old_ssrc = main_ssrc_;
139 main_ssrc_ = main_ssrc;
140 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000141 }
142 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000143 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
144 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000145 }
146 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000147}
148
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000149int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000150 int64_t* RTT,
151 int64_t* avgRTT,
152 int64_t* minRTT,
153 int64_t* maxRTT) const {
danilchap7c9426c2016-04-14 03:05:31 -0700154 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000155
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000156 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000157 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000158
159 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000160 return -1;
161 }
162 if (RTT) {
163 *RTT = reportBlock->RTT;
164 }
165 if (avgRTT) {
166 *avgRTT = reportBlock->avgRTT;
167 }
168 if (minRTT) {
169 *minRTT = reportBlock->minRTT;
170 }
171 if (maxRTT) {
172 *maxRTT = reportBlock->maxRTT;
173 }
174 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000175}
176
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100177void RTCPReceiver::SetRtcpXrRrtrStatus(bool enable) {
danilchap7c9426c2016-04-14 03:05:31 -0700178 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100179 xr_rrtr_status_ = enable;
180}
181
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000182bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000183 assert(rtt_ms);
danilchap7c9426c2016-04-14 03:05:31 -0700184 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000185 if (xr_rr_rtt_ms_ == 0) {
186 return false;
187 }
188 *rtt_ms = xr_rr_rtt_ms_;
189 xr_rr_rtt_ms_ = 0;
190 return true;
191}
192
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000193// TODO(pbos): Make this fail when we haven't received NTP.
194bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
195 uint32_t* ReceivedNTPfrac,
196 uint32_t* RTCPArrivalTimeSecs,
197 uint32_t* RTCPArrivalTimeFrac,
danilchapda161d72016-08-19 07:29:46 -0700198 uint32_t* rtcp_timestamp) const {
199 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
200 if (ReceivedNTPsecs) {
201 *ReceivedNTPsecs =
202 _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
203 }
204 if (ReceivedNTPfrac) {
205 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
206 }
207 if (RTCPArrivalTimeFrac) {
208 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we
209 // received a RTCP packet
210 // with a send block
211 }
212 if (RTCPArrivalTimeSecs) {
213 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
214 }
215 if (rtcp_timestamp) {
216 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
217 }
218 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000219}
220
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000221bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
222 RtcpReceiveTimeInfo* info) const {
223 assert(info);
danilchap7c9426c2016-04-14 03:05:31 -0700224 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000225 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
226 return false;
227 }
228
229 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
230 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
231
232 // Get the delay since last received report (RFC 3611).
danilchapda161d72016-08-19 07:29:46 -0700233 uint32_t receive_time =
234 RTCPUtility::MidNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000235
236 uint32_t ntp_sec = 0;
237 uint32_t ntp_frac = 0;
238 _clock->CurrentNtp(ntp_sec, ntp_frac);
239 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
240
241 info->delaySinceLastRR = now - receive_time;
242 return true;
243}
244
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000245int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
246 assert(senderInfo);
danilchap7c9426c2016-04-14 03:05:31 -0700247 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000248 if (_lastReceivedSRNTPsecs == 0) {
249 return -1;
250 }
251 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
252 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000253}
254
255// statistics
256// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000257int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000258 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000259 assert(receiveBlocks);
danilchap7c9426c2016-04-14 03:05:31 -0700260 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000261 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
262 for (; it != _receivedReportBlockMap.end(); ++it) {
263 const ReportBlockInfoMap* info_map = &(it->second);
264 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
265 for (; it_info != info_map->end(); ++it_info) {
266 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
267 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000268 }
269 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000270}
271
danilchapda161d72016-08-19 07:29:46 -0700272int32_t RTCPReceiver::IncomingRTCPPacket(
273 RTCPPacketInformation& rtcpPacketInformation,
274 RTCPUtility::RTCPParserV2* rtcpParser) {
275 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000276
danilchapda161d72016-08-19 07:29:46 -0700277 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000278
danilchapda161d72016-08-19 07:29:46 -0700279 if (packet_type_counter_.first_packet_time_ms == -1) {
280 packet_type_counter_.first_packet_time_ms = _lastReceived;
281 }
282
283 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
284 while (pktType != RTCPPacketTypes::kInvalid) {
285 // Each "case" is responsible for iterate the parser to the
286 // next top level packet.
287 switch (pktType) {
288 case RTCPPacketTypes::kSr:
289 case RTCPPacketTypes::kRr:
290 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
291 break;
292 case RTCPPacketTypes::kSdes:
293 HandleSDES(*rtcpParser, rtcpPacketInformation);
294 break;
295 case RTCPPacketTypes::kXrHeader:
296 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
297 break;
298 case RTCPPacketTypes::kXrReceiverReferenceTime:
299 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
300 break;
301 case RTCPPacketTypes::kXrDlrrReportBlock:
302 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
303 break;
304 case RTCPPacketTypes::kXrVoipMetric:
305 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
306 break;
307 case RTCPPacketTypes::kBye:
308 HandleBYE(*rtcpParser);
309 break;
310 case RTCPPacketTypes::kRtpfbNack:
311 HandleNACK(*rtcpParser, rtcpPacketInformation);
312 break;
313 case RTCPPacketTypes::kRtpfbTmmbr:
314 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
315 break;
316 case RTCPPacketTypes::kRtpfbTmmbn:
317 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
318 break;
319 case RTCPPacketTypes::kRtpfbSrReq:
320 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
321 break;
322 case RTCPPacketTypes::kPsfbPli:
323 HandlePLI(*rtcpParser, rtcpPacketInformation);
324 break;
325 case RTCPPacketTypes::kPsfbSli:
326 HandleSLI(*rtcpParser, rtcpPacketInformation);
327 break;
328 case RTCPPacketTypes::kPsfbRpsi:
329 HandleRPSI(*rtcpParser, rtcpPacketInformation);
330 break;
331 case RTCPPacketTypes::kExtendedIj:
332 HandleIJ(*rtcpParser, rtcpPacketInformation);
333 break;
334 case RTCPPacketTypes::kPsfbFir:
335 HandleFIR(*rtcpParser, rtcpPacketInformation);
336 break;
337 case RTCPPacketTypes::kPsfbApp:
338 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
339 break;
340 case RTCPPacketTypes::kApp:
341 // generic application messages
342 HandleAPP(*rtcpParser, rtcpPacketInformation);
343 break;
344 case RTCPPacketTypes::kAppItem:
345 // generic application messages
346 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
347 break;
348 case RTCPPacketTypes::kTransportFeedback:
349 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
350 break;
351 default:
352 rtcpParser->Iterate();
353 break;
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000354 }
danilchapda161d72016-08-19 07:29:46 -0700355 pktType = rtcpParser->PacketType();
356 }
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000357
danilchapda161d72016-08-19 07:29:46 -0700358 if (packet_type_counter_observer_ != NULL) {
359 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
360 main_ssrc_, packet_type_counter_);
361 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000362
danilchapda161d72016-08-19 07:29:46 -0700363 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000364
danilchapda161d72016-08-19 07:29:46 -0700365 int64_t now = _clock->TimeInMilliseconds();
366 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
367 num_skipped_packets_ > 0) {
368 last_skipped_packets_warning_ = now;
369 LOG(LS_WARNING) << num_skipped_packets_
370 << " RTCP blocks were skipped due to being malformed or of "
371 "unrecognized/unsupported type, during the past "
372 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
373 }
Erik Språng6b8d3552015-09-24 15:06:57 +0200374
danilchapda161d72016-08-19 07:29:46 -0700375 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000376}
377
danilchapda161d72016-08-19 07:29:46 -0700378void RTCPReceiver::HandleSenderReceiverReport(
379 RTCPUtility::RTCPParserV2& rtcpParser,
380 RTCPPacketInformation& rtcpPacketInformation) {
381 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
382 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000383
danilchapda161d72016-08-19 07:29:46 -0700384 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
385 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000386
danilchapda161d72016-08-19 07:29:46 -0700387 // SR.SenderSSRC
388 // The synchronization source identifier for the originator of this SR packet
niklase@google.com470e71d2011-07-07 08:21:25 +0000389
danilchapda161d72016-08-19 07:29:46 -0700390 // rtcpPacket.RR.SenderSSRC
391 // The source of the packet sender, same as of SR? or is this a CE?
niklase@google.com470e71d2011-07-07 08:21:25 +0000392
danilchapda161d72016-08-19 07:29:46 -0700393 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
394 ? rtcpPacket.RR.SenderSSRC
395 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000396
danilchapda161d72016-08-19 07:29:46 -0700397 rtcpPacketInformation.remoteSSRC = remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000398
danilchapda161d72016-08-19 07:29:46 -0700399 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
400 if (!ptrReceiveInfo) {
401 rtcpParser.Iterate();
402 return;
403 }
404
405 if (rtcpPacketType == RTCPPacketTypes::kSr) {
406 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
407 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
408
409 if (_remoteSSRC ==
410 remoteSSRC) // have I received RTP packets from this party
niklase@google.com470e71d2011-07-07 08:21:25 +0000411 {
danilchapda161d72016-08-19 07:29:46 -0700412 // only signal that we have received a SR when we accept one
413 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
414
415 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
416 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
417 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
418
419 // We will only store the send report from one source, but
420 // we will store all the receive block
421
422 // Save the NTP time of this report
423 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
424 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
425 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
426 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
427 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
428
429 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
430 } else {
431 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
niklase@google.com470e71d2011-07-07 08:21:25 +0000432 }
danilchapda161d72016-08-19 07:29:46 -0700433 } else {
434 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
435 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000436
danilchapda161d72016-08-19 07:29:46 -0700437 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
438 }
439 // Update that this remote is alive.
440 ptrReceiveInfo->last_time_received_ms = _clock->TimeInMilliseconds();
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000441
danilchapda161d72016-08-19 07:29:46 -0700442 rtcpPacketType = rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000443
danilchapda161d72016-08-19 07:29:46 -0700444 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
445 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000446 rtcpPacketType = rtcpParser.Iterate();
danilchapda161d72016-08-19 07:29:46 -0700447 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000448}
449
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000450void RTCPReceiver::HandleReportBlock(
451 const RTCPUtility::RTCPPacket& rtcpPacket,
452 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000453 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000454 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
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.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000465 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
466 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000467 // This block is not for us ignore it.
468 return;
469 }
470
danilchapda161d72016-08-19 07:29:46 -0700471 RTCPReportBlockInformation* reportBlock = CreateOrGetReportBlockInformation(
472 remoteSSRC, rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000473 if (reportBlock == NULL) {
danilchapda161d72016-08-19 07:29:46 -0700474 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation(" << remoteSSRC
475 << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000476 return;
477 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000478
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000479 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000480 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
481 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
482 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
483 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
484 reportBlock->remoteReceiveBlock.cumulativeLost =
485 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000486 if (rb.ExtendedHighestSequenceNumber >
487 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
488 // We have successfully delivered new RTP packets to the remote side after
489 // the last RR was sent from the remote side.
490 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000491 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000492 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
493 rb.ExtendedHighestSequenceNumber;
494 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
495 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
496 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
497
498 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
499 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
500 }
501
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100502 int64_t rtt = 0;
Danil Chapovalova094fd12016-02-22 18:59:36 +0100503 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100504 // RFC3550, section 6.4.1, LSR field discription states:
505 // If no SR has been received yet, the field is set to zero.
506 // Receiver rtp_rtcp module is not expected to calculate rtt using
507 // Sender Reports even if it accidentally can.
508 if (!receiver_only_ && send_time != 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100509 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
510 // Local NTP time.
511 uint32_t receive_time = CompactNtp(NtpTime(*_clock));
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000512
Danil Chapovalova094fd12016-02-22 18:59:36 +0100513 // RTT in 1/(2^16) seconds.
514 uint32_t rtt_ntp = receive_time - delay - send_time;
515 // Convert to 1/1000 seconds (milliseconds).
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100516 rtt = CompactNtpRttToMs(rtt_ntp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100517 if (rtt > reportBlock->maxRTT) {
518 // Store max RTT.
519 reportBlock->maxRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000520 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000521 if (reportBlock->minRTT == 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100522 // First RTT.
523 reportBlock->minRTT = rtt;
524 } else if (rtt < reportBlock->minRTT) {
525 // Store min RTT.
526 reportBlock->minRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000527 }
Danil Chapovalova094fd12016-02-22 18:59:36 +0100528 // Store last RTT.
529 reportBlock->RTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000530
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000531 // store average RTT
532 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000533 float ac = static_cast<float>(reportBlock->numAverageCalcs);
534 float newAverage =
Danil Chapovalova094fd12016-02-22 18:59:36 +0100535 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000536 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000537 } else {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100538 // First RTT.
539 reportBlock->avgRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000540 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000541 reportBlock->numAverageCalcs++;
542 }
543
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000544 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
Danil Chapovalova094fd12016-02-22 18:59:36 +0100545 rtt);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000546
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000547 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000548}
549
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000550RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
551 uint32_t remote_ssrc,
552 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000553 RTCPReportBlockInformation* info =
554 GetReportBlockInformation(remote_ssrc, source_ssrc);
555 if (info == NULL) {
556 info = new RTCPReportBlockInformation;
557 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000558 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000559 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000560}
561
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000562RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
563 uint32_t remote_ssrc,
564 uint32_t source_ssrc) const {
565 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000566 if (it == _receivedReportBlockMap.end()) {
567 return NULL;
568 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000569 const ReportBlockInfoMap* info_map = &(it->second);
570 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
571 if (it_info == info_map->end()) {
572 return NULL;
573 }
574 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000575}
576
danilchapda161d72016-08-19 07:29:46 -0700577RTCPCnameInformation* RTCPReceiver::CreateCnameInformation(
578 uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700579 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000580
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000581 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000582 _receivedCnameMap.find(remoteSSRC);
583
584 if (it != _receivedCnameMap.end()) {
585 return it->second;
586 }
587 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000588 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000589 _receivedCnameMap[remoteSSRC] = cnameInfo;
590 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000591}
592
danilchapda161d72016-08-19 07:29:46 -0700593RTCPCnameInformation* RTCPReceiver::GetCnameInformation(
594 uint32_t remoteSSRC) const {
danilchap7c9426c2016-04-14 03:05:31 -0700595 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000596
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000597 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000598 _receivedCnameMap.find(remoteSSRC);
599
600 if (it == _receivedCnameMap.end()) {
601 return NULL;
602 }
603 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000604}
605
danilchapda161d72016-08-19 07:29:46 -0700606RTCPReceiveInformation* RTCPReceiver::CreateReceiveInformation(
607 uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700608 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000609
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000610 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000611 _receivedInfoMap.find(remoteSSRC);
612
613 if (it != _receivedInfoMap.end()) {
614 return it->second;
615 }
616 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
617 _receivedInfoMap[remoteSSRC] = receiveInfo;
618 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000619}
620
danilchapda161d72016-08-19 07:29:46 -0700621RTCPReceiveInformation* RTCPReceiver::GetReceiveInformation(
622 uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700623 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000624
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000625 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000626 _receivedInfoMap.find(remoteSSRC);
627 if (it == _receivedInfoMap.end()) {
628 return NULL;
629 }
630 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000631}
632
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000633bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
danilchap7c9426c2016-04-14 03:05:31 -0700634 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000635 if (_lastReceivedRrMs == 0)
636 return false;
637
638 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000639 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000640 // Reset the timer to only trigger one log.
641 _lastReceivedRrMs = 0;
642 return true;
643 }
644 return false;
645}
646
647bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
danilchap7c9426c2016-04-14 03:05:31 -0700648 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000649 if (_lastIncreasedSequenceNumberMs == 0)
650 return false;
651
652 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
danilchapda161d72016-08-19 07:29:46 -0700653 if (_clock->TimeInMilliseconds() >
654 _lastIncreasedSequenceNumberMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000655 // Reset the timer to only trigger one log.
656 _lastIncreasedSequenceNumberMs = 0;
657 return true;
658 }
659 return false;
660}
661
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000662bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
danilchap7c9426c2016-04-14 03:05:31 -0700663 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000664
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000665 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000666 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000667
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000668 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000669 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000670
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000671 while (receiveInfoIt != _receivedInfoMap.end()) {
672 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
673 if (receiveInfo == NULL) {
674 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000675 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000676 // time since last received rtcp packet
677 // when we dont have a lastTimeReceived and the object is marked
678 // readyForDelete it's removed from the map
danilchap2b616392016-08-18 06:17:42 -0700679 if (receiveInfo->last_time_received_ms > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000680 /// use audio define since we don't know what interval the remote peer is
681 // using
danilchap2b616392016-08-18 06:17:42 -0700682 if ((timeNow - receiveInfo->last_time_received_ms) >
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000683 5 * RTCP_INTERVAL_AUDIO_MS) {
684 // no rtcp packet for the last five regular intervals, reset limitations
danilchap2b616392016-08-18 06:17:42 -0700685 receiveInfo->ClearTmmbr();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000686 // prevent that we call this over and over again
danilchap2b616392016-08-18 06:17:42 -0700687 receiveInfo->last_time_received_ms = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000688 // send new TMMBN to all channels using the default codec
689 updateBoundingSet = true;
690 }
691 receiveInfoIt++;
danilchap2b616392016-08-18 06:17:42 -0700692 } else if (receiveInfo->ready_for_delete) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000693 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000694 std::map<uint32_t, RTCPReceiveInformation*>::iterator
danilchapda161d72016-08-19 07:29:46 -0700695 receiveInfoItemToBeErased = receiveInfoIt;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000696 receiveInfoIt++;
697 delete receiveInfoItemToBeErased->second;
698 _receivedInfoMap.erase(receiveInfoItemToBeErased);
699 } else {
700 receiveInfoIt++;
701 }
702 }
703 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000704}
705
danilchap2b616392016-08-18 06:17:42 -0700706std::vector<rtcp::TmmbItem> RTCPReceiver::BoundingSet(bool* tmmbr_owner) {
danilchap7c9426c2016-04-14 03:05:31 -0700707 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000708
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000709 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000710 _receivedInfoMap.find(_remoteSSRC);
711
712 if (receiveInfoIt == _receivedInfoMap.end()) {
danilchap2b616392016-08-18 06:17:42 -0700713 return std::vector<rtcp::TmmbItem>();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000714 }
715 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
danilchap2b616392016-08-18 06:17:42 -0700716 RTC_DCHECK(receiveInfo);
717
718 *tmmbr_owner = TMMBRHelp::IsOwner(receiveInfo->tmmbn, main_ssrc_);
719 return receiveInfo->tmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +0000720}
721
Erik Språnga38233a2015-07-24 09:58:18 +0200722void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
723 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000724 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200725 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000726 HandleSDESChunk(rtcpParser);
727 pktType = rtcpParser.Iterate();
728 }
Erik Språnga38233a2015-07-24 09:58:18 +0200729 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000730}
731
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000732void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
733 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
734 RTCPCnameInformation* cnameInfo =
735 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
736 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000737
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000738 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
739 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000740 {
danilchap7c9426c2016-04-14 03:05:31 -0700741 rtc::CritScope lock(&_criticalSectionFeedbacks);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000742 if (stats_callback_ != NULL) {
743 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
744 rtcpPacket.CName.SenderSSRC);
745 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000746 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000747}
748
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000749void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
750 RTCPPacketInformation& rtcpPacketInformation) {
751 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200752 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000753 // Not to us.
754 rtcpParser.Iterate();
755 return;
756 }
757 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000758
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000759 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200760 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000761 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
762 pktType = rtcpParser.Iterate();
763 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000764
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000765 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
766 ++packet_type_counter_.nack_packets;
767 packet_type_counter_.nack_requests = nack_stats_.requests();
768 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
769 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000770}
771
danilchapda161d72016-08-19 07:29:46 -0700772void RTCPReceiver::HandleNACKItem(
773 const RTCPUtility::RTCPPacket& rtcpPacket,
774 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000775 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
776 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000777
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000778 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
779 if (bitMask) {
danilchapda161d72016-08-19 07:29:46 -0700780 for (int i = 1; i <= 16; ++i) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000781 if (bitMask & 0x01) {
782 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
783 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
784 }
danilchapda161d72016-08-19 07:29:46 -0700785 bitMask = bitMask >> 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000786 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000787 }
788 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000789}
790
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000791void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
792 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000793
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000794 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000795 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
796 for (; it != _receivedReportBlockMap.end(); ++it) {
797 ReportBlockInfoMap* info_map = &(it->second);
danilchapda161d72016-08-19 07:29:46 -0700798 ReportBlockInfoMap::iterator it_info =
799 info_map->find(rtcpPacket.BYE.SenderSSRC);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000800 if (it_info != info_map->end()) {
801 delete it_info->second;
802 info_map->erase(it_info);
803 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000804 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000805
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000806 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000807 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000808 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000809
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000810 if (receiveInfoIt != _receivedInfoMap.end()) {
danilchap2b616392016-08-18 06:17:42 -0700811 receiveInfoIt->second->ready_for_delete = true;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000812 }
813
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000814 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000815 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
816
817 if (cnameInfoIt != _receivedCnameMap.end()) {
818 delete cnameInfoIt->second;
819 _receivedCnameMap.erase(cnameInfoIt);
820 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000821 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000822 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000823}
824
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000825void RTCPReceiver::HandleXrHeader(
826 RTCPUtility::RTCPParserV2& parser,
827 RTCPPacketInformation& rtcpPacketInformation) {
828 const RTCPUtility::RTCPPacket& packet = parser.Packet();
829
830 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
831
832 parser.Iterate();
833}
834
835void RTCPReceiver::HandleXrReceiveReferenceTime(
836 RTCPUtility::RTCPParserV2& parser,
837 RTCPPacketInformation& rtcpPacketInformation) {
838 const RTCPUtility::RTCPPacket& packet = parser.Packet();
839
840 _remoteXRReceiveTimeInfo.sourceSSRC =
841 rtcpPacketInformation.xr_originator_ssrc;
842
843 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
844 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
845 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
846
847 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
848
849 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
850
851 parser.Iterate();
852}
853
854void RTCPReceiver::HandleXrDlrrReportBlock(
855 RTCPUtility::RTCPParserV2& parser,
856 RTCPPacketInformation& rtcpPacketInformation) {
857 const RTCPUtility::RTCPPacket& packet = parser.Packet();
858 // Iterate through sub-block(s), if any.
859 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
860
Erik Språng242e22b2015-05-11 10:17:43 +0200861 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000862 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
863 packet_type = parser.Iterate();
864 }
865}
866
867void RTCPReceiver::HandleXrDlrrReportBlockItem(
868 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000869 RTCPPacketInformation& rtcpPacketInformation)
870 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000871 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
872 registered_ssrcs_.end()) {
873 // Not to us.
874 return;
875 }
876
877 rtcpPacketInformation.xr_dlrr_item = true;
878
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100879 // Caller should explicitly enable rtt calculation using extended reports.
880 if (!xr_rrtr_status_)
881 return;
882
Danil Chapovalova094fd12016-02-22 18:59:36 +0100883 // The send_time and delay_rr fields are in units of 1/2^16 sec.
884 uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100885 // RFC3611, section 4.5, LRR field discription states:
Danil Chapovalova094fd12016-02-22 18:59:36 +0100886 // If no such block has been received, the field is set to zero.
887 if (send_time == 0)
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000888 return;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000889
Danil Chapovalova094fd12016-02-22 18:59:36 +0100890 uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
891 uint32_t now = CompactNtp(NtpTime(*_clock));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000892
Danil Chapovalova094fd12016-02-22 18:59:36 +0100893 uint32_t rtt_ntp = now - delay_rr - send_time;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100894 xr_rr_rtt_ms_ = CompactNtpRttToMs(rtt_ntp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000895
896 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
897}
898
danilchapda161d72016-08-19 07:29:46 -0700899void RTCPReceiver::HandleXRVOIPMetric(
900 RTCPUtility::RTCPParserV2& rtcpParser,
901 RTCPPacketInformation& rtcpPacketInformation) {
902 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000903
danilchapda161d72016-08-19 07:29:46 -0700904 if (rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_) {
905 // Store VoIP metrics block if it's about me
906 // from OriginatorSSRC do we filter it?
907 // rtcpPacket.XR.OriginatorSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000908
danilchapda161d72016-08-19 07:29:46 -0700909 RTCPVoIPMetric receivedVoIPMetrics;
910 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
911 receivedVoIPMetrics.burstDuration =
912 rtcpPacket.XRVOIPMetricItem.burstDuration;
913 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
914 receivedVoIPMetrics.endSystemDelay =
915 rtcpPacket.XRVOIPMetricItem.endSystemDelay;
916 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
917 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
918 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
919 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
920 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
921 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
922 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
923 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
924 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
925 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
926 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
927 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
928 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
929 receivedVoIPMetrics.roundTripDelay =
930 rtcpPacket.XRVOIPMetricItem.roundTripDelay;
931 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
932 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
niklase@google.com470e71d2011-07-07 08:21:25 +0000933
danilchapda161d72016-08-19 07:29:46 -0700934 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
niklase@google.com470e71d2011-07-07 08:21:25 +0000935
danilchapda161d72016-08-19 07:29:46 -0700936 rtcpPacketInformation.rtcpPacketTypeFlags |=
937 kRtcpXrVoipMetric; // received signal
938 }
939 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000940}
941
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000942void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
943 RTCPPacketInformation& rtcpPacketInformation) {
944 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000945 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000946 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000947
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000948 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000949 // Received a signal that we need to send a new key frame.
950 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
951 }
952 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000953}
954
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000955void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
956 RTCPPacketInformation& rtcpPacketInformation) {
957 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000958
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000959 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
960 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
961 if (ptrReceiveInfo == NULL) {
962 // This remote SSRC must be saved before.
963 rtcpParser.Iterate();
964 return;
965 }
966 if (rtcpPacket.TMMBR.MediaSSRC) {
967 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
968 // in relay mode this is a valid number
969 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
970 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000971
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000972 // Use packet length to calc max number of TMMBR blocks
973 // each TMMBR block is 8 bytes
974 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +0000975
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000976 // sanity, we can't have more than what's in one packet
977 if (maxNumOfTMMBRBlocks > 200) {
978 assert(false);
979 rtcpParser.Iterate();
980 return;
981 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000982
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000983 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200984 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
danilchapda161d72016-08-19 07:29:46 -0700985 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation,
986 senderSSRC);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000987 pktType = rtcpParser.Iterate();
988 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000989}
990
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000991void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
992 const RTCPUtility::RTCPPacket& rtcpPacket,
993 RTCPPacketInformation& rtcpPacketInformation,
994 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000995 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
996 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
danilchap2b616392016-08-18 06:17:42 -0700997 receiveInfo.InsertTmmbrItem(
998 senderSSRC,
999 rtcp::TmmbItem(rtcpPacket.TMMBRItem.SSRC,
1000 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate * 1000,
1001 rtcpPacket.TMMBRItem.MeasuredOverhead),
1002 _clock->TimeInMilliseconds());
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001003 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1004 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001005}
1006
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001007void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1008 RTCPPacketInformation& rtcpPacketInformation) {
1009 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
danilchapda161d72016-08-19 07:29:46 -07001010 RTCPReceiveInformation* ptrReceiveInfo =
1011 GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001012 if (ptrReceiveInfo == NULL) {
1013 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001014 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001015 return;
1016 }
1017 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1018 // Use packet length to calc max number of TMMBN blocks
1019 // each TMMBN block is 8 bytes
1020 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1021
1022 // sanity, we cant have more than what's in one packet
1023 if (maxNumOfTMMBNBlocks > 200) {
1024 assert(false);
1025 rtcpParser.Iterate();
1026 return;
1027 }
1028
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001029 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001030 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001031 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1032 pktType = rtcpParser.Iterate();
1033 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001034}
1035
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001036void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1037 RTCPPacketInformation& rtcpPacketInformation) {
1038 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1039 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001040}
1041
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001042void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1043 const RTCPUtility::RTCPPacket& rtcpPacket) {
danilchap2b616392016-08-18 06:17:42 -07001044 receiveInfo.tmmbn.emplace_back(
1045 rtcpPacket.TMMBNItem.SSRC,
1046 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate * 1000,
1047 rtcpPacket.TMMBNItem.MeasuredOverhead);
niklase@google.com470e71d2011-07-07 08:21:25 +00001048}
1049
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001050void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1051 RTCPPacketInformation& rtcpPacketInformation) {
1052 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1053 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001054 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001055 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1056 pktType = rtcpParser.Iterate();
1057 }
1058}
1059
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001060void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1061 RTCPPacketInformation& rtcpPacketInformation) {
1062 // in theory there could be multiple slices lost
danilchapda161d72016-08-19 07:29:46 -07001063 rtcpPacketInformation.rtcpPacketTypeFlags |=
1064 kRtcpSli; // received signal that we need to refresh a slice
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001065 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001066}
1067
danilchapda161d72016-08-19 07:29:46 -07001068void RTCPReceiver::HandleRPSI(
1069 RTCPUtility::RTCPParserV2& rtcpParser,
1070 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation) {
1071 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1072 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1073 if (pktType == RTCPPacketTypes::kPsfbRpsiItem) {
1074 if (rtcpPacket.RPSI.NumberOfValidBits % 8 != 0) {
1075 // to us unknown
1076 // continue
1077 rtcpParser.Iterate();
1078 return;
niklase@google.com470e71d2011-07-07 08:21:25 +00001079 }
danilchapda161d72016-08-19 07:29:46 -07001080 // Received signal that we have a confirmed reference picture.
1081 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi;
1082 rtcpPacketInformation.rpsiPictureId = 0;
1083
1084 // convert NativeBitString to rpsiPictureId
1085 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits / 8;
1086 for (uint8_t n = 0; n < (numberOfBytes - 1); n++) {
1087 rtcpPacketInformation.rpsiPictureId +=
1088 (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1089 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1090 }
1091 rtcpPacketInformation.rpsiPictureId +=
1092 (rtcpPacket.RPSI.NativeBitString[numberOfBytes - 1] & 0x7f);
1093 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001094}
1095
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001096void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1097 RTCPPacketInformation& rtcpPacketInformation) {
1098 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001099 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001100 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001101 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001102 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1103 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001104 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001105 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001106}
1107
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001108void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1109 RTCPPacketInformation& rtcpPacketInformation) {
1110 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001111
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001112 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001113 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001114 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1115 pktType = rtcpParser.Iterate();
1116 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001117}
1118
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001119void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1120 RTCPPacketInformation& rtcpPacketInformation) {
1121 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1122 rtcpPacketInformation.interArrivalJitter =
danilchapda161d72016-08-19 07:29:46 -07001123 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001124}
1125
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001126void RTCPReceiver::HandleREMBItem(
1127 RTCPUtility::RTCPParserV2& rtcpParser,
1128 RTCPPacketInformation& rtcpPacketInformation) {
1129 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1130 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1131 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1132 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001133}
1134
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001135void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1136 RTCPPacketInformation& rtcpPacketInformation) {
1137 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1138 RTCPReceiveInformation* ptrReceiveInfo =
1139 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001140
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001141 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001142 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001143 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1144 pktType = rtcpParser.Iterate();
1145 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001146}
1147
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001148void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1149 const RTCPUtility::RTCPPacket& rtcpPacket,
1150 RTCPPacketInformation& rtcpPacketInformation) {
1151 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001152 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001153 return;
1154 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001155
1156 ++packet_type_counter_.fir_packets;
1157
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001158 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1159 // we don't know who this originate from
1160 if (receiveInfo) {
1161 // check if we have reported this FIRSequenceNumber before
1162 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
danilchap2b616392016-08-18 06:17:42 -07001163 receiveInfo->last_fir_sequence_number) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001164 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001165 // sanity; don't go crazy with the callbacks
danilchap2b616392016-08-18 06:17:42 -07001166 if ((now - receiveInfo->last_fir_request_ms) > RTCP_MIN_FRAME_LENGTH_MS) {
1167 receiveInfo->last_fir_request_ms = now;
1168 receiveInfo->last_fir_sequence_number =
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001169 rtcpPacket.FIRItem.CommandSequenceNumber;
1170 // received signal that we need to send a new key frame
1171 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1172 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001173 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001174 } else {
1175 // received signal that we need to send a new key frame
1176 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1177 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001178}
1179
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001180void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1181 RTCPPacketInformation& rtcpPacketInformation) {
1182 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001183
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001184 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1185 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1186 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001187
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001188 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001189}
1190
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001191void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1192 RTCPPacketInformation& rtcpPacketInformation) {
1193 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001194
danilchapda161d72016-08-19 07:29:46 -07001195 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data,
1196 rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001197
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001198 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001199}
1200
Erik Språng6b8d3552015-09-24 15:06:57 +02001201void RTCPReceiver::HandleTransportFeedback(
1202 RTCPUtility::RTCPParserV2* rtcp_parser,
1203 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1204 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1205 RTC_DCHECK(packet != nullptr);
1206 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1207 rtcp_packet_information->transport_feedback_.reset(
1208 static_cast<rtcp::TransportFeedback*>(packet));
1209
1210 rtcp_parser->Iterate();
1211}
danilchap287e5482016-08-16 15:15:39 -07001212
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001213int32_t RTCPReceiver::UpdateTMMBR() {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001214 // Find bounding set
danilchap2f69ce92016-08-16 03:21:38 -07001215 std::vector<rtcp::TmmbItem> bounding =
danilchap287e5482016-08-16 15:15:39 -07001216 TMMBRHelp::FindBoundingSet(TMMBRReceived());
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001217 // Set bounding set
1218 // Inform remote clients about the new bandwidth
1219 // inform the remote client
Danil Chapovalovdaa90a72016-08-10 11:29:50 +02001220 _rtpRtcp.SetTMMBN(&bounding);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001221
1222 // might trigger a TMMBN
Danil Chapovalovdaa90a72016-08-10 11:29:50 +02001223 if (bounding.empty()) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001224 // owner of max bitrate request has timed out
1225 // empty bounding set has been sent
1226 return 0;
1227 }
danilchap2f69ce92016-08-16 03:21:38 -07001228 // We have a new bandwidth estimate on this channel.
1229 if (_cbRtcpBandwidthObserver) {
1230 uint64_t bitrate_bps = TMMBRHelp::CalcMinBitrateBps(bounding);
1231 if (bitrate_bps <= std::numeric_limits<uint32_t>::max())
1232 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate_bps);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001233 }
1234 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001235}
1236
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001237void RTCPReceiver::RegisterRtcpStatisticsCallback(
1238 RtcpStatisticsCallback* callback) {
danilchap7c9426c2016-04-14 03:05:31 -07001239 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001240 stats_callback_ = callback;
1241}
1242
1243RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
danilchap7c9426c2016-04-14 03:05:31 -07001244 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001245 return stats_callback_;
1246}
1247
niklase@google.com470e71d2011-07-07 08:21:25 +00001248// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001249void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001250 RTCPPacketInformation& rtcpPacketInformation) {
1251 // Process TMMBR and REMB first to avoid multiple callbacks
1252 // to OnNetworkChanged.
1253 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001254 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1255 UpdateTMMBR();
1256 }
sprang7dc39f32015-10-13 09:17:48 -07001257 uint32_t local_ssrc;
1258 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001259 {
1260 // We don't want to hold this critsect when triggering the callbacks below.
danilchap7c9426c2016-04-14 03:05:31 -07001261 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001262 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001263 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001264 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001265 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001266 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001267 _rtpRtcp.OnRequestSendReport();
1268 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001269 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001270 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001271 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001272 LOG(LS_VERBOSE) << "Incoming NACK length: "
danilchapda161d72016-08-19 07:29:46 -07001273 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001274 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001275 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001276 }
1277 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001278 // We need feedback that we have received a report block(s) so that we
1279 // can generate a new packet in a conference relay scenario, one received
1280 // report can generate several RTCP packets, based on number relayed/mixed
1281 // a send report block should go out to all receivers.
1282 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001283 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001284 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1285 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1286 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001287 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001288 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001289 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001290 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001291 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001292 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001293 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001294 }
1295 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1296 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001297 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001298 }
1299 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1300 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001301 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001302 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001303 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001304 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001305 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001306 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001307 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001308 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001309 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1310 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1311 }
Erik Språng242e22b2015-05-11 10:17:43 +02001312 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1313 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001314 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001315 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
danilchapda161d72016-08-19 07:29:46 -07001316 rtcpPacketInformation.report_blocks, rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001317 now);
1318 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001319 }
isheriff6b4b5f32016-06-08 00:24:21 -07001320 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1321 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
1322 _rtpRtcp.OnReceivedRtcpReportBlocks(rtcpPacketInformation.report_blocks);
1323 }
1324
Erik Språng6b8d3552015-09-24 15:06:57 +02001325 if (_cbTransportFeedbackObserver &&
1326 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1327 uint32_t media_source_ssrc =
1328 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001329 if (media_source_ssrc == local_ssrc ||
1330 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001331 _cbTransportFeedbackObserver->OnTransportFeedback(
1332 *rtcpPacketInformation.transport_feedback_.get());
1333 }
1334 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001335 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001336
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001337 if (!receiver_only_) {
danilchap7c9426c2016-04-14 03:05:31 -07001338 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001339 if (stats_callback_) {
1340 for (ReportBlockList::const_iterator it =
danilchapda161d72016-08-19 07:29:46 -07001341 rtcpPacketInformation.report_blocks.begin();
1342 it != rtcpPacketInformation.report_blocks.end(); ++it) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001343 RtcpStatistics stats;
1344 stats.cumulative_lost = it->cumulativeLost;
1345 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1346 stats.fraction_lost = it->fractionLost;
1347 stats.jitter = it->jitter;
1348
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001349 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001350 }
1351 }
1352 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001353}
1354
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001355int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001356 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001357 assert(cName);
1358
danilchap7c9426c2016-04-14 03:05:31 -07001359 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001360 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001361 if (cnameInfo == NULL) {
1362 return -1;
1363 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001364 cName[RTCP_CNAME_SIZE - 1] = 0;
1365 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1366 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001367}
1368
danilchap287e5482016-08-16 15:15:39 -07001369std::vector<rtcp::TmmbItem> RTCPReceiver::TMMBRReceived() const {
danilchap7c9426c2016-04-14 03:05:31 -07001370 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
danilchap287e5482016-08-16 15:15:39 -07001371 std::vector<rtcp::TmmbItem> candidates;
niklase@google.com470e71d2011-07-07 08:21:25 +00001372
danilchap287e5482016-08-16 15:15:39 -07001373 int64_t now_ms = _clock->TimeInMilliseconds();
1374
1375 for (const auto& kv : _receivedInfoMap) {
1376 RTCPReceiveInformation* receive_info = kv.second;
1377 RTC_DCHECK(receive_info);
danilchap2b616392016-08-18 06:17:42 -07001378 receive_info->GetTmmbrSet(now_ms, &candidates);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001379 }
danilchap287e5482016-08-16 15:15:39 -07001380 return candidates;
niklase@google.com470e71d2011-07-07 08:21:25 +00001381}
1382
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001383} // namespace webrtc