blob: 4d30bb0784742926b929b6ab936f778b14ab950f [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"
Danil Chapovalova094fd12016-02-22 18:59:36 +010023#include "webrtc/modules/rtp_rtcp/source/time_util.h"
danilchap13deaad2016-05-24 13:25:27 -070024#include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010025#include "webrtc/system_wrappers/include/ntp_time.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000026
niklase@google.com470e71d2011-07-07 08:21:25 +000027namespace webrtc {
danilchap6a6f0892015-12-10 12:39:08 -080028using RTCPHelp::RTCPPacketInformation;
29using RTCPHelp::RTCPReceiveInformation;
30using RTCPHelp::RTCPReportBlockInformation;
31using RTCPUtility::kBtVoipMetric;
32using RTCPUtility::RTCPCnameInformation;
33using RTCPUtility::RTCPPacketReportBlockItem;
34using RTCPUtility::RTCPPacketTypes;
niklase@google.com470e71d2011-07-07 08:21:25 +000035
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000036// The number of RTCP time intervals needed to trigger a timeout.
37const int kRrTimeoutIntervals = 3;
38
Erik Språng6b8d3552015-09-24 15:06:57 +020039const int64_t kMaxWarningLogIntervalMs = 10000;
40
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000041RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000042 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020043 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000044 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000045 RtcpBandwidthObserver* rtcp_bandwidth_observer,
46 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020047 TransportFeedbackObserver* transport_feedback_observer,
danilchap59cb2bd2016-08-29 11:08:47 -070048 ModuleRtpRtcp* owner)
danilchap13deaad2016-05-24 13:25:27 -070049 : _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020050 receiver_only_(receiver_only),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000051 _lastReceived(0),
52 _rtpRtcp(*owner),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000053 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
54 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020055 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000056 main_ssrc_(0),
57 _remoteSSRC(0),
58 _remoteSenderInfo(),
59 _lastReceivedSRNTPsecs(0),
60 _lastReceivedSRNTPfrac(0),
61 _lastReceivedXRNTPsecs(0),
62 _lastReceivedXRNTPfrac(0),
Danil Chapovalovc1e55c72016-03-09 15:14:35 +010063 xr_rrtr_status_(false),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000064 xr_rr_rtt_ms_(0),
65 _receivedInfoMap(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000066 _lastReceivedRrMs(0),
67 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000068 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020069 packet_type_counter_observer_(packet_type_counter_observer),
70 num_skipped_packets_(0),
71 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000072 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000073}
74
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000075RTCPReceiver::~RTCPReceiver() {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000076 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
77 for (; it != _receivedReportBlockMap.end(); ++it) {
78 ReportBlockInfoMap* info_map = &(it->second);
79 while (!info_map->empty()) {
80 ReportBlockInfoMap::iterator it_info = info_map->begin();
81 delete it_info->second;
82 info_map->erase(it_info);
83 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000084 }
85 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000086 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000087 _receivedInfoMap.begin();
88 delete first->second;
89 _receivedInfoMap.erase(first);
90 }
91 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000092 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000093 _receivedCnameMap.begin();
94 delete first->second;
95 _receivedCnameMap.erase(first);
96 }
niklase@google.com470e71d2011-07-07 08:21:25 +000097}
98
danilchap59cb2bd2016-08-29 11:08:47 -070099bool RTCPReceiver::IncomingPacket(const uint8_t* packet, size_t packet_size) {
100 // Allow receive of non-compound RTCP packets.
101 RTCPUtility::RTCPParserV2 rtcp_parser(packet, packet_size, true);
102
103 if (!rtcp_parser.IsValid()) {
104 LOG(LS_WARNING) << "Incoming invalid RTCP packet";
105 return false;
106 }
107 RTCPHelp::RTCPPacketInformation rtcp_packet_information;
108 IncomingRTCPPacket(rtcp_packet_information, &rtcp_parser);
109 TriggerCallbacksFromRTCPPacket(rtcp_packet_information);
110 return true;
111}
112
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000113int64_t RTCPReceiver::LastReceived() {
danilchap7c9426c2016-04-14 03:05:31 -0700114 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000115 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000116}
117
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000118int64_t RTCPReceiver::LastReceivedReceiverReport() const {
danilchap7c9426c2016-04-14 03:05:31 -0700119 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000120 int64_t last_received_rr = -1;
121 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
122 it != _receivedInfoMap.end(); ++it) {
danilchap2b616392016-08-18 06:17:42 -0700123 if (it->second->last_time_received_ms > last_received_rr) {
124 last_received_rr = it->second->last_time_received_ms;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000125 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000126 }
127 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000128}
129
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000130void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
danilchap7c9426c2016-04-14 03:05:31 -0700131 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000132
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000133 // new SSRC reset old reports
134 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
135 _lastReceivedSRNTPsecs = 0;
136 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000137
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000138 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000139}
140
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000141uint32_t RTCPReceiver::RemoteSSRC() const {
danilchap7c9426c2016-04-14 03:05:31 -0700142 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000143 return _remoteSSRC;
144}
145
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000146void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
147 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000148 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000149 {
danilchap7c9426c2016-04-14 03:05:31 -0700150 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000151 old_ssrc = main_ssrc_;
152 main_ssrc_ = main_ssrc;
153 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000154 }
155 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000156 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
157 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000158 }
159 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000160}
161
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000162int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000163 int64_t* RTT,
164 int64_t* avgRTT,
165 int64_t* minRTT,
166 int64_t* maxRTT) const {
danilchap7c9426c2016-04-14 03:05:31 -0700167 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000168
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000169 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000170 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000171
172 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000173 return -1;
174 }
175 if (RTT) {
176 *RTT = reportBlock->RTT;
177 }
178 if (avgRTT) {
179 *avgRTT = reportBlock->avgRTT;
180 }
181 if (minRTT) {
182 *minRTT = reportBlock->minRTT;
183 }
184 if (maxRTT) {
185 *maxRTT = reportBlock->maxRTT;
186 }
187 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000188}
189
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100190void RTCPReceiver::SetRtcpXrRrtrStatus(bool enable) {
danilchap7c9426c2016-04-14 03:05:31 -0700191 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100192 xr_rrtr_status_ = enable;
193}
194
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000195bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000196 assert(rtt_ms);
danilchap7c9426c2016-04-14 03:05:31 -0700197 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000198 if (xr_rr_rtt_ms_ == 0) {
199 return false;
200 }
201 *rtt_ms = xr_rr_rtt_ms_;
202 xr_rr_rtt_ms_ = 0;
203 return true;
204}
205
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000206// TODO(pbos): Make this fail when we haven't received NTP.
207bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
208 uint32_t* ReceivedNTPfrac,
209 uint32_t* RTCPArrivalTimeSecs,
210 uint32_t* RTCPArrivalTimeFrac,
danilchapda161d72016-08-19 07:29:46 -0700211 uint32_t* rtcp_timestamp) const {
212 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
213 if (ReceivedNTPsecs) {
214 *ReceivedNTPsecs =
215 _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
216 }
217 if (ReceivedNTPfrac) {
218 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
219 }
220 if (RTCPArrivalTimeFrac) {
221 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we
222 // received a RTCP packet
223 // with a send block
224 }
225 if (RTCPArrivalTimeSecs) {
226 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
227 }
228 if (rtcp_timestamp) {
229 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
230 }
231 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000232}
233
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000234bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
235 RtcpReceiveTimeInfo* info) const {
236 assert(info);
danilchap7c9426c2016-04-14 03:05:31 -0700237 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000238 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
239 return false;
240 }
241
242 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
243 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
244
245 // Get the delay since last received report (RFC 3611).
danilchapda161d72016-08-19 07:29:46 -0700246 uint32_t receive_time =
247 RTCPUtility::MidNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000248
249 uint32_t ntp_sec = 0;
250 uint32_t ntp_frac = 0;
251 _clock->CurrentNtp(ntp_sec, ntp_frac);
252 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
253
254 info->delaySinceLastRR = now - receive_time;
255 return true;
256}
257
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000258int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
259 assert(senderInfo);
danilchap7c9426c2016-04-14 03:05:31 -0700260 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000261 if (_lastReceivedSRNTPsecs == 0) {
262 return -1;
263 }
264 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
265 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000266}
267
268// statistics
269// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000270int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000271 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000272 assert(receiveBlocks);
danilchap7c9426c2016-04-14 03:05:31 -0700273 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000274 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
275 for (; it != _receivedReportBlockMap.end(); ++it) {
276 const ReportBlockInfoMap* info_map = &(it->second);
277 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
278 for (; it_info != info_map->end(); ++it_info) {
279 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
280 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000281 }
282 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000283}
284
danilchapda161d72016-08-19 07:29:46 -0700285int32_t RTCPReceiver::IncomingRTCPPacket(
286 RTCPPacketInformation& rtcpPacketInformation,
287 RTCPUtility::RTCPParserV2* rtcpParser) {
288 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000289
danilchapda161d72016-08-19 07:29:46 -0700290 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000291
danilchapda161d72016-08-19 07:29:46 -0700292 if (packet_type_counter_.first_packet_time_ms == -1) {
293 packet_type_counter_.first_packet_time_ms = _lastReceived;
294 }
295
296 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
297 while (pktType != RTCPPacketTypes::kInvalid) {
298 // Each "case" is responsible for iterate the parser to the
299 // next top level packet.
300 switch (pktType) {
301 case RTCPPacketTypes::kSr:
302 case RTCPPacketTypes::kRr:
303 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
304 break;
305 case RTCPPacketTypes::kSdes:
306 HandleSDES(*rtcpParser, rtcpPacketInformation);
307 break;
308 case RTCPPacketTypes::kXrHeader:
309 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
310 break;
311 case RTCPPacketTypes::kXrReceiverReferenceTime:
312 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
313 break;
314 case RTCPPacketTypes::kXrDlrrReportBlock:
315 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
316 break;
317 case RTCPPacketTypes::kXrVoipMetric:
318 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
319 break;
320 case RTCPPacketTypes::kBye:
321 HandleBYE(*rtcpParser);
322 break;
323 case RTCPPacketTypes::kRtpfbNack:
324 HandleNACK(*rtcpParser, rtcpPacketInformation);
325 break;
326 case RTCPPacketTypes::kRtpfbTmmbr:
327 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
328 break;
329 case RTCPPacketTypes::kRtpfbTmmbn:
330 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
331 break;
332 case RTCPPacketTypes::kRtpfbSrReq:
333 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
334 break;
335 case RTCPPacketTypes::kPsfbPli:
336 HandlePLI(*rtcpParser, rtcpPacketInformation);
337 break;
338 case RTCPPacketTypes::kPsfbSli:
339 HandleSLI(*rtcpParser, rtcpPacketInformation);
340 break;
341 case RTCPPacketTypes::kPsfbRpsi:
342 HandleRPSI(*rtcpParser, rtcpPacketInformation);
343 break;
344 case RTCPPacketTypes::kExtendedIj:
345 HandleIJ(*rtcpParser, rtcpPacketInformation);
346 break;
347 case RTCPPacketTypes::kPsfbFir:
348 HandleFIR(*rtcpParser, rtcpPacketInformation);
349 break;
350 case RTCPPacketTypes::kPsfbApp:
351 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
352 break;
353 case RTCPPacketTypes::kApp:
354 // generic application messages
355 HandleAPP(*rtcpParser, rtcpPacketInformation);
356 break;
357 case RTCPPacketTypes::kAppItem:
358 // generic application messages
359 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
360 break;
361 case RTCPPacketTypes::kTransportFeedback:
362 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
363 break;
364 default:
365 rtcpParser->Iterate();
366 break;
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000367 }
danilchapda161d72016-08-19 07:29:46 -0700368 pktType = rtcpParser->PacketType();
369 }
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000370
danilchapda161d72016-08-19 07:29:46 -0700371 if (packet_type_counter_observer_ != NULL) {
372 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
373 main_ssrc_, packet_type_counter_);
374 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000375
danilchapda161d72016-08-19 07:29:46 -0700376 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000377
danilchapda161d72016-08-19 07:29:46 -0700378 int64_t now = _clock->TimeInMilliseconds();
379 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
380 num_skipped_packets_ > 0) {
381 last_skipped_packets_warning_ = now;
382 LOG(LS_WARNING) << num_skipped_packets_
383 << " RTCP blocks were skipped due to being malformed or of "
384 "unrecognized/unsupported type, during the past "
385 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
386 }
Erik Språng6b8d3552015-09-24 15:06:57 +0200387
danilchapda161d72016-08-19 07:29:46 -0700388 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000389}
390
danilchapda161d72016-08-19 07:29:46 -0700391void RTCPReceiver::HandleSenderReceiverReport(
392 RTCPUtility::RTCPParserV2& rtcpParser,
393 RTCPPacketInformation& rtcpPacketInformation) {
394 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
395 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000396
danilchapda161d72016-08-19 07:29:46 -0700397 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
398 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000399
danilchapda161d72016-08-19 07:29:46 -0700400 // SR.SenderSSRC
401 // The synchronization source identifier for the originator of this SR packet
niklase@google.com470e71d2011-07-07 08:21:25 +0000402
danilchapda161d72016-08-19 07:29:46 -0700403 // rtcpPacket.RR.SenderSSRC
404 // The source of the packet sender, same as of SR? or is this a CE?
niklase@google.com470e71d2011-07-07 08:21:25 +0000405
danilchapda161d72016-08-19 07:29:46 -0700406 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
407 ? rtcpPacket.RR.SenderSSRC
408 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000409
danilchapda161d72016-08-19 07:29:46 -0700410 rtcpPacketInformation.remoteSSRC = remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000411
danilchapda161d72016-08-19 07:29:46 -0700412 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
413 if (!ptrReceiveInfo) {
414 rtcpParser.Iterate();
415 return;
416 }
417
418 if (rtcpPacketType == RTCPPacketTypes::kSr) {
419 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
420 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
421
422 if (_remoteSSRC ==
423 remoteSSRC) // have I received RTP packets from this party
niklase@google.com470e71d2011-07-07 08:21:25 +0000424 {
danilchapda161d72016-08-19 07:29:46 -0700425 // only signal that we have received a SR when we accept one
426 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
427
428 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
429 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
430 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
431
432 // We will only store the send report from one source, but
433 // we will store all the receive block
434
435 // Save the NTP time of this report
436 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
437 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
438 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
439 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
440 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
441
442 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
443 } else {
444 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
niklase@google.com470e71d2011-07-07 08:21:25 +0000445 }
danilchapda161d72016-08-19 07:29:46 -0700446 } else {
447 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
448 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000449
danilchapda161d72016-08-19 07:29:46 -0700450 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
451 }
452 // Update that this remote is alive.
453 ptrReceiveInfo->last_time_received_ms = _clock->TimeInMilliseconds();
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000454
danilchapda161d72016-08-19 07:29:46 -0700455 rtcpPacketType = rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000456
danilchapda161d72016-08-19 07:29:46 -0700457 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
458 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000459 rtcpPacketType = rtcpParser.Iterate();
danilchapda161d72016-08-19 07:29:46 -0700460 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000461}
462
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000463void RTCPReceiver::HandleReportBlock(
464 const RTCPUtility::RTCPPacket& rtcpPacket,
465 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000466 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000467 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000468 // This will be called once per report block in the RTCP packet.
469 // We filter out all report blocks that are not for us.
470 // Each packet has max 31 RR blocks.
471 //
472 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000473
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000474 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
475 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000476
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000477 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000478 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
479 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000480 // This block is not for us ignore it.
481 return;
482 }
483
danilchapda161d72016-08-19 07:29:46 -0700484 RTCPReportBlockInformation* reportBlock = CreateOrGetReportBlockInformation(
485 remoteSSRC, rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000486 if (reportBlock == NULL) {
danilchapda161d72016-08-19 07:29:46 -0700487 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation(" << remoteSSRC
488 << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000489 return;
490 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000491
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000492 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000493 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
494 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
495 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
496 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
497 reportBlock->remoteReceiveBlock.cumulativeLost =
498 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000499 if (rb.ExtendedHighestSequenceNumber >
500 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
501 // We have successfully delivered new RTP packets to the remote side after
502 // the last RR was sent from the remote side.
503 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000504 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000505 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
506 rb.ExtendedHighestSequenceNumber;
507 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
508 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
509 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
510
511 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
512 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
513 }
514
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100515 int64_t rtt = 0;
Danil Chapovalova094fd12016-02-22 18:59:36 +0100516 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100517 // RFC3550, section 6.4.1, LSR field discription states:
518 // If no SR has been received yet, the field is set to zero.
519 // Receiver rtp_rtcp module is not expected to calculate rtt using
520 // Sender Reports even if it accidentally can.
521 if (!receiver_only_ && send_time != 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100522 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
523 // Local NTP time.
524 uint32_t receive_time = CompactNtp(NtpTime(*_clock));
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000525
Danil Chapovalova094fd12016-02-22 18:59:36 +0100526 // RTT in 1/(2^16) seconds.
527 uint32_t rtt_ntp = receive_time - delay - send_time;
528 // Convert to 1/1000 seconds (milliseconds).
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100529 rtt = CompactNtpRttToMs(rtt_ntp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100530 if (rtt > reportBlock->maxRTT) {
531 // Store max RTT.
532 reportBlock->maxRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000533 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000534 if (reportBlock->minRTT == 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100535 // First RTT.
536 reportBlock->minRTT = rtt;
537 } else if (rtt < reportBlock->minRTT) {
538 // Store min RTT.
539 reportBlock->minRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000540 }
Danil Chapovalova094fd12016-02-22 18:59:36 +0100541 // Store last RTT.
542 reportBlock->RTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000543
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000544 // store average RTT
545 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000546 float ac = static_cast<float>(reportBlock->numAverageCalcs);
547 float newAverage =
Danil Chapovalova094fd12016-02-22 18:59:36 +0100548 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000549 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000550 } else {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100551 // First RTT.
552 reportBlock->avgRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000553 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000554 reportBlock->numAverageCalcs++;
555 }
556
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000557 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
Danil Chapovalova094fd12016-02-22 18:59:36 +0100558 rtt);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000559
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000560 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000561}
562
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000563RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
564 uint32_t remote_ssrc,
565 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000566 RTCPReportBlockInformation* info =
567 GetReportBlockInformation(remote_ssrc, source_ssrc);
568 if (info == NULL) {
569 info = new RTCPReportBlockInformation;
570 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000571 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000572 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000573}
574
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000575RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
576 uint32_t remote_ssrc,
577 uint32_t source_ssrc) const {
578 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000579 if (it == _receivedReportBlockMap.end()) {
580 return NULL;
581 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000582 const ReportBlockInfoMap* info_map = &(it->second);
583 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
584 if (it_info == info_map->end()) {
585 return NULL;
586 }
587 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000588}
589
danilchapda161d72016-08-19 07:29:46 -0700590RTCPCnameInformation* RTCPReceiver::CreateCnameInformation(
591 uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700592 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000593
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000594 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000595 _receivedCnameMap.find(remoteSSRC);
596
597 if (it != _receivedCnameMap.end()) {
598 return it->second;
599 }
600 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000601 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000602 _receivedCnameMap[remoteSSRC] = cnameInfo;
603 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000604}
605
danilchapda161d72016-08-19 07:29:46 -0700606RTCPCnameInformation* RTCPReceiver::GetCnameInformation(
607 uint32_t remoteSSRC) const {
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, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000611 _receivedCnameMap.find(remoteSSRC);
612
613 if (it == _receivedCnameMap.end()) {
614 return NULL;
615 }
616 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000617}
618
danilchapda161d72016-08-19 07:29:46 -0700619RTCPReceiveInformation* RTCPReceiver::CreateReceiveInformation(
620 uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700621 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000622
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000623 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000624 _receivedInfoMap.find(remoteSSRC);
625
626 if (it != _receivedInfoMap.end()) {
627 return it->second;
628 }
629 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
630 _receivedInfoMap[remoteSSRC] = receiveInfo;
631 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000632}
633
danilchapda161d72016-08-19 07:29:46 -0700634RTCPReceiveInformation* RTCPReceiver::GetReceiveInformation(
635 uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700636 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000637
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000638 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000639 _receivedInfoMap.find(remoteSSRC);
640 if (it == _receivedInfoMap.end()) {
641 return NULL;
642 }
643 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000644}
645
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000646bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
danilchap7c9426c2016-04-14 03:05:31 -0700647 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000648 if (_lastReceivedRrMs == 0)
649 return false;
650
651 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000652 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000653 // Reset the timer to only trigger one log.
654 _lastReceivedRrMs = 0;
655 return true;
656 }
657 return false;
658}
659
660bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
danilchap7c9426c2016-04-14 03:05:31 -0700661 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000662 if (_lastIncreasedSequenceNumberMs == 0)
663 return false;
664
665 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
danilchapda161d72016-08-19 07:29:46 -0700666 if (_clock->TimeInMilliseconds() >
667 _lastIncreasedSequenceNumberMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000668 // Reset the timer to only trigger one log.
669 _lastIncreasedSequenceNumberMs = 0;
670 return true;
671 }
672 return false;
673}
674
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000675bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
danilchap7c9426c2016-04-14 03:05:31 -0700676 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000677
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000678 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000679 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000680
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000681 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000682 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000683
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000684 while (receiveInfoIt != _receivedInfoMap.end()) {
685 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
686 if (receiveInfo == NULL) {
687 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000688 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000689 // time since last received rtcp packet
690 // when we dont have a lastTimeReceived and the object is marked
691 // readyForDelete it's removed from the map
danilchap2b616392016-08-18 06:17:42 -0700692 if (receiveInfo->last_time_received_ms > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000693 /// use audio define since we don't know what interval the remote peer is
694 // using
danilchap2b616392016-08-18 06:17:42 -0700695 if ((timeNow - receiveInfo->last_time_received_ms) >
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000696 5 * RTCP_INTERVAL_AUDIO_MS) {
697 // no rtcp packet for the last five regular intervals, reset limitations
danilchap2b616392016-08-18 06:17:42 -0700698 receiveInfo->ClearTmmbr();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000699 // prevent that we call this over and over again
danilchap2b616392016-08-18 06:17:42 -0700700 receiveInfo->last_time_received_ms = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000701 // send new TMMBN to all channels using the default codec
702 updateBoundingSet = true;
703 }
704 receiveInfoIt++;
danilchap2b616392016-08-18 06:17:42 -0700705 } else if (receiveInfo->ready_for_delete) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000706 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000707 std::map<uint32_t, RTCPReceiveInformation*>::iterator
danilchapda161d72016-08-19 07:29:46 -0700708 receiveInfoItemToBeErased = receiveInfoIt;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000709 receiveInfoIt++;
710 delete receiveInfoItemToBeErased->second;
711 _receivedInfoMap.erase(receiveInfoItemToBeErased);
712 } else {
713 receiveInfoIt++;
714 }
715 }
716 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000717}
718
danilchap2b616392016-08-18 06:17:42 -0700719std::vector<rtcp::TmmbItem> RTCPReceiver::BoundingSet(bool* tmmbr_owner) {
danilchap7c9426c2016-04-14 03:05:31 -0700720 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000721
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000722 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000723 _receivedInfoMap.find(_remoteSSRC);
724
725 if (receiveInfoIt == _receivedInfoMap.end()) {
danilchap2b616392016-08-18 06:17:42 -0700726 return std::vector<rtcp::TmmbItem>();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000727 }
728 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
danilchap2b616392016-08-18 06:17:42 -0700729 RTC_DCHECK(receiveInfo);
730
731 *tmmbr_owner = TMMBRHelp::IsOwner(receiveInfo->tmmbn, main_ssrc_);
732 return receiveInfo->tmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +0000733}
734
Erik Språnga38233a2015-07-24 09:58:18 +0200735void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
736 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000737 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200738 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000739 HandleSDESChunk(rtcpParser);
740 pktType = rtcpParser.Iterate();
741 }
Erik Språnga38233a2015-07-24 09:58:18 +0200742 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000743}
744
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000745void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
746 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
747 RTCPCnameInformation* cnameInfo =
748 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
749 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000750
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000751 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
752 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000753 {
danilchap7c9426c2016-04-14 03:05:31 -0700754 rtc::CritScope lock(&_criticalSectionFeedbacks);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000755 if (stats_callback_ != NULL) {
756 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
757 rtcpPacket.CName.SenderSSRC);
758 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000759 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000760}
761
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000762void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
763 RTCPPacketInformation& rtcpPacketInformation) {
764 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200765 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000766 // Not to us.
767 rtcpParser.Iterate();
768 return;
769 }
770 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000771
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000772 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200773 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000774 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
775 pktType = rtcpParser.Iterate();
776 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000777
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000778 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
779 ++packet_type_counter_.nack_packets;
780 packet_type_counter_.nack_requests = nack_stats_.requests();
781 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
782 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000783}
784
danilchapda161d72016-08-19 07:29:46 -0700785void RTCPReceiver::HandleNACKItem(
786 const RTCPUtility::RTCPPacket& rtcpPacket,
787 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000788 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
789 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000790
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000791 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
792 if (bitMask) {
danilchapda161d72016-08-19 07:29:46 -0700793 for (int i = 1; i <= 16; ++i) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000794 if (bitMask & 0x01) {
795 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
796 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
797 }
danilchapda161d72016-08-19 07:29:46 -0700798 bitMask = bitMask >> 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000799 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000800 }
801 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000802}
803
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000804void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
805 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000806
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000807 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000808 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
809 for (; it != _receivedReportBlockMap.end(); ++it) {
810 ReportBlockInfoMap* info_map = &(it->second);
danilchapda161d72016-08-19 07:29:46 -0700811 ReportBlockInfoMap::iterator it_info =
812 info_map->find(rtcpPacket.BYE.SenderSSRC);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000813 if (it_info != info_map->end()) {
814 delete it_info->second;
815 info_map->erase(it_info);
816 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000817 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000818
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000819 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000820 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000821 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000822
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000823 if (receiveInfoIt != _receivedInfoMap.end()) {
danilchap2b616392016-08-18 06:17:42 -0700824 receiveInfoIt->second->ready_for_delete = true;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000825 }
826
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000827 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000828 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
829
830 if (cnameInfoIt != _receivedCnameMap.end()) {
831 delete cnameInfoIt->second;
832 _receivedCnameMap.erase(cnameInfoIt);
833 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000834 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000835 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000836}
837
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000838void RTCPReceiver::HandleXrHeader(
839 RTCPUtility::RTCPParserV2& parser,
840 RTCPPacketInformation& rtcpPacketInformation) {
841 const RTCPUtility::RTCPPacket& packet = parser.Packet();
842
843 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
844
845 parser.Iterate();
846}
847
848void RTCPReceiver::HandleXrReceiveReferenceTime(
849 RTCPUtility::RTCPParserV2& parser,
850 RTCPPacketInformation& rtcpPacketInformation) {
851 const RTCPUtility::RTCPPacket& packet = parser.Packet();
852
853 _remoteXRReceiveTimeInfo.sourceSSRC =
854 rtcpPacketInformation.xr_originator_ssrc;
855
856 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
857 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
858 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
859
860 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
861
862 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
863
864 parser.Iterate();
865}
866
867void RTCPReceiver::HandleXrDlrrReportBlock(
868 RTCPUtility::RTCPParserV2& parser,
869 RTCPPacketInformation& rtcpPacketInformation) {
870 const RTCPUtility::RTCPPacket& packet = parser.Packet();
871 // Iterate through sub-block(s), if any.
872 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
873
Erik Språng242e22b2015-05-11 10:17:43 +0200874 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000875 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
876 packet_type = parser.Iterate();
877 }
878}
879
880void RTCPReceiver::HandleXrDlrrReportBlockItem(
881 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000882 RTCPPacketInformation& rtcpPacketInformation)
883 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000884 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
885 registered_ssrcs_.end()) {
886 // Not to us.
887 return;
888 }
889
890 rtcpPacketInformation.xr_dlrr_item = true;
891
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100892 // Caller should explicitly enable rtt calculation using extended reports.
893 if (!xr_rrtr_status_)
894 return;
895
Danil Chapovalova094fd12016-02-22 18:59:36 +0100896 // The send_time and delay_rr fields are in units of 1/2^16 sec.
897 uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100898 // RFC3611, section 4.5, LRR field discription states:
Danil Chapovalova094fd12016-02-22 18:59:36 +0100899 // If no such block has been received, the field is set to zero.
900 if (send_time == 0)
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000901 return;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000902
Danil Chapovalova094fd12016-02-22 18:59:36 +0100903 uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
904 uint32_t now = CompactNtp(NtpTime(*_clock));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000905
Danil Chapovalova094fd12016-02-22 18:59:36 +0100906 uint32_t rtt_ntp = now - delay_rr - send_time;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100907 xr_rr_rtt_ms_ = CompactNtpRttToMs(rtt_ntp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000908
909 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
910}
911
danilchapda161d72016-08-19 07:29:46 -0700912void RTCPReceiver::HandleXRVOIPMetric(
913 RTCPUtility::RTCPParserV2& rtcpParser,
914 RTCPPacketInformation& rtcpPacketInformation) {
915 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000916
danilchapda161d72016-08-19 07:29:46 -0700917 if (rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_) {
918 // Store VoIP metrics block if it's about me
919 // from OriginatorSSRC do we filter it?
920 // rtcpPacket.XR.OriginatorSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000921
danilchapda161d72016-08-19 07:29:46 -0700922 RTCPVoIPMetric receivedVoIPMetrics;
923 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
924 receivedVoIPMetrics.burstDuration =
925 rtcpPacket.XRVOIPMetricItem.burstDuration;
926 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
927 receivedVoIPMetrics.endSystemDelay =
928 rtcpPacket.XRVOIPMetricItem.endSystemDelay;
929 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
930 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
931 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
932 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
933 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
934 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
935 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
936 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
937 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
938 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
939 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
940 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
941 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
942 receivedVoIPMetrics.roundTripDelay =
943 rtcpPacket.XRVOIPMetricItem.roundTripDelay;
944 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
945 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
niklase@google.com470e71d2011-07-07 08:21:25 +0000946
danilchapda161d72016-08-19 07:29:46 -0700947 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
niklase@google.com470e71d2011-07-07 08:21:25 +0000948
danilchapda161d72016-08-19 07:29:46 -0700949 rtcpPacketInformation.rtcpPacketTypeFlags |=
950 kRtcpXrVoipMetric; // received signal
951 }
952 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000953}
954
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000955void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
956 RTCPPacketInformation& rtcpPacketInformation) {
957 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000958 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000959 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000960
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000961 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000962 // Received a signal that we need to send a new key frame.
963 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
964 }
965 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000966}
967
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000968void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
969 RTCPPacketInformation& rtcpPacketInformation) {
970 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000971
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000972 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
973 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
974 if (ptrReceiveInfo == NULL) {
975 // This remote SSRC must be saved before.
976 rtcpParser.Iterate();
977 return;
978 }
979 if (rtcpPacket.TMMBR.MediaSSRC) {
980 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
981 // in relay mode this is a valid number
982 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
983 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000984
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000985 // Use packet length to calc max number of TMMBR blocks
986 // each TMMBR block is 8 bytes
987 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +0000988
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000989 // sanity, we can't have more than what's in one packet
990 if (maxNumOfTMMBRBlocks > 200) {
991 assert(false);
992 rtcpParser.Iterate();
993 return;
994 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000995
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000996 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200997 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
danilchapda161d72016-08-19 07:29:46 -0700998 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation,
999 senderSSRC);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001000 pktType = rtcpParser.Iterate();
1001 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001002}
1003
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001004void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1005 const RTCPUtility::RTCPPacket& rtcpPacket,
1006 RTCPPacketInformation& rtcpPacketInformation,
1007 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001008 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1009 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
danilchap2b616392016-08-18 06:17:42 -07001010 receiveInfo.InsertTmmbrItem(
1011 senderSSRC,
1012 rtcp::TmmbItem(rtcpPacket.TMMBRItem.SSRC,
1013 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate * 1000,
1014 rtcpPacket.TMMBRItem.MeasuredOverhead),
1015 _clock->TimeInMilliseconds());
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001016 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1017 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001018}
1019
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001020void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1021 RTCPPacketInformation& rtcpPacketInformation) {
1022 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
danilchapda161d72016-08-19 07:29:46 -07001023 RTCPReceiveInformation* ptrReceiveInfo =
1024 GetReceiveInformation(rtcpPacket.TMMBN.SenderSSRC);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001025 if (ptrReceiveInfo == NULL) {
1026 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001027 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001028 return;
1029 }
1030 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1031 // Use packet length to calc max number of TMMBN blocks
1032 // each TMMBN block is 8 bytes
1033 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1034
1035 // sanity, we cant have more than what's in one packet
1036 if (maxNumOfTMMBNBlocks > 200) {
1037 assert(false);
1038 rtcpParser.Iterate();
1039 return;
1040 }
1041
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001042 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001043 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001044 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1045 pktType = rtcpParser.Iterate();
1046 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001047}
1048
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001049void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1050 RTCPPacketInformation& rtcpPacketInformation) {
1051 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1052 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001053}
1054
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001055void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1056 const RTCPUtility::RTCPPacket& rtcpPacket) {
danilchap2b616392016-08-18 06:17:42 -07001057 receiveInfo.tmmbn.emplace_back(
1058 rtcpPacket.TMMBNItem.SSRC,
1059 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate * 1000,
1060 rtcpPacket.TMMBNItem.MeasuredOverhead);
niklase@google.com470e71d2011-07-07 08:21:25 +00001061}
1062
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001063void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1064 RTCPPacketInformation& rtcpPacketInformation) {
1065 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1066 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001067 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001068 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1069 pktType = rtcpParser.Iterate();
1070 }
1071}
1072
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001073void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1074 RTCPPacketInformation& rtcpPacketInformation) {
1075 // in theory there could be multiple slices lost
danilchapda161d72016-08-19 07:29:46 -07001076 rtcpPacketInformation.rtcpPacketTypeFlags |=
1077 kRtcpSli; // received signal that we need to refresh a slice
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001078 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001079}
1080
danilchapda161d72016-08-19 07:29:46 -07001081void RTCPReceiver::HandleRPSI(
1082 RTCPUtility::RTCPParserV2& rtcpParser,
1083 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation) {
1084 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1085 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
1086 if (pktType == RTCPPacketTypes::kPsfbRpsiItem) {
1087 if (rtcpPacket.RPSI.NumberOfValidBits % 8 != 0) {
1088 // to us unknown
1089 // continue
1090 rtcpParser.Iterate();
1091 return;
niklase@google.com470e71d2011-07-07 08:21:25 +00001092 }
danilchapda161d72016-08-19 07:29:46 -07001093 // Received signal that we have a confirmed reference picture.
1094 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi;
1095 rtcpPacketInformation.rpsiPictureId = 0;
1096
1097 // convert NativeBitString to rpsiPictureId
1098 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits / 8;
1099 for (uint8_t n = 0; n < (numberOfBytes - 1); n++) {
1100 rtcpPacketInformation.rpsiPictureId +=
1101 (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1102 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1103 }
1104 rtcpPacketInformation.rpsiPictureId +=
1105 (rtcpPacket.RPSI.NativeBitString[numberOfBytes - 1] & 0x7f);
1106 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001107}
1108
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001109void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1110 RTCPPacketInformation& rtcpPacketInformation) {
1111 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001112 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001113 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001114 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001115 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1116 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001117 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001118 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001119}
1120
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001121void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1122 RTCPPacketInformation& rtcpPacketInformation) {
1123 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001124
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001125 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001126 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001127 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1128 pktType = rtcpParser.Iterate();
1129 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001130}
1131
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001132void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1133 RTCPPacketInformation& rtcpPacketInformation) {
1134 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1135 rtcpPacketInformation.interArrivalJitter =
danilchapda161d72016-08-19 07:29:46 -07001136 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001137}
1138
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001139void RTCPReceiver::HandleREMBItem(
1140 RTCPUtility::RTCPParserV2& rtcpParser,
1141 RTCPPacketInformation& rtcpPacketInformation) {
1142 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1143 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1144 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1145 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001146}
1147
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001148void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1149 RTCPPacketInformation& rtcpPacketInformation) {
1150 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1151 RTCPReceiveInformation* ptrReceiveInfo =
1152 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001153
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001154 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001155 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001156 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1157 pktType = rtcpParser.Iterate();
1158 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001159}
1160
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001161void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1162 const RTCPUtility::RTCPPacket& rtcpPacket,
1163 RTCPPacketInformation& rtcpPacketInformation) {
1164 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001165 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001166 return;
1167 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001168
1169 ++packet_type_counter_.fir_packets;
1170
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001171 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1172 // we don't know who this originate from
1173 if (receiveInfo) {
1174 // check if we have reported this FIRSequenceNumber before
1175 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
danilchap2b616392016-08-18 06:17:42 -07001176 receiveInfo->last_fir_sequence_number) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001177 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001178 // sanity; don't go crazy with the callbacks
danilchap2b616392016-08-18 06:17:42 -07001179 if ((now - receiveInfo->last_fir_request_ms) > RTCP_MIN_FRAME_LENGTH_MS) {
1180 receiveInfo->last_fir_request_ms = now;
1181 receiveInfo->last_fir_sequence_number =
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001182 rtcpPacket.FIRItem.CommandSequenceNumber;
1183 // received signal that we need to send a new key frame
1184 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1185 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001186 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001187 } else {
1188 // received signal that we need to send a new key frame
1189 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1190 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001191}
1192
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001193void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1194 RTCPPacketInformation& rtcpPacketInformation) {
1195 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001196
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001197 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1198 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1199 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001200
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001201 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001202}
1203
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001204void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1205 RTCPPacketInformation& rtcpPacketInformation) {
1206 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001207
danilchapda161d72016-08-19 07:29:46 -07001208 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data,
1209 rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001210
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001211 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001212}
1213
Erik Språng6b8d3552015-09-24 15:06:57 +02001214void RTCPReceiver::HandleTransportFeedback(
1215 RTCPUtility::RTCPParserV2* rtcp_parser,
1216 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1217 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1218 RTC_DCHECK(packet != nullptr);
1219 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1220 rtcp_packet_information->transport_feedback_.reset(
1221 static_cast<rtcp::TransportFeedback*>(packet));
1222
1223 rtcp_parser->Iterate();
1224}
danilchap287e5482016-08-16 15:15:39 -07001225
danilchap853ecb22016-08-22 08:26:15 -07001226void RTCPReceiver::UpdateTmmbr() {
1227 // Find bounding set.
danilchap2f69ce92016-08-16 03:21:38 -07001228 std::vector<rtcp::TmmbItem> bounding =
danilchap853ecb22016-08-22 08:26:15 -07001229 TMMBRHelp::FindBoundingSet(TmmbrReceived());
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001230
danilchap853ecb22016-08-22 08:26:15 -07001231 if (!bounding.empty() && _cbRtcpBandwidthObserver) {
1232 // We have a new bandwidth estimate on this channel.
danilchap2f69ce92016-08-16 03:21:38 -07001233 uint64_t bitrate_bps = TMMBRHelp::CalcMinBitrateBps(bounding);
1234 if (bitrate_bps <= std::numeric_limits<uint32_t>::max())
1235 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate_bps);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001236 }
danilchap853ecb22016-08-22 08:26:15 -07001237
1238 // Set bounding set: inform remote clients about the new bandwidth.
1239 _rtpRtcp.SetTmmbn(std::move(bounding));
niklase@google.com470e71d2011-07-07 08:21:25 +00001240}
1241
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001242void RTCPReceiver::RegisterRtcpStatisticsCallback(
1243 RtcpStatisticsCallback* callback) {
danilchap7c9426c2016-04-14 03:05:31 -07001244 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001245 stats_callback_ = callback;
1246}
1247
1248RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
danilchap7c9426c2016-04-14 03:05:31 -07001249 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001250 return stats_callback_;
1251}
1252
niklase@google.com470e71d2011-07-07 08:21:25 +00001253// 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) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001259 // Might trigger a OnReceivedBandwidthEstimateUpdate.
danilchap853ecb22016-08-22 08:26:15 -07001260 UpdateTmmbr();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001261 }
sprang7dc39f32015-10-13 09:17:48 -07001262 uint32_t local_ssrc;
1263 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001264 {
1265 // We don't want to hold this critsect when triggering the callbacks below.
danilchap7c9426c2016-04-14 03:05:31 -07001266 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001267 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001268 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001269 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001270 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001271 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001272 _rtpRtcp.OnRequestSendReport();
1273 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001274 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001275 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001276 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001277 LOG(LS_VERBOSE) << "Incoming NACK length: "
danilchapda161d72016-08-19 07:29:46 -07001278 << rtcpPacketInformation.nackSequenceNumbers.size();
Danil Chapovalov2800d742016-08-26 18:48:46 +02001279 _rtpRtcp.OnReceivedNack(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001280 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001281 }
1282 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001283 // We need feedback that we have received a report block(s) so that we
1284 // can generate a new packet in a conference relay scenario, one received
1285 // report can generate several RTCP packets, based on number relayed/mixed
1286 // a send report block should go out to all receivers.
1287 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001288 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001289 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1290 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1291 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001292 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001293 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001294 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001295 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001296 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001297 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001298 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001299 }
1300 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1301 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001302 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001303 }
1304 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1305 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001306 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001307 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001308 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001309 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001310 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001311 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001312 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001313 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001314 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1315 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1316 }
Erik Språng242e22b2015-05-11 10:17:43 +02001317 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1318 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001319 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001320 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
danilchapda161d72016-08-19 07:29:46 -07001321 rtcpPacketInformation.report_blocks, rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001322 now);
1323 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001324 }
isheriff6b4b5f32016-06-08 00:24:21 -07001325 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1326 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
1327 _rtpRtcp.OnReceivedRtcpReportBlocks(rtcpPacketInformation.report_blocks);
1328 }
1329
Erik Språng6b8d3552015-09-24 15:06:57 +02001330 if (_cbTransportFeedbackObserver &&
1331 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1332 uint32_t media_source_ssrc =
1333 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001334 if (media_source_ssrc == local_ssrc ||
1335 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001336 _cbTransportFeedbackObserver->OnTransportFeedback(
1337 *rtcpPacketInformation.transport_feedback_.get());
1338 }
1339 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001340 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001341
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001342 if (!receiver_only_) {
danilchap7c9426c2016-04-14 03:05:31 -07001343 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001344 if (stats_callback_) {
1345 for (ReportBlockList::const_iterator it =
danilchapda161d72016-08-19 07:29:46 -07001346 rtcpPacketInformation.report_blocks.begin();
1347 it != rtcpPacketInformation.report_blocks.end(); ++it) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001348 RtcpStatistics stats;
1349 stats.cumulative_lost = it->cumulativeLost;
1350 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1351 stats.fraction_lost = it->fractionLost;
1352 stats.jitter = it->jitter;
1353
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001354 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001355 }
1356 }
1357 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001358}
1359
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001360int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001361 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001362 assert(cName);
1363
danilchap7c9426c2016-04-14 03:05:31 -07001364 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001365 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001366 if (cnameInfo == NULL) {
1367 return -1;
1368 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001369 cName[RTCP_CNAME_SIZE - 1] = 0;
1370 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1371 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001372}
1373
danilchap853ecb22016-08-22 08:26:15 -07001374std::vector<rtcp::TmmbItem> RTCPReceiver::TmmbrReceived() const {
danilchap7c9426c2016-04-14 03:05:31 -07001375 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
danilchap287e5482016-08-16 15:15:39 -07001376 std::vector<rtcp::TmmbItem> candidates;
niklase@google.com470e71d2011-07-07 08:21:25 +00001377
danilchap287e5482016-08-16 15:15:39 -07001378 int64_t now_ms = _clock->TimeInMilliseconds();
1379
1380 for (const auto& kv : _receivedInfoMap) {
1381 RTCPReceiveInformation* receive_info = kv.second;
1382 RTC_DCHECK(receive_info);
danilchap2b616392016-08-18 06:17:42 -07001383 receive_info->GetTmmbrSet(now_ms, &candidates);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001384 }
danilchap287e5482016-08-16 15:15:39 -07001385 return candidates;
niklase@google.com470e71d2011-07-07 08:21:25 +00001386}
1387
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001388} // namespace webrtc