blob: 8012f47dc0e7e3d6ec46b1e9efe452592bfc7422 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000011#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
Peter Boströmfe7a80c2015-04-23 17:53:17 +020013#include <assert.h>
14#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000015
danilchap2f69ce92016-08-16 03:21:38 -070016#include <limits>
17
Peter Boströmfe7a80c2015-04-23 17:53:17 +020018#include "webrtc/base/checks.h"
Peter Boströmebc0b4e2015-10-28 16:39:33 +010019#include "webrtc/base/logging.h"
tommie4f96502015-10-20 23:00:48 -070020#include "webrtc/base/trace_event.h"
Erik Språng6b8d3552015-09-24 15:06:57 +020021#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
tommie4f96502015-10-20 23:00:48 -070022#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000023#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010024#include "webrtc/modules/rtp_rtcp/source/time_util.h"
danilchap13deaad2016-05-24 13:25:27 -070025#include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010026#include "webrtc/system_wrappers/include/ntp_time.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000027
niklase@google.com470e71d2011-07-07 08:21:25 +000028namespace webrtc {
danilchap6a6f0892015-12-10 12:39:08 -080029using RTCPHelp::RTCPPacketInformation;
30using RTCPHelp::RTCPReceiveInformation;
31using RTCPHelp::RTCPReportBlockInformation;
32using RTCPUtility::kBtVoipMetric;
33using RTCPUtility::RTCPCnameInformation;
34using RTCPUtility::RTCPPacketReportBlockItem;
35using RTCPUtility::RTCPPacketTypes;
niklase@google.com470e71d2011-07-07 08:21:25 +000036
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000037// The number of RTCP time intervals needed to trigger a timeout.
38const int kRrTimeoutIntervals = 3;
39
Erik Språng6b8d3552015-09-24 15:06:57 +020040const int64_t kMaxWarningLogIntervalMs = 10000;
41
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000042RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000043 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020044 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000045 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000046 RtcpBandwidthObserver* rtcp_bandwidth_observer,
47 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020048 TransportFeedbackObserver* transport_feedback_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000049 ModuleRtpRtcpImpl* owner)
danilchap13deaad2016-05-24 13:25:27 -070050 : _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020051 receiver_only_(receiver_only),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000052 _lastReceived(0),
53 _rtpRtcp(*owner),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000054 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
55 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020056 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000057 main_ssrc_(0),
58 _remoteSSRC(0),
59 _remoteSenderInfo(),
60 _lastReceivedSRNTPsecs(0),
61 _lastReceivedSRNTPfrac(0),
62 _lastReceivedXRNTPsecs(0),
63 _lastReceivedXRNTPfrac(0),
Danil Chapovalovc1e55c72016-03-09 15:14:35 +010064 xr_rrtr_status_(false),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000065 xr_rr_rtt_ms_(0),
66 _receivedInfoMap(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000067 _lastReceivedRrMs(0),
68 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000069 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020070 packet_type_counter_observer_(packet_type_counter_observer),
71 num_skipped_packets_(0),
72 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000073 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000074}
75
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000076RTCPReceiver::~RTCPReceiver() {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000077 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
78 for (; it != _receivedReportBlockMap.end(); ++it) {
79 ReportBlockInfoMap* info_map = &(it->second);
80 while (!info_map->empty()) {
81 ReportBlockInfoMap::iterator it_info = info_map->begin();
82 delete it_info->second;
83 info_map->erase(it_info);
84 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000085 }
86 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000087 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000088 _receivedInfoMap.begin();
89 delete first->second;
90 _receivedInfoMap.erase(first);
91 }
92 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000093 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000094 _receivedCnameMap.begin();
95 delete first->second;
96 _receivedCnameMap.erase(first);
97 }
niklase@google.com470e71d2011-07-07 08:21:25 +000098}
99
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000100int64_t RTCPReceiver::LastReceived() {
danilchap7c9426c2016-04-14 03:05:31 -0700101 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000102 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000103}
104
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000105int64_t RTCPReceiver::LastReceivedReceiverReport() const {
danilchap7c9426c2016-04-14 03:05:31 -0700106 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000107 int64_t last_received_rr = -1;
108 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
109 it != _receivedInfoMap.end(); ++it) {
110 if (it->second->lastTimeReceived > last_received_rr) {
111 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000112 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000113 }
114 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000115}
116
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000117void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
danilchap7c9426c2016-04-14 03:05:31 -0700118 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000119
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000120 // new SSRC reset old reports
121 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
122 _lastReceivedSRNTPsecs = 0;
123 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000124
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000125 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000126}
127
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000128uint32_t RTCPReceiver::RemoteSSRC() const {
danilchap7c9426c2016-04-14 03:05:31 -0700129 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000130 return _remoteSSRC;
131}
132
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000133void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
134 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000135 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000136 {
danilchap7c9426c2016-04-14 03:05:31 -0700137 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000138 old_ssrc = main_ssrc_;
139 main_ssrc_ = main_ssrc;
140 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000141 }
142 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000143 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
144 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000145 }
146 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000147}
148
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000149int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000150 int64_t* RTT,
151 int64_t* avgRTT,
152 int64_t* minRTT,
153 int64_t* maxRTT) const {
danilchap7c9426c2016-04-14 03:05:31 -0700154 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000155
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000156 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000157 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000158
159 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000160 return -1;
161 }
162 if (RTT) {
163 *RTT = reportBlock->RTT;
164 }
165 if (avgRTT) {
166 *avgRTT = reportBlock->avgRTT;
167 }
168 if (minRTT) {
169 *minRTT = reportBlock->minRTT;
170 }
171 if (maxRTT) {
172 *maxRTT = reportBlock->maxRTT;
173 }
174 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000175}
176
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100177void RTCPReceiver::SetRtcpXrRrtrStatus(bool enable) {
danilchap7c9426c2016-04-14 03:05:31 -0700178 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100179 xr_rrtr_status_ = enable;
180}
181
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000182bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000183 assert(rtt_ms);
danilchap7c9426c2016-04-14 03:05:31 -0700184 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000185 if (xr_rr_rtt_ms_ == 0) {
186 return false;
187 }
188 *rtt_ms = xr_rr_rtt_ms_;
189 xr_rr_rtt_ms_ = 0;
190 return true;
191}
192
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000193// TODO(pbos): Make this fail when we haven't received NTP.
194bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
195 uint32_t* ReceivedNTPfrac,
196 uint32_t* RTCPArrivalTimeSecs,
197 uint32_t* RTCPArrivalTimeFrac,
198 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000199{
danilchap7c9426c2016-04-14 03:05:31 -0700200 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000201 if(ReceivedNTPsecs)
202 {
203 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
204 }
205 if(ReceivedNTPfrac)
206 {
207 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
208 }
209 if(RTCPArrivalTimeFrac)
210 {
211 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
212 }
213 if(RTCPArrivalTimeSecs)
214 {
215 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
216 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000217 if (rtcp_timestamp) {
218 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
219 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000220 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000221}
222
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000223bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
224 RtcpReceiveTimeInfo* info) const {
225 assert(info);
danilchap7c9426c2016-04-14 03:05:31 -0700226 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000227 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
228 return false;
229 }
230
231 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
232 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
233
234 // Get the delay since last received report (RFC 3611).
235 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
236 _lastReceivedXRNTPfrac);
237
238 uint32_t ntp_sec = 0;
239 uint32_t ntp_frac = 0;
240 _clock->CurrentNtp(ntp_sec, ntp_frac);
241 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
242
243 info->delaySinceLastRR = now - receive_time;
244 return true;
245}
246
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000247int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
248 assert(senderInfo);
danilchap7c9426c2016-04-14 03:05:31 -0700249 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000250 if (_lastReceivedSRNTPsecs == 0) {
251 return -1;
252 }
253 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
254 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000255}
256
257// statistics
258// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000259int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000260 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000261 assert(receiveBlocks);
danilchap7c9426c2016-04-14 03:05:31 -0700262 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000263 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
264 for (; it != _receivedReportBlockMap.end(); ++it) {
265 const ReportBlockInfoMap* info_map = &(it->second);
266 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
267 for (; it_info != info_map->end(); ++it_info) {
268 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
269 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000270 }
271 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000272}
273
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000274int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000275RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
276 RTCPUtility::RTCPParserV2* rtcpParser)
277{
danilchap7c9426c2016-04-14 03:05:31 -0700278 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000279
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000280 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000281
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000282 if (packet_type_counter_.first_packet_time_ms == -1) {
283 packet_type_counter_.first_packet_time_ms = _lastReceived;
284 }
285
niklase@google.com470e71d2011-07-07 08:21:25 +0000286 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200287 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000288 // Each "case" is responsible for iterate the parser to the
289 // next top level packet.
290 switch (pktType)
291 {
Erik Språng242e22b2015-05-11 10:17:43 +0200292 case RTCPPacketTypes::kSr:
293 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000294 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
295 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200296 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200297 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000298 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200299 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000300 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
301 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200302 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000303 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
304 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200305 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000306 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
307 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200308 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000309 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
310 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200311 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000312 HandleBYE(*rtcpParser);
313 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200314 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000315 HandleNACK(*rtcpParser, rtcpPacketInformation);
316 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200317 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000318 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
319 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200320 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000321 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000322 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200323 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000324 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
325 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200326 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000327 HandlePLI(*rtcpParser, rtcpPacketInformation);
328 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200329 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000330 HandleSLI(*rtcpParser, rtcpPacketInformation);
331 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200332 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 HandleRPSI(*rtcpParser, rtcpPacketInformation);
334 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200335 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000336 HandleIJ(*rtcpParser, rtcpPacketInformation);
337 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200338 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 HandleFIR(*rtcpParser, rtcpPacketInformation);
340 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200341 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000342 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
343 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200344 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000345 // generic application messages
346 HandleAPP(*rtcpParser, rtcpPacketInformation);
347 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200348 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000349 // generic application messages
350 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
351 break;
Erik Språng6b8d3552015-09-24 15:06:57 +0200352 case RTCPPacketTypes::kTransportFeedback:
353 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
354 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000355 default:
356 rtcpParser->Iterate();
357 break;
358 }
359 pktType = rtcpParser->PacketType();
360 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000361
362 if (packet_type_counter_observer_ != NULL) {
363 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
364 main_ssrc_, packet_type_counter_);
365 }
366
Erik Språng6b8d3552015-09-24 15:06:57 +0200367 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
368
369 int64_t now = _clock->TimeInMilliseconds();
370 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
371 num_skipped_packets_ > 0) {
372 last_skipped_packets_warning_ = now;
373 LOG(LS_WARNING)
374 << num_skipped_packets_
375 << " RTCP blocks were skipped due to being malformed or of "
376 "unrecognized/unsupported type, during the past "
377 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
378 }
379
niklase@google.com470e71d2011-07-07 08:21:25 +0000380 return 0;
381}
382
niklase@google.com470e71d2011-07-07 08:21:25 +0000383void
384RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
385 RTCPPacketInformation& rtcpPacketInformation)
386{
387 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
388 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
389
Erik Språng242e22b2015-05-11 10:17:43 +0200390 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
391 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000392
393 // SR.SenderSSRC
394 // The synchronization source identifier for the originator of this SR packet
395
396 // rtcpPacket.RR.SenderSSRC
397 // The source of the packet sender, same as of SR? or is this a CE?
398
Erik Språng242e22b2015-05-11 10:17:43 +0200399 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
400 ? rtcpPacket.RR.SenderSSRC
401 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000402
403 rtcpPacketInformation.remoteSSRC = remoteSSRC;
404
405 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
406 if (!ptrReceiveInfo)
407 {
408 rtcpParser.Iterate();
409 return;
410 }
411
Erik Språng242e22b2015-05-11 10:17:43 +0200412 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000413 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
414 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000415
niklase@google.com470e71d2011-07-07 08:21:25 +0000416 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
417 {
418 // only signal that we have received a SR when we accept one
419 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
420
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000421 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
422 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
423 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
424
niklase@google.com470e71d2011-07-07 08:21:25 +0000425 // We will only store the send report from one source, but
426 // we will store all the receive block
427
428 // Save the NTP time of this report
429 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
430 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
431 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
432 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
433 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
434
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000435 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000436 }
437 else
438 {
439 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
440 }
441 } else
442 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000443 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
444 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000445
446 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
447 }
448 UpdateReceiveInformation(*ptrReceiveInfo);
449
450 rtcpPacketType = rtcpParser.Iterate();
451
Erik Språng242e22b2015-05-11 10:17:43 +0200452 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000453 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000454 rtcpPacketType = rtcpParser.Iterate();
455 }
456}
457
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000458void RTCPReceiver::HandleReportBlock(
459 const RTCPUtility::RTCPPacket& rtcpPacket,
460 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000461 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000462 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000463 // This will be called once per report block in the RTCP packet.
464 // We filter out all report blocks that are not for us.
465 // Each packet has max 31 RR blocks.
466 //
467 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000468
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000469 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
470 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000471
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000472 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000473 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
474 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000475 // This block is not for us ignore it.
476 return;
477 }
478
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000479 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000480 CreateOrGetReportBlockInformation(remoteSSRC,
481 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000482 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000483 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
484 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000485 return;
486 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000487
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000488 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000489 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
490 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
491 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
492 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
493 reportBlock->remoteReceiveBlock.cumulativeLost =
494 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000495 if (rb.ExtendedHighestSequenceNumber >
496 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
497 // We have successfully delivered new RTP packets to the remote side after
498 // the last RR was sent from the remote side.
499 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000500 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000501 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
502 rb.ExtendedHighestSequenceNumber;
503 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
504 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
505 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
506
507 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
508 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
509 }
510
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100511 int64_t rtt = 0;
Danil Chapovalova094fd12016-02-22 18:59:36 +0100512 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100513 // RFC3550, section 6.4.1, LSR field discription states:
514 // If no SR has been received yet, the field is set to zero.
515 // Receiver rtp_rtcp module is not expected to calculate rtt using
516 // Sender Reports even if it accidentally can.
517 if (!receiver_only_ && send_time != 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100518 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
519 // Local NTP time.
520 uint32_t receive_time = CompactNtp(NtpTime(*_clock));
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000521
Danil Chapovalova094fd12016-02-22 18:59:36 +0100522 // RTT in 1/(2^16) seconds.
523 uint32_t rtt_ntp = receive_time - delay - send_time;
524 // Convert to 1/1000 seconds (milliseconds).
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100525 rtt = CompactNtpRttToMs(rtt_ntp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100526 if (rtt > reportBlock->maxRTT) {
527 // Store max RTT.
528 reportBlock->maxRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000529 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000530 if (reportBlock->minRTT == 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100531 // First RTT.
532 reportBlock->minRTT = rtt;
533 } else if (rtt < reportBlock->minRTT) {
534 // Store min RTT.
535 reportBlock->minRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000536 }
Danil Chapovalova094fd12016-02-22 18:59:36 +0100537 // Store last RTT.
538 reportBlock->RTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000539
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000540 // store average RTT
541 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000542 float ac = static_cast<float>(reportBlock->numAverageCalcs);
543 float newAverage =
Danil Chapovalova094fd12016-02-22 18:59:36 +0100544 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000545 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000546 } else {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100547 // First RTT.
548 reportBlock->avgRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000549 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000550 reportBlock->numAverageCalcs++;
551 }
552
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000553 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
Danil Chapovalova094fd12016-02-22 18:59:36 +0100554 rtt);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000555
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000556 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000557}
558
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000559RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
560 uint32_t remote_ssrc,
561 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000562 RTCPReportBlockInformation* info =
563 GetReportBlockInformation(remote_ssrc, source_ssrc);
564 if (info == NULL) {
565 info = new RTCPReportBlockInformation;
566 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000567 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000568 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000569}
570
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000571RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
572 uint32_t remote_ssrc,
573 uint32_t source_ssrc) const {
574 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000575 if (it == _receivedReportBlockMap.end()) {
576 return NULL;
577 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000578 const ReportBlockInfoMap* info_map = &(it->second);
579 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
580 if (it_info == info_map->end()) {
581 return NULL;
582 }
583 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000584}
585
586RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000587RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700588 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000589
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000590 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000591 _receivedCnameMap.find(remoteSSRC);
592
593 if (it != _receivedCnameMap.end()) {
594 return it->second;
595 }
596 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000597 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000598 _receivedCnameMap[remoteSSRC] = cnameInfo;
599 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000600}
601
602RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000603RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
danilchap7c9426c2016-04-14 03:05:31 -0700604 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000605
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000606 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000607 _receivedCnameMap.find(remoteSSRC);
608
609 if (it == _receivedCnameMap.end()) {
610 return NULL;
611 }
612 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000613}
614
615RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000616RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700617 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000618
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000619 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000620 _receivedInfoMap.find(remoteSSRC);
621
622 if (it != _receivedInfoMap.end()) {
623 return it->second;
624 }
625 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
626 _receivedInfoMap[remoteSSRC] = receiveInfo;
627 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000628}
629
630RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000631RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700632 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000633
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000634 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000635 _receivedInfoMap.find(remoteSSRC);
636 if (it == _receivedInfoMap.end()) {
637 return NULL;
638 }
639 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000640}
641
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000642void RTCPReceiver::UpdateReceiveInformation(
643 RTCPReceiveInformation& receiveInformation) {
644 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000645 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000646}
647
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000648bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
danilchap7c9426c2016-04-14 03:05:31 -0700649 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000650 if (_lastReceivedRrMs == 0)
651 return false;
652
653 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000654 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000655 // Reset the timer to only trigger one log.
656 _lastReceivedRrMs = 0;
657 return true;
658 }
659 return false;
660}
661
662bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
danilchap7c9426c2016-04-14 03:05:31 -0700663 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000664 if (_lastIncreasedSequenceNumberMs == 0)
665 return false;
666
667 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000668 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000669 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000670 // Reset the timer to only trigger one log.
671 _lastIncreasedSequenceNumberMs = 0;
672 return true;
673 }
674 return false;
675}
676
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000677bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
danilchap7c9426c2016-04-14 03:05:31 -0700678 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000679
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000680 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000681 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000682
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000683 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000684 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000685
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000686 while (receiveInfoIt != _receivedInfoMap.end()) {
687 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
688 if (receiveInfo == NULL) {
689 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000690 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000691 // time since last received rtcp packet
692 // when we dont have a lastTimeReceived and the object is marked
693 // readyForDelete it's removed from the map
694 if (receiveInfo->lastTimeReceived) {
695 /// use audio define since we don't know what interval the remote peer is
696 // using
697 if ((timeNow - receiveInfo->lastTimeReceived) >
698 5 * RTCP_INTERVAL_AUDIO_MS) {
699 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000700 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000701 // prevent that we call this over and over again
702 receiveInfo->lastTimeReceived = 0;
703 // send new TMMBN to all channels using the default codec
704 updateBoundingSet = true;
705 }
706 receiveInfoIt++;
707 } else if (receiveInfo->readyForDelete) {
708 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000709 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000710 receiveInfoItemToBeErased = receiveInfoIt;
711 receiveInfoIt++;
712 delete receiveInfoItemToBeErased->second;
713 _receivedInfoMap.erase(receiveInfoItemToBeErased);
714 } else {
715 receiveInfoIt++;
716 }
717 }
718 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000719}
720
danilchap6db6cdc2015-12-15 02:54:47 -0800721int32_t RTCPReceiver::BoundingSet(bool* tmmbrOwner, TMMBRSet* boundingSetRec) {
danilchap7c9426c2016-04-14 03:05:31 -0700722 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000723
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000724 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000725 _receivedInfoMap.find(_remoteSSRC);
726
727 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000728 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000729 }
730 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
731 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000732 return -1;
733 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000734 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000735 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000736 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000737 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000738 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000739 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000740 // owner of bounding set
danilchap6db6cdc2015-12-15 02:54:47 -0800741 *tmmbrOwner = true;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000742 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000743 boundingSetRec->SetEntry(i,
744 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
745 receiveInfo->TmmbnBoundingSet.PacketOH(i),
746 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000747 }
748 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000749 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000750}
751
Erik Språnga38233a2015-07-24 09:58:18 +0200752void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
753 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000754 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200755 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000756 HandleSDESChunk(rtcpParser);
757 pktType = rtcpParser.Iterate();
758 }
Erik Språnga38233a2015-07-24 09:58:18 +0200759 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000760}
761
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000762void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
763 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
764 RTCPCnameInformation* cnameInfo =
765 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
766 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000767
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000768 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
769 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000770 {
danilchap7c9426c2016-04-14 03:05:31 -0700771 rtc::CritScope lock(&_criticalSectionFeedbacks);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000772 if (stats_callback_ != NULL) {
773 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
774 rtcpPacket.CName.SenderSSRC);
775 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000776 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000777}
778
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000779void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
780 RTCPPacketInformation& rtcpPacketInformation) {
781 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200782 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000783 // Not to us.
784 rtcpParser.Iterate();
785 return;
786 }
787 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000788
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000789 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200790 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000791 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
792 pktType = rtcpParser.Iterate();
793 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000794
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000795 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
796 ++packet_type_counter_.nack_packets;
797 packet_type_counter_.nack_requests = nack_stats_.requests();
798 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
799 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000800}
801
niklase@google.com470e71d2011-07-07 08:21:25 +0000802void
803RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000804 RTCPPacketInformation& rtcpPacketInformation) {
805 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
806 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000807
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000808 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
809 if (bitMask) {
810 for (int i=1; i <= 16; ++i) {
811 if (bitMask & 0x01) {
812 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
813 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
814 }
815 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000816 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000817 }
818 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000819}
820
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000821void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
822 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000823
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000824 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000825 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
826 for (; it != _receivedReportBlockMap.end(); ++it) {
827 ReportBlockInfoMap* info_map = &(it->second);
828 ReportBlockInfoMap::iterator it_info = info_map->find(
829 rtcpPacket.BYE.SenderSSRC);
830 if (it_info != info_map->end()) {
831 delete it_info->second;
832 info_map->erase(it_info);
833 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000834 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000835
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000836 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000837 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000838 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000839
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000840 if (receiveInfoIt != _receivedInfoMap.end()) {
841 receiveInfoIt->second->readyForDelete = true;
842 }
843
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000844 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000845 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
846
847 if (cnameInfoIt != _receivedCnameMap.end()) {
848 delete cnameInfoIt->second;
849 _receivedCnameMap.erase(cnameInfoIt);
850 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000851 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000852 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000853}
854
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000855void RTCPReceiver::HandleXrHeader(
856 RTCPUtility::RTCPParserV2& parser,
857 RTCPPacketInformation& rtcpPacketInformation) {
858 const RTCPUtility::RTCPPacket& packet = parser.Packet();
859
860 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
861
862 parser.Iterate();
863}
864
865void RTCPReceiver::HandleXrReceiveReferenceTime(
866 RTCPUtility::RTCPParserV2& parser,
867 RTCPPacketInformation& rtcpPacketInformation) {
868 const RTCPUtility::RTCPPacket& packet = parser.Packet();
869
870 _remoteXRReceiveTimeInfo.sourceSSRC =
871 rtcpPacketInformation.xr_originator_ssrc;
872
873 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
874 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
875 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
876
877 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
878
879 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
880
881 parser.Iterate();
882}
883
884void RTCPReceiver::HandleXrDlrrReportBlock(
885 RTCPUtility::RTCPParserV2& parser,
886 RTCPPacketInformation& rtcpPacketInformation) {
887 const RTCPUtility::RTCPPacket& packet = parser.Packet();
888 // Iterate through sub-block(s), if any.
889 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
890
Erik Språng242e22b2015-05-11 10:17:43 +0200891 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000892 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
893 packet_type = parser.Iterate();
894 }
895}
896
897void RTCPReceiver::HandleXrDlrrReportBlockItem(
898 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000899 RTCPPacketInformation& rtcpPacketInformation)
900 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000901 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
902 registered_ssrcs_.end()) {
903 // Not to us.
904 return;
905 }
906
907 rtcpPacketInformation.xr_dlrr_item = true;
908
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100909 // Caller should explicitly enable rtt calculation using extended reports.
910 if (!xr_rrtr_status_)
911 return;
912
Danil Chapovalova094fd12016-02-22 18:59:36 +0100913 // The send_time and delay_rr fields are in units of 1/2^16 sec.
914 uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100915 // RFC3611, section 4.5, LRR field discription states:
Danil Chapovalova094fd12016-02-22 18:59:36 +0100916 // If no such block has been received, the field is set to zero.
917 if (send_time == 0)
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000918 return;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000919
Danil Chapovalova094fd12016-02-22 18:59:36 +0100920 uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
921 uint32_t now = CompactNtp(NtpTime(*_clock));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000922
Danil Chapovalova094fd12016-02-22 18:59:36 +0100923 uint32_t rtt_ntp = now - delay_rr - send_time;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100924 xr_rr_rtt_ms_ = CompactNtpRttToMs(rtt_ntp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000925
926 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
927}
928
niklase@google.com470e71d2011-07-07 08:21:25 +0000929void
930RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
931 RTCPPacketInformation& rtcpPacketInformation)
932{
933 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
934
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000935 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000936 {
937 // Store VoIP metrics block if it's about me
938 // from OriginatorSSRC do we filter it?
939 // rtcpPacket.XR.OriginatorSSRC;
940
941 RTCPVoIPMetric receivedVoIPMetrics;
942 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
943 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
944 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
945 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
946 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
947 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
948 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
949 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
950 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
951 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
952 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
953 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
954 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
955 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
956 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
957 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
958 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
959 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
960 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
961 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
962
963 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
964
965 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
966 }
967 rtcpParser.Iterate();
968}
969
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000970void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
971 RTCPPacketInformation& rtcpPacketInformation) {
972 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000973 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000974 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000975
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000976 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000977 // Received a signal that we need to send a new key frame.
978 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
979 }
980 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000981}
982
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000983void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
984 RTCPPacketInformation& rtcpPacketInformation) {
985 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000986
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000987 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
988 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
989 if (ptrReceiveInfo == NULL) {
990 // This remote SSRC must be saved before.
991 rtcpParser.Iterate();
992 return;
993 }
994 if (rtcpPacket.TMMBR.MediaSSRC) {
995 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
996 // in relay mode this is a valid number
997 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
998 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000999
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001000 // Use packet length to calc max number of TMMBR blocks
1001 // each TMMBR block is 8 bytes
1002 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001003
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001004 // sanity, we can't have more than what's in one packet
1005 if (maxNumOfTMMBRBlocks > 200) {
1006 assert(false);
1007 rtcpParser.Iterate();
1008 return;
1009 }
1010 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001011
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001012 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001013 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001014 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1015 pktType = rtcpParser.Iterate();
1016 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001017}
1018
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001019void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1020 const RTCPUtility::RTCPPacket& rtcpPacket,
1021 RTCPPacketInformation& rtcpPacketInformation,
1022 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001023 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1024 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1025 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1026 _clock->TimeInMilliseconds());
1027 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1028 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001029}
1030
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001031void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1032 RTCPPacketInformation& rtcpPacketInformation) {
1033 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1034 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1035 rtcpPacket.TMMBN.SenderSSRC);
1036 if (ptrReceiveInfo == NULL) {
1037 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001038 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001039 return;
1040 }
1041 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1042 // Use packet length to calc max number of TMMBN blocks
1043 // each TMMBN block is 8 bytes
1044 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1045
1046 // sanity, we cant have more than what's in one packet
1047 if (maxNumOfTMMBNBlocks > 200) {
1048 assert(false);
1049 rtcpParser.Iterate();
1050 return;
1051 }
1052
1053 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1054
1055 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001056 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001057 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1058 pktType = rtcpParser.Iterate();
1059 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001060}
1061
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001062void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1063 RTCPPacketInformation& rtcpPacketInformation) {
1064 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1065 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001066}
1067
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001068void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1069 const RTCPUtility::RTCPPacket& rtcpPacket) {
1070 receiveInfo.TmmbnBoundingSet.AddEntry(
1071 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1072 rtcpPacket.TMMBNItem.MeasuredOverhead,
1073 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001074}
1075
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001076void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1077 RTCPPacketInformation& rtcpPacketInformation) {
1078 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1079 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001080 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001081 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1082 pktType = rtcpParser.Iterate();
1083 }
1084}
1085
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001086void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1087 RTCPPacketInformation& rtcpPacketInformation) {
1088 // in theory there could be multiple slices lost
1089 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1090 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001091}
1092
1093void
1094RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1095 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1096{
1097 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001098 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
danilchap90a13512016-04-11 10:05:02 -07001099 if (pktType == RTCPPacketTypes::kPsfbRpsiItem) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001100 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1101 {
1102 // to us unknown
1103 // continue
1104 rtcpParser.Iterate();
1105 return;
1106 }
danilchap90a13512016-04-11 10:05:02 -07001107 // Received signal that we have a confirmed reference picture.
1108 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi;
niklase@google.com470e71d2011-07-07 08:21:25 +00001109 rtcpPacketInformation.rpsiPictureId = 0;
1110
1111 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001112 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1113 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001114 {
1115 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1116 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1117 }
1118 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1119 }
1120}
1121
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001122void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1123 RTCPPacketInformation& rtcpPacketInformation) {
1124 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001125 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001126 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001127 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001128 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1129 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001130 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001131 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001132}
1133
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001134void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1135 RTCPPacketInformation& rtcpPacketInformation) {
1136 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001137
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001138 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001139 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001140 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1141 pktType = rtcpParser.Iterate();
1142 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001143}
1144
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001145void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1146 RTCPPacketInformation& rtcpPacketInformation) {
1147 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1148 rtcpPacketInformation.interArrivalJitter =
1149 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001150}
1151
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001152void RTCPReceiver::HandleREMBItem(
1153 RTCPUtility::RTCPParserV2& rtcpParser,
1154 RTCPPacketInformation& rtcpPacketInformation) {
1155 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1156 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1157 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1158 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001159}
1160
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001161void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1162 RTCPPacketInformation& rtcpPacketInformation) {
1163 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1164 RTCPReceiveInformation* ptrReceiveInfo =
1165 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001166
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001167 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001168 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001169 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1170 pktType = rtcpParser.Iterate();
1171 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001172}
1173
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001174void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1175 const RTCPUtility::RTCPPacket& rtcpPacket,
1176 RTCPPacketInformation& rtcpPacketInformation) {
1177 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001178 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001179 return;
1180 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001181
1182 ++packet_type_counter_.fir_packets;
1183
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001184 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1185 // we don't know who this originate from
1186 if (receiveInfo) {
1187 // check if we have reported this FIRSequenceNumber before
1188 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1189 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001190 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001191 // sanity; don't go crazy with the callbacks
1192 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1193 receiveInfo->lastFIRRequest = now;
1194 receiveInfo->lastFIRSequenceNumber =
1195 rtcpPacket.FIRItem.CommandSequenceNumber;
1196 // received signal that we need to send a new key frame
1197 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1198 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001199 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001200 } else {
1201 // received signal that we need to send a new key frame
1202 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1203 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001204}
1205
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001206void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1207 RTCPPacketInformation& rtcpPacketInformation) {
1208 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001209
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001210 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1211 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1212 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001213
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001214 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001215}
1216
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001217void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1218 RTCPPacketInformation& rtcpPacketInformation) {
1219 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001220
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001221 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001222
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001223 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001224}
1225
Erik Språng6b8d3552015-09-24 15:06:57 +02001226void RTCPReceiver::HandleTransportFeedback(
1227 RTCPUtility::RTCPParserV2* rtcp_parser,
1228 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1229 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1230 RTC_DCHECK(packet != nullptr);
1231 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1232 rtcp_packet_information->transport_feedback_.reset(
1233 static_cast<rtcp::TransportFeedback*>(packet));
1234
1235 rtcp_parser->Iterate();
1236}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001237int32_t RTCPReceiver::UpdateTMMBR() {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001238 int32_t size = TMMBRReceived(0, 0, NULL);
danilchap2f69ce92016-08-16 03:21:38 -07001239 TMMBRSet candidates;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001240 if (size > 0) {
danilchap2f69ce92016-08-16 03:21:38 -07001241 candidates.reserve(size);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001242 // Get candidate set from receiver.
danilchap2f69ce92016-08-16 03:21:38 -07001243 TMMBRReceived(size, 0, &candidates);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001244 }
1245 // Find bounding set
danilchap2f69ce92016-08-16 03:21:38 -07001246 std::vector<rtcp::TmmbItem> bounding =
1247 TMMBRHelp::FindBoundingSet(std::move(candidates));
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 }
danilchap2f69ce92016-08-16 03:21:38 -07001259 // We have a new bandwidth estimate on this channel.
1260 if (_cbRtcpBandwidthObserver) {
1261 uint64_t bitrate_bps = TMMBRHelp::CalcMinBitrateBps(bounding);
1262 if (bitrate_bps <= std::numeric_limits<uint32_t>::max())
1263 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate_bps);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001264 }
1265 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001266}
1267
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001268void RTCPReceiver::RegisterRtcpStatisticsCallback(
1269 RtcpStatisticsCallback* callback) {
danilchap7c9426c2016-04-14 03:05:31 -07001270 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001271 stats_callback_ = callback;
1272}
1273
1274RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
danilchap7c9426c2016-04-14 03:05:31 -07001275 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001276 return stats_callback_;
1277}
1278
niklase@google.com470e71d2011-07-07 08:21:25 +00001279// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001280void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001281 RTCPPacketInformation& rtcpPacketInformation) {
1282 // Process TMMBR and REMB first to avoid multiple callbacks
1283 // to OnNetworkChanged.
1284 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001285 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1286 UpdateTMMBR();
1287 }
sprang7dc39f32015-10-13 09:17:48 -07001288 uint32_t local_ssrc;
1289 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001290 {
1291 // We don't want to hold this critsect when triggering the callbacks below.
danilchap7c9426c2016-04-14 03:05:31 -07001292 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001293 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001294 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001295 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001296 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001297 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001298 _rtpRtcp.OnRequestSendReport();
1299 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001300 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001301 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001302 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001303 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001304 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001305 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001306 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001307 }
1308 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001309 // We need feedback that we have received a report block(s) so that we
1310 // can generate a new packet in a conference relay scenario, one received
1311 // report can generate several RTCP packets, based on number relayed/mixed
1312 // a send report block should go out to all receivers.
1313 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001314 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001315 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1316 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1317 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001318 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001319 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001320 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001321 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001322 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001323 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001324 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001325 }
1326 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1327 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001328 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001329 }
1330 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1331 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001332 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001333 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001334 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001335 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001336 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001337 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001338 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001339 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001340 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1341 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1342 }
Erik Språng242e22b2015-05-11 10:17:43 +02001343 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1344 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001345 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001346 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001347 rtcpPacketInformation.report_blocks,
1348 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001349 now);
1350 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001351 }
isheriff6b4b5f32016-06-08 00:24:21 -07001352 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1353 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
1354 _rtpRtcp.OnReceivedRtcpReportBlocks(rtcpPacketInformation.report_blocks);
1355 }
1356
Erik Språng6b8d3552015-09-24 15:06:57 +02001357 if (_cbTransportFeedbackObserver &&
1358 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1359 uint32_t media_source_ssrc =
1360 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001361 if (media_source_ssrc == local_ssrc ||
1362 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001363 _cbTransportFeedbackObserver->OnTransportFeedback(
1364 *rtcpPacketInformation.transport_feedback_.get());
1365 }
1366 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001367 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001368
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001369 if (!receiver_only_) {
danilchap7c9426c2016-04-14 03:05:31 -07001370 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001371 if (stats_callback_) {
1372 for (ReportBlockList::const_iterator it =
1373 rtcpPacketInformation.report_blocks.begin();
1374 it != rtcpPacketInformation.report_blocks.end();
1375 ++it) {
1376 RtcpStatistics stats;
1377 stats.cumulative_lost = it->cumulativeLost;
1378 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1379 stats.fraction_lost = it->fractionLost;
1380 stats.jitter = it->jitter;
1381
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001382 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001383 }
1384 }
1385 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001386}
1387
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001388int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001389 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001390 assert(cName);
1391
danilchap7c9426c2016-04-14 03:05:31 -07001392 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001393 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001394 if (cnameInfo == NULL) {
1395 return -1;
1396 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001397 cName[RTCP_CNAME_SIZE - 1] = 0;
1398 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1399 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001400}
1401
1402// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001403int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1404 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001405 TMMBRSet* candidateSet) const {
danilchap7c9426c2016-04-14 03:05:31 -07001406 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001407
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001408 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001409 receiveInfoIt = _receivedInfoMap.begin();
1410 if (receiveInfoIt == _receivedInfoMap.end()) {
1411 return -1;
1412 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001413 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001414 if (candidateSet) {
1415 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1416 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1417 if (receiveInfo == NULL) {
1418 return 0;
1419 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001420 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001421 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001422 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001423 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001424 num++;
1425 }
1426 }
1427 receiveInfoIt++;
1428 }
1429 } else {
1430 while (receiveInfoIt != _receivedInfoMap.end()) {
1431 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1432 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001433 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001434 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001435 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001436 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001437 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001438 }
1439 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001440}
1441
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001442} // namespace webrtc