blob: 31a11e28925759fd149de689d197a37f0876c5ca [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
Peter Boströmfe7a80c2015-04-23 17:53:17 +020016#include "webrtc/base/checks.h"
Peter Boströmebc0b4e2015-10-28 16:39:33 +010017#include "webrtc/base/logging.h"
tommie4f96502015-10-20 23:00:48 -070018#include "webrtc/base/trace_event.h"
Erik Språng6b8d3552015-09-24 15:06:57 +020019#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
tommie4f96502015-10-20 23:00:48 -070020#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000021#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010022#include "webrtc/modules/rtp_rtcp/source/time_util.h"
danilchap13deaad2016-05-24 13:25:27 -070023#include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010024#include "webrtc/system_wrappers/include/ntp_time.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000025
niklase@google.com470e71d2011-07-07 08:21:25 +000026namespace webrtc {
danilchap6a6f0892015-12-10 12:39:08 -080027using RTCPHelp::RTCPPacketInformation;
28using RTCPHelp::RTCPReceiveInformation;
29using RTCPHelp::RTCPReportBlockInformation;
30using RTCPUtility::kBtVoipMetric;
31using RTCPUtility::RTCPCnameInformation;
32using RTCPUtility::RTCPPacketReportBlockItem;
33using RTCPUtility::RTCPPacketTypes;
niklase@google.com470e71d2011-07-07 08:21:25 +000034
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000035// The number of RTCP time intervals needed to trigger a timeout.
36const int kRrTimeoutIntervals = 3;
37
Erik Språng6b8d3552015-09-24 15:06:57 +020038const int64_t kMaxWarningLogIntervalMs = 10000;
39
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000040RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000041 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020042 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000043 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000044 RtcpBandwidthObserver* rtcp_bandwidth_observer,
45 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020046 TransportFeedbackObserver* transport_feedback_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000047 ModuleRtpRtcpImpl* owner)
danilchap13deaad2016-05-24 13:25:27 -070048 : _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020049 receiver_only_(receiver_only),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000050 _lastReceived(0),
51 _rtpRtcp(*owner),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000052 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
53 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020054 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000055 main_ssrc_(0),
56 _remoteSSRC(0),
57 _remoteSenderInfo(),
58 _lastReceivedSRNTPsecs(0),
59 _lastReceivedSRNTPfrac(0),
60 _lastReceivedXRNTPsecs(0),
61 _lastReceivedXRNTPfrac(0),
Danil Chapovalovc1e55c72016-03-09 15:14:35 +010062 xr_rrtr_status_(false),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000063 xr_rr_rtt_ms_(0),
64 _receivedInfoMap(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000065 _lastReceivedRrMs(0),
66 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000067 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020068 packet_type_counter_observer_(packet_type_counter_observer),
69 num_skipped_packets_(0),
70 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000071 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000072}
73
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000074RTCPReceiver::~RTCPReceiver() {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000075 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
76 for (; it != _receivedReportBlockMap.end(); ++it) {
77 ReportBlockInfoMap* info_map = &(it->second);
78 while (!info_map->empty()) {
79 ReportBlockInfoMap::iterator it_info = info_map->begin();
80 delete it_info->second;
81 info_map->erase(it_info);
82 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000083 }
84 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000085 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000086 _receivedInfoMap.begin();
87 delete first->second;
88 _receivedInfoMap.erase(first);
89 }
90 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000091 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000092 _receivedCnameMap.begin();
93 delete first->second;
94 _receivedCnameMap.erase(first);
95 }
niklase@google.com470e71d2011-07-07 08:21:25 +000096}
97
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000098int64_t RTCPReceiver::LastReceived() {
danilchap7c9426c2016-04-14 03:05:31 -070099 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000100 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000101}
102
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000103int64_t RTCPReceiver::LastReceivedReceiverReport() const {
danilchap7c9426c2016-04-14 03:05:31 -0700104 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000105 int64_t last_received_rr = -1;
106 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
107 it != _receivedInfoMap.end(); ++it) {
108 if (it->second->lastTimeReceived > last_received_rr) {
109 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000110 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000111 }
112 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000113}
114
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000115void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
danilchap7c9426c2016-04-14 03:05:31 -0700116 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000117
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000118 // new SSRC reset old reports
119 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
120 _lastReceivedSRNTPsecs = 0;
121 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000122
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000123 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000124}
125
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000126uint32_t RTCPReceiver::RemoteSSRC() const {
danilchap7c9426c2016-04-14 03:05:31 -0700127 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000128 return _remoteSSRC;
129}
130
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000131void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
132 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000133 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000134 {
danilchap7c9426c2016-04-14 03:05:31 -0700135 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000136 old_ssrc = main_ssrc_;
137 main_ssrc_ = main_ssrc;
138 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000139 }
140 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000141 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
142 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000143 }
144 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000145}
146
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000147int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000148 int64_t* RTT,
149 int64_t* avgRTT,
150 int64_t* minRTT,
151 int64_t* maxRTT) const {
danilchap7c9426c2016-04-14 03:05:31 -0700152 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000153
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000154 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000155 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000156
157 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000158 return -1;
159 }
160 if (RTT) {
161 *RTT = reportBlock->RTT;
162 }
163 if (avgRTT) {
164 *avgRTT = reportBlock->avgRTT;
165 }
166 if (minRTT) {
167 *minRTT = reportBlock->minRTT;
168 }
169 if (maxRTT) {
170 *maxRTT = reportBlock->maxRTT;
171 }
172 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000173}
174
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100175void RTCPReceiver::SetRtcpXrRrtrStatus(bool enable) {
danilchap7c9426c2016-04-14 03:05:31 -0700176 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100177 xr_rrtr_status_ = enable;
178}
179
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000180bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000181 assert(rtt_ms);
danilchap7c9426c2016-04-14 03:05:31 -0700182 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000183 if (xr_rr_rtt_ms_ == 0) {
184 return false;
185 }
186 *rtt_ms = xr_rr_rtt_ms_;
187 xr_rr_rtt_ms_ = 0;
188 return true;
189}
190
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000191// TODO(pbos): Make this fail when we haven't received NTP.
192bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
193 uint32_t* ReceivedNTPfrac,
194 uint32_t* RTCPArrivalTimeSecs,
195 uint32_t* RTCPArrivalTimeFrac,
196 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000197{
danilchap7c9426c2016-04-14 03:05:31 -0700198 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000199 if(ReceivedNTPsecs)
200 {
201 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
202 }
203 if(ReceivedNTPfrac)
204 {
205 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
206 }
207 if(RTCPArrivalTimeFrac)
208 {
209 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
210 }
211 if(RTCPArrivalTimeSecs)
212 {
213 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
214 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000215 if (rtcp_timestamp) {
216 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
217 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000218 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).
233 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
234 _lastReceivedXRNTPfrac);
235
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
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000272int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000273RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
274 RTCPUtility::RTCPParserV2* rtcpParser)
275{
danilchap7c9426c2016-04-14 03:05:31 -0700276 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000277
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000278 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000279
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000280 if (packet_type_counter_.first_packet_time_ms == -1) {
281 packet_type_counter_.first_packet_time_ms = _lastReceived;
282 }
283
niklase@google.com470e71d2011-07-07 08:21:25 +0000284 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200285 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000286 // Each "case" is responsible for iterate the parser to the
287 // next top level packet.
288 switch (pktType)
289 {
Erik Språng242e22b2015-05-11 10:17:43 +0200290 case RTCPPacketTypes::kSr:
291 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000292 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
293 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200294 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200295 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000296 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200297 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000298 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
299 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200300 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000301 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
302 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200303 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000304 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
305 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200306 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000307 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
308 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200309 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000310 HandleBYE(*rtcpParser);
311 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200312 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000313 HandleNACK(*rtcpParser, rtcpPacketInformation);
314 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200315 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000316 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
317 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200318 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000319 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000320 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200321 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000322 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
323 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200324 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000325 HandlePLI(*rtcpParser, rtcpPacketInformation);
326 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200327 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 HandleSLI(*rtcpParser, rtcpPacketInformation);
329 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200330 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 HandleRPSI(*rtcpParser, rtcpPacketInformation);
332 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200333 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000334 HandleIJ(*rtcpParser, rtcpPacketInformation);
335 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200336 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000337 HandleFIR(*rtcpParser, rtcpPacketInformation);
338 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200339 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000340 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
341 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200342 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 // generic application messages
344 HandleAPP(*rtcpParser, rtcpPacketInformation);
345 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200346 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000347 // generic application messages
348 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
349 break;
Erik Språng6b8d3552015-09-24 15:06:57 +0200350 case RTCPPacketTypes::kTransportFeedback:
351 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
352 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000353 default:
354 rtcpParser->Iterate();
355 break;
356 }
357 pktType = rtcpParser->PacketType();
358 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000359
360 if (packet_type_counter_observer_ != NULL) {
361 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
362 main_ssrc_, packet_type_counter_);
363 }
364
Erik Språng6b8d3552015-09-24 15:06:57 +0200365 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
366
367 int64_t now = _clock->TimeInMilliseconds();
368 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
369 num_skipped_packets_ > 0) {
370 last_skipped_packets_warning_ = now;
371 LOG(LS_WARNING)
372 << num_skipped_packets_
373 << " RTCP blocks were skipped due to being malformed or of "
374 "unrecognized/unsupported type, during the past "
375 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
376 }
377
niklase@google.com470e71d2011-07-07 08:21:25 +0000378 return 0;
379}
380
niklase@google.com470e71d2011-07-07 08:21:25 +0000381void
382RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
383 RTCPPacketInformation& rtcpPacketInformation)
384{
385 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
386 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
387
Erik Språng242e22b2015-05-11 10:17:43 +0200388 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
389 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000390
391 // SR.SenderSSRC
392 // The synchronization source identifier for the originator of this SR packet
393
394 // rtcpPacket.RR.SenderSSRC
395 // The source of the packet sender, same as of SR? or is this a CE?
396
Erik Språng242e22b2015-05-11 10:17:43 +0200397 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
398 ? rtcpPacket.RR.SenderSSRC
399 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000400
401 rtcpPacketInformation.remoteSSRC = remoteSSRC;
402
403 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
404 if (!ptrReceiveInfo)
405 {
406 rtcpParser.Iterate();
407 return;
408 }
409
Erik Språng242e22b2015-05-11 10:17:43 +0200410 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000411 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
412 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000413
niklase@google.com470e71d2011-07-07 08:21:25 +0000414 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
415 {
416 // only signal that we have received a SR when we accept one
417 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
418
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000419 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
420 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
421 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
422
niklase@google.com470e71d2011-07-07 08:21:25 +0000423 // We will only store the send report from one source, but
424 // we will store all the receive block
425
426 // Save the NTP time of this report
427 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
428 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
429 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
430 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
431 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
432
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000433 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000434 }
435 else
436 {
437 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
438 }
439 } else
440 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000441 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
442 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000443
444 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
445 }
446 UpdateReceiveInformation(*ptrReceiveInfo);
447
448 rtcpPacketType = rtcpParser.Iterate();
449
Erik Språng242e22b2015-05-11 10:17:43 +0200450 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000451 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000452 rtcpPacketType = rtcpParser.Iterate();
453 }
454}
455
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000456void RTCPReceiver::HandleReportBlock(
457 const RTCPUtility::RTCPPacket& rtcpPacket,
458 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000459 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000460 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000461 // This will be called once per report block in the RTCP packet.
462 // We filter out all report blocks that are not for us.
463 // Each packet has max 31 RR blocks.
464 //
465 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000466
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000467 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
468 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000469
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000470 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000471 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
472 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000473 // This block is not for us ignore it.
474 return;
475 }
476
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000477 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000478 CreateOrGetReportBlockInformation(remoteSSRC,
479 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000480 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000481 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
482 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000483 return;
484 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000485
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000486 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000487 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
488 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
489 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
490 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
491 reportBlock->remoteReceiveBlock.cumulativeLost =
492 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000493 if (rb.ExtendedHighestSequenceNumber >
494 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
495 // We have successfully delivered new RTP packets to the remote side after
496 // the last RR was sent from the remote side.
497 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000498 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000499 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
500 rb.ExtendedHighestSequenceNumber;
501 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
502 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
503 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
504
505 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
506 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
507 }
508
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100509 int64_t rtt = 0;
Danil Chapovalova094fd12016-02-22 18:59:36 +0100510 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100511 // RFC3550, section 6.4.1, LSR field discription states:
512 // If no SR has been received yet, the field is set to zero.
513 // Receiver rtp_rtcp module is not expected to calculate rtt using
514 // Sender Reports even if it accidentally can.
515 if (!receiver_only_ && send_time != 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100516 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
517 // Local NTP time.
518 uint32_t receive_time = CompactNtp(NtpTime(*_clock));
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000519
Danil Chapovalova094fd12016-02-22 18:59:36 +0100520 // RTT in 1/(2^16) seconds.
521 uint32_t rtt_ntp = receive_time - delay - send_time;
522 // Convert to 1/1000 seconds (milliseconds).
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100523 rtt = CompactNtpRttToMs(rtt_ntp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100524 if (rtt > reportBlock->maxRTT) {
525 // Store max RTT.
526 reportBlock->maxRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000527 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000528 if (reportBlock->minRTT == 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100529 // First RTT.
530 reportBlock->minRTT = rtt;
531 } else if (rtt < reportBlock->minRTT) {
532 // Store min RTT.
533 reportBlock->minRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000534 }
Danil Chapovalova094fd12016-02-22 18:59:36 +0100535 // Store last RTT.
536 reportBlock->RTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000537
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000538 // store average RTT
539 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000540 float ac = static_cast<float>(reportBlock->numAverageCalcs);
541 float newAverage =
Danil Chapovalova094fd12016-02-22 18:59:36 +0100542 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000543 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000544 } else {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100545 // First RTT.
546 reportBlock->avgRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000547 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000548 reportBlock->numAverageCalcs++;
549 }
550
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000551 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
Danil Chapovalova094fd12016-02-22 18:59:36 +0100552 rtt);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000553
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000554 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000555}
556
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000557RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
558 uint32_t remote_ssrc,
559 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000560 RTCPReportBlockInformation* info =
561 GetReportBlockInformation(remote_ssrc, source_ssrc);
562 if (info == NULL) {
563 info = new RTCPReportBlockInformation;
564 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000565 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000566 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000567}
568
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000569RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
570 uint32_t remote_ssrc,
571 uint32_t source_ssrc) const {
572 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000573 if (it == _receivedReportBlockMap.end()) {
574 return NULL;
575 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000576 const ReportBlockInfoMap* info_map = &(it->second);
577 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
578 if (it_info == info_map->end()) {
579 return NULL;
580 }
581 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000582}
583
584RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000585RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700586 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000587
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000588 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000589 _receivedCnameMap.find(remoteSSRC);
590
591 if (it != _receivedCnameMap.end()) {
592 return it->second;
593 }
594 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000595 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000596 _receivedCnameMap[remoteSSRC] = cnameInfo;
597 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000598}
599
600RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000601RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
danilchap7c9426c2016-04-14 03:05:31 -0700602 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000603
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000604 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000605 _receivedCnameMap.find(remoteSSRC);
606
607 if (it == _receivedCnameMap.end()) {
608 return NULL;
609 }
610 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000611}
612
613RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000614RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700615 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000616
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000617 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000618 _receivedInfoMap.find(remoteSSRC);
619
620 if (it != _receivedInfoMap.end()) {
621 return it->second;
622 }
623 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
624 _receivedInfoMap[remoteSSRC] = receiveInfo;
625 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000626}
627
628RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000629RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700630 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000631
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000632 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000633 _receivedInfoMap.find(remoteSSRC);
634 if (it == _receivedInfoMap.end()) {
635 return NULL;
636 }
637 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000638}
639
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000640void RTCPReceiver::UpdateReceiveInformation(
641 RTCPReceiveInformation& receiveInformation) {
642 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000643 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
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;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000666 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000667 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
692 if (receiveInfo->lastTimeReceived) {
693 /// use audio define since we don't know what interval the remote peer is
694 // using
695 if ((timeNow - receiveInfo->lastTimeReceived) >
696 5 * RTCP_INTERVAL_AUDIO_MS) {
697 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000698 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000699 // prevent that we call this over and over again
700 receiveInfo->lastTimeReceived = 0;
701 // send new TMMBN to all channels using the default codec
702 updateBoundingSet = true;
703 }
704 receiveInfoIt++;
705 } else if (receiveInfo->readyForDelete) {
706 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000707 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000708 receiveInfoItemToBeErased = receiveInfoIt;
709 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
danilchap6db6cdc2015-12-15 02:54:47 -0800719int32_t RTCPReceiver::BoundingSet(bool* tmmbrOwner, TMMBRSet* boundingSetRec) {
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()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000726 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000727 }
728 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
729 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000730 return -1;
731 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000732 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000733 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000734 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000735 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000736 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000737 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000738 // owner of bounding set
danilchap6db6cdc2015-12-15 02:54:47 -0800739 *tmmbrOwner = true;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000740 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000741 boundingSetRec->SetEntry(i,
742 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
743 receiveInfo->TmmbnBoundingSet.PacketOH(i),
744 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000745 }
746 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000747 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000748}
749
Erik Språnga38233a2015-07-24 09:58:18 +0200750void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
751 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000752 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200753 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000754 HandleSDESChunk(rtcpParser);
755 pktType = rtcpParser.Iterate();
756 }
Erik Språnga38233a2015-07-24 09:58:18 +0200757 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000758}
759
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000760void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
761 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
762 RTCPCnameInformation* cnameInfo =
763 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
764 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000765
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000766 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
767 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000768 {
danilchap7c9426c2016-04-14 03:05:31 -0700769 rtc::CritScope lock(&_criticalSectionFeedbacks);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000770 if (stats_callback_ != NULL) {
771 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
772 rtcpPacket.CName.SenderSSRC);
773 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000774 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000775}
776
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000777void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
778 RTCPPacketInformation& rtcpPacketInformation) {
779 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200780 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000781 // Not to us.
782 rtcpParser.Iterate();
783 return;
784 }
785 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000786
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000787 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200788 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000789 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
790 pktType = rtcpParser.Iterate();
791 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000792
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000793 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
794 ++packet_type_counter_.nack_packets;
795 packet_type_counter_.nack_requests = nack_stats_.requests();
796 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
797 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000798}
799
niklase@google.com470e71d2011-07-07 08:21:25 +0000800void
801RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000802 RTCPPacketInformation& rtcpPacketInformation) {
803 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
804 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000805
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000806 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
807 if (bitMask) {
808 for (int i=1; i <= 16; ++i) {
809 if (bitMask & 0x01) {
810 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
811 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
812 }
813 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000814 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000815 }
816 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000817}
818
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000819void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
820 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000821
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000822 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000823 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
824 for (; it != _receivedReportBlockMap.end(); ++it) {
825 ReportBlockInfoMap* info_map = &(it->second);
826 ReportBlockInfoMap::iterator it_info = info_map->find(
827 rtcpPacket.BYE.SenderSSRC);
828 if (it_info != info_map->end()) {
829 delete it_info->second;
830 info_map->erase(it_info);
831 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000832 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000833
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000834 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000835 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000836 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000837
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000838 if (receiveInfoIt != _receivedInfoMap.end()) {
839 receiveInfoIt->second->readyForDelete = true;
840 }
841
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000842 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000843 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
844
845 if (cnameInfoIt != _receivedCnameMap.end()) {
846 delete cnameInfoIt->second;
847 _receivedCnameMap.erase(cnameInfoIt);
848 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000849 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000850 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000851}
852
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000853void RTCPReceiver::HandleXrHeader(
854 RTCPUtility::RTCPParserV2& parser,
855 RTCPPacketInformation& rtcpPacketInformation) {
856 const RTCPUtility::RTCPPacket& packet = parser.Packet();
857
858 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
859
860 parser.Iterate();
861}
862
863void RTCPReceiver::HandleXrReceiveReferenceTime(
864 RTCPUtility::RTCPParserV2& parser,
865 RTCPPacketInformation& rtcpPacketInformation) {
866 const RTCPUtility::RTCPPacket& packet = parser.Packet();
867
868 _remoteXRReceiveTimeInfo.sourceSSRC =
869 rtcpPacketInformation.xr_originator_ssrc;
870
871 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
872 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
873 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
874
875 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
876
877 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
878
879 parser.Iterate();
880}
881
882void RTCPReceiver::HandleXrDlrrReportBlock(
883 RTCPUtility::RTCPParserV2& parser,
884 RTCPPacketInformation& rtcpPacketInformation) {
885 const RTCPUtility::RTCPPacket& packet = parser.Packet();
886 // Iterate through sub-block(s), if any.
887 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
888
Erik Språng242e22b2015-05-11 10:17:43 +0200889 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000890 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
891 packet_type = parser.Iterate();
892 }
893}
894
895void RTCPReceiver::HandleXrDlrrReportBlockItem(
896 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000897 RTCPPacketInformation& rtcpPacketInformation)
898 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000899 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
900 registered_ssrcs_.end()) {
901 // Not to us.
902 return;
903 }
904
905 rtcpPacketInformation.xr_dlrr_item = true;
906
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100907 // Caller should explicitly enable rtt calculation using extended reports.
908 if (!xr_rrtr_status_)
909 return;
910
Danil Chapovalova094fd12016-02-22 18:59:36 +0100911 // The send_time and delay_rr fields are in units of 1/2^16 sec.
912 uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100913 // RFC3611, section 4.5, LRR field discription states:
Danil Chapovalova094fd12016-02-22 18:59:36 +0100914 // If no such block has been received, the field is set to zero.
915 if (send_time == 0)
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000916 return;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000917
Danil Chapovalova094fd12016-02-22 18:59:36 +0100918 uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
919 uint32_t now = CompactNtp(NtpTime(*_clock));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000920
Danil Chapovalova094fd12016-02-22 18:59:36 +0100921 uint32_t rtt_ntp = now - delay_rr - send_time;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100922 xr_rr_rtt_ms_ = CompactNtpRttToMs(rtt_ntp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000923
924 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
925}
926
niklase@google.com470e71d2011-07-07 08:21:25 +0000927void
928RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
929 RTCPPacketInformation& rtcpPacketInformation)
930{
931 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
932
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000933 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000934 {
935 // Store VoIP metrics block if it's about me
936 // from OriginatorSSRC do we filter it?
937 // rtcpPacket.XR.OriginatorSSRC;
938
939 RTCPVoIPMetric receivedVoIPMetrics;
940 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
941 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
942 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
943 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
944 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
945 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
946 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
947 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
948 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
949 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
950 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
951 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
952 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
953 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
954 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
955 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
956 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
957 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
958 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
959 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
960
961 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
962
963 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
964 }
965 rtcpParser.Iterate();
966}
967
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000968void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
969 RTCPPacketInformation& rtcpPacketInformation) {
970 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000971 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000972 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000973
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000974 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000975 // Received a signal that we need to send a new key frame.
976 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
977 }
978 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000979}
980
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000981void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
982 RTCPPacketInformation& rtcpPacketInformation) {
983 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000984
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000985 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
986 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
987 if (ptrReceiveInfo == NULL) {
988 // This remote SSRC must be saved before.
989 rtcpParser.Iterate();
990 return;
991 }
992 if (rtcpPacket.TMMBR.MediaSSRC) {
993 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
994 // in relay mode this is a valid number
995 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
996 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000997
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000998 // Use packet length to calc max number of TMMBR blocks
999 // each TMMBR block is 8 bytes
1000 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001001
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001002 // sanity, we can't have more than what's in one packet
1003 if (maxNumOfTMMBRBlocks > 200) {
1004 assert(false);
1005 rtcpParser.Iterate();
1006 return;
1007 }
1008 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001009
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001010 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001011 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001012 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1013 pktType = rtcpParser.Iterate();
1014 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001015}
1016
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001017void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1018 const RTCPUtility::RTCPPacket& rtcpPacket,
1019 RTCPPacketInformation& rtcpPacketInformation,
1020 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001021 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1022 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1023 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1024 _clock->TimeInMilliseconds());
1025 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1026 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001027}
1028
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001029void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1030 RTCPPacketInformation& rtcpPacketInformation) {
1031 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1032 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1033 rtcpPacket.TMMBN.SenderSSRC);
1034 if (ptrReceiveInfo == NULL) {
1035 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001036 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001037 return;
1038 }
1039 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1040 // Use packet length to calc max number of TMMBN blocks
1041 // each TMMBN block is 8 bytes
1042 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1043
1044 // sanity, we cant have more than what's in one packet
1045 if (maxNumOfTMMBNBlocks > 200) {
1046 assert(false);
1047 rtcpParser.Iterate();
1048 return;
1049 }
1050
1051 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1052
1053 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001054 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001055 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1056 pktType = rtcpParser.Iterate();
1057 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001058}
1059
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001060void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1061 RTCPPacketInformation& rtcpPacketInformation) {
1062 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1063 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001064}
1065
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001066void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1067 const RTCPUtility::RTCPPacket& rtcpPacket) {
1068 receiveInfo.TmmbnBoundingSet.AddEntry(
1069 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1070 rtcpPacket.TMMBNItem.MeasuredOverhead,
1071 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001072}
1073
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001074void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1075 RTCPPacketInformation& rtcpPacketInformation) {
1076 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1077 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001078 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001079 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1080 pktType = rtcpParser.Iterate();
1081 }
1082}
1083
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001084void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1085 RTCPPacketInformation& rtcpPacketInformation) {
1086 // in theory there could be multiple slices lost
1087 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1088 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001089}
1090
1091void
1092RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1093 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1094{
1095 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001096 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
danilchap90a13512016-04-11 10:05:02 -07001097 if (pktType == RTCPPacketTypes::kPsfbRpsiItem) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001098 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1099 {
1100 // to us unknown
1101 // continue
1102 rtcpParser.Iterate();
1103 return;
1104 }
danilchap90a13512016-04-11 10:05:02 -07001105 // Received signal that we have a confirmed reference picture.
1106 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi;
niklase@google.com470e71d2011-07-07 08:21:25 +00001107 rtcpPacketInformation.rpsiPictureId = 0;
1108
1109 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001110 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1111 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001112 {
1113 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1114 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1115 }
1116 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1117 }
1118}
1119
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001120void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1121 RTCPPacketInformation& rtcpPacketInformation) {
1122 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001123 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001124 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001125 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001126 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1127 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001128 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001129 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001130}
1131
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001132void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1133 RTCPPacketInformation& rtcpPacketInformation) {
1134 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001135
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001136 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001137 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001138 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1139 pktType = rtcpParser.Iterate();
1140 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001141}
1142
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001143void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1144 RTCPPacketInformation& rtcpPacketInformation) {
1145 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1146 rtcpPacketInformation.interArrivalJitter =
1147 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001148}
1149
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001150void RTCPReceiver::HandleREMBItem(
1151 RTCPUtility::RTCPParserV2& rtcpParser,
1152 RTCPPacketInformation& rtcpPacketInformation) {
1153 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1154 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1155 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1156 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001157}
1158
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001159void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1160 RTCPPacketInformation& rtcpPacketInformation) {
1161 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1162 RTCPReceiveInformation* ptrReceiveInfo =
1163 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001164
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001165 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001166 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001167 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1168 pktType = rtcpParser.Iterate();
1169 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001170}
1171
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001172void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1173 const RTCPUtility::RTCPPacket& rtcpPacket,
1174 RTCPPacketInformation& rtcpPacketInformation) {
1175 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001176 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001177 return;
1178 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001179
1180 ++packet_type_counter_.fir_packets;
1181
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001182 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1183 // we don't know who this originate from
1184 if (receiveInfo) {
1185 // check if we have reported this FIRSequenceNumber before
1186 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1187 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001188 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001189 // sanity; don't go crazy with the callbacks
1190 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1191 receiveInfo->lastFIRRequest = now;
1192 receiveInfo->lastFIRSequenceNumber =
1193 rtcpPacket.FIRItem.CommandSequenceNumber;
1194 // received signal that we need to send a new key frame
1195 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1196 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001197 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001198 } else {
1199 // received signal that we need to send a new key frame
1200 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1201 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001202}
1203
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001204void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1205 RTCPPacketInformation& rtcpPacketInformation) {
1206 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001207
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001208 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1209 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1210 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001211
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001212 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001213}
1214
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001215void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1216 RTCPPacketInformation& rtcpPacketInformation) {
1217 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001218
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001219 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001220
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001221 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001222}
1223
Erik Språng6b8d3552015-09-24 15:06:57 +02001224void RTCPReceiver::HandleTransportFeedback(
1225 RTCPUtility::RTCPParserV2* rtcp_parser,
1226 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1227 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1228 RTC_DCHECK(packet != nullptr);
1229 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1230 rtcp_packet_information->transport_feedback_.reset(
1231 static_cast<rtcp::TransportFeedback*>(packet));
1232
1233 rtcp_parser->Iterate();
1234}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001235int32_t RTCPReceiver::UpdateTMMBR() {
danilchap13deaad2016-05-24 13:25:27 -07001236 TMMBRHelp tmmbr_help;
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001237 uint32_t bitrate = 0;
1238 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001239
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001240 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001241 if (size > 0) {
danilchap13deaad2016-05-24 13:25:27 -07001242 TMMBRSet* candidateSet = tmmbr_help.VerifyAndAllocateCandidateSet(size);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001243 // Get candidate set from receiver.
1244 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001245 }
1246 // Find bounding set
Danil Chapovalovdaa90a72016-08-10 11:29:50 +02001247 std::vector<rtcp::TmmbItem> bounding = tmmbr_help.FindTMMBRBoundingSet();
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001248 // Set bounding set
1249 // Inform remote clients about the new bandwidth
1250 // inform the remote client
Danil Chapovalovdaa90a72016-08-10 11:29:50 +02001251 _rtpRtcp.SetTMMBN(&bounding);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001252
1253 // might trigger a TMMBN
Danil Chapovalovdaa90a72016-08-10 11:29:50 +02001254 if (bounding.empty()) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001255 // owner of max bitrate request has timed out
1256 // empty bounding set has been sent
1257 return 0;
1258 }
1259 // Get net bitrate from bounding set depending on sent packet rate
danilchap13deaad2016-05-24 13:25:27 -07001260 if (tmmbr_help.CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001261 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001262 if (_cbRtcpBandwidthObserver) {
1263 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001264 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001265 }
1266 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001267}
1268
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001269void RTCPReceiver::RegisterRtcpStatisticsCallback(
1270 RtcpStatisticsCallback* callback) {
danilchap7c9426c2016-04-14 03:05:31 -07001271 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001272 stats_callback_ = callback;
1273}
1274
1275RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
danilchap7c9426c2016-04-14 03:05:31 -07001276 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001277 return stats_callback_;
1278}
1279
niklase@google.com470e71d2011-07-07 08:21:25 +00001280// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001281void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001282 RTCPPacketInformation& rtcpPacketInformation) {
1283 // Process TMMBR and REMB first to avoid multiple callbacks
1284 // to OnNetworkChanged.
1285 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001286 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1287 UpdateTMMBR();
1288 }
sprang7dc39f32015-10-13 09:17:48 -07001289 uint32_t local_ssrc;
1290 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001291 {
1292 // We don't want to hold this critsect when triggering the callbacks below.
danilchap7c9426c2016-04-14 03:05:31 -07001293 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001294 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001295 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001296 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001297 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001298 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001299 _rtpRtcp.OnRequestSendReport();
1300 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001301 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001302 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001303 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001304 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001305 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001306 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001307 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001308 }
1309 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001310 // We need feedback that we have received a report block(s) so that we
1311 // can generate a new packet in a conference relay scenario, one received
1312 // report can generate several RTCP packets, based on number relayed/mixed
1313 // a send report block should go out to all receivers.
1314 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001315 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001316 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1317 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1318 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001319 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001320 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001321 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001322 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001323 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001324 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001325 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001326 }
1327 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1328 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001329 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001330 }
1331 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1332 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001333 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001334 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001335 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001336 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001337 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001338 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001339 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001340 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001341 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1342 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1343 }
Erik Språng242e22b2015-05-11 10:17:43 +02001344 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1345 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001346 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001347 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001348 rtcpPacketInformation.report_blocks,
1349 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001350 now);
1351 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001352 }
isheriff6b4b5f32016-06-08 00:24:21 -07001353 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1354 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
1355 _rtpRtcp.OnReceivedRtcpReportBlocks(rtcpPacketInformation.report_blocks);
1356 }
1357
Erik Språng6b8d3552015-09-24 15:06:57 +02001358 if (_cbTransportFeedbackObserver &&
1359 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1360 uint32_t media_source_ssrc =
1361 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001362 if (media_source_ssrc == local_ssrc ||
1363 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001364 _cbTransportFeedbackObserver->OnTransportFeedback(
1365 *rtcpPacketInformation.transport_feedback_.get());
1366 }
1367 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001368 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001369
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001370 if (!receiver_only_) {
danilchap7c9426c2016-04-14 03:05:31 -07001371 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001372 if (stats_callback_) {
1373 for (ReportBlockList::const_iterator it =
1374 rtcpPacketInformation.report_blocks.begin();
1375 it != rtcpPacketInformation.report_blocks.end();
1376 ++it) {
1377 RtcpStatistics stats;
1378 stats.cumulative_lost = it->cumulativeLost;
1379 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1380 stats.fraction_lost = it->fractionLost;
1381 stats.jitter = it->jitter;
1382
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001383 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001384 }
1385 }
1386 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001387}
1388
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001389int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001390 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001391 assert(cName);
1392
danilchap7c9426c2016-04-14 03:05:31 -07001393 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001394 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001395 if (cnameInfo == NULL) {
1396 return -1;
1397 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001398 cName[RTCP_CNAME_SIZE - 1] = 0;
1399 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1400 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001401}
1402
1403// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001404int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1405 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001406 TMMBRSet* candidateSet) const {
danilchap7c9426c2016-04-14 03:05:31 -07001407 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001408
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001409 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001410 receiveInfoIt = _receivedInfoMap.begin();
1411 if (receiveInfoIt == _receivedInfoMap.end()) {
1412 return -1;
1413 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001414 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001415 if (candidateSet) {
1416 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1417 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1418 if (receiveInfo == NULL) {
1419 return 0;
1420 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001421 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001422 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001423 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001424 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001425 num++;
1426 }
1427 }
1428 receiveInfoIt++;
1429 }
1430 } else {
1431 while (receiveInfoIt != _receivedInfoMap.end()) {
1432 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1433 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001434 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001435 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001436 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001437 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001438 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001439 }
1440 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001441}
1442
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001443} // namespace webrtc