blob: 75c7eec47553604b513927044dd15d0c20ec22a6 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000011#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
Peter Boströmfe7a80c2015-04-23 17:53:17 +020013#include <assert.h>
14#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000015
danilchap2f69ce92016-08-16 03:21:38 -070016#include <limits>
17
Peter Boströmfe7a80c2015-04-23 17:53:17 +020018#include "webrtc/base/checks.h"
Peter Boströmebc0b4e2015-10-28 16:39:33 +010019#include "webrtc/base/logging.h"
tommie4f96502015-10-20 23:00:48 -070020#include "webrtc/base/trace_event.h"
Erik Språng6b8d3552015-09-24 15:06:57 +020021#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
tommie4f96502015-10-20 23:00:48 -070022#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000023#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010024#include "webrtc/modules/rtp_rtcp/source/time_util.h"
danilchap13deaad2016-05-24 13:25:27 -070025#include "webrtc/modules/rtp_rtcp/source/tmmbr_help.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010026#include "webrtc/system_wrappers/include/ntp_time.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000027
niklase@google.com470e71d2011-07-07 08:21:25 +000028namespace webrtc {
danilchap6a6f0892015-12-10 12:39:08 -080029using RTCPHelp::RTCPPacketInformation;
30using RTCPHelp::RTCPReceiveInformation;
31using RTCPHelp::RTCPReportBlockInformation;
32using RTCPUtility::kBtVoipMetric;
33using RTCPUtility::RTCPCnameInformation;
34using RTCPUtility::RTCPPacketReportBlockItem;
35using RTCPUtility::RTCPPacketTypes;
niklase@google.com470e71d2011-07-07 08:21:25 +000036
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000037// The number of RTCP time intervals needed to trigger a timeout.
38const int kRrTimeoutIntervals = 3;
39
Erik Språng6b8d3552015-09-24 15:06:57 +020040const int64_t kMaxWarningLogIntervalMs = 10000;
41
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000042RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000043 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020044 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000045 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000046 RtcpBandwidthObserver* rtcp_bandwidth_observer,
47 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020048 TransportFeedbackObserver* transport_feedback_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000049 ModuleRtpRtcpImpl* owner)
danilchap13deaad2016-05-24 13:25:27 -070050 : _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020051 receiver_only_(receiver_only),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000052 _lastReceived(0),
53 _rtpRtcp(*owner),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000054 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
55 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020056 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000057 main_ssrc_(0),
58 _remoteSSRC(0),
59 _remoteSenderInfo(),
60 _lastReceivedSRNTPsecs(0),
61 _lastReceivedSRNTPfrac(0),
62 _lastReceivedXRNTPsecs(0),
63 _lastReceivedXRNTPfrac(0),
Danil Chapovalovc1e55c72016-03-09 15:14:35 +010064 xr_rrtr_status_(false),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000065 xr_rr_rtt_ms_(0),
66 _receivedInfoMap(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000067 _lastReceivedRrMs(0),
68 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000069 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020070 packet_type_counter_observer_(packet_type_counter_observer),
71 num_skipped_packets_(0),
72 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000073 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000074}
75
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000076RTCPReceiver::~RTCPReceiver() {
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000077 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
78 for (; it != _receivedReportBlockMap.end(); ++it) {
79 ReportBlockInfoMap* info_map = &(it->second);
80 while (!info_map->empty()) {
81 ReportBlockInfoMap::iterator it_info = info_map->begin();
82 delete it_info->second;
83 info_map->erase(it_info);
84 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000085 }
86 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000087 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000088 _receivedInfoMap.begin();
89 delete first->second;
90 _receivedInfoMap.erase(first);
91 }
92 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000093 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000094 _receivedCnameMap.begin();
95 delete first->second;
96 _receivedCnameMap.erase(first);
97 }
niklase@google.com470e71d2011-07-07 08:21:25 +000098}
99
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000100int64_t RTCPReceiver::LastReceived() {
danilchap7c9426c2016-04-14 03:05:31 -0700101 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000102 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000103}
104
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000105int64_t RTCPReceiver::LastReceivedReceiverReport() const {
danilchap7c9426c2016-04-14 03:05:31 -0700106 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000107 int64_t last_received_rr = -1;
108 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
109 it != _receivedInfoMap.end(); ++it) {
danilchap2b616392016-08-18 06:17:42 -0700110 if (it->second->last_time_received_ms > last_received_rr) {
111 last_received_rr = it->second->last_time_received_ms;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000112 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000113 }
114 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000115}
116
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000117void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
danilchap7c9426c2016-04-14 03:05:31 -0700118 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000119
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000120 // new SSRC reset old reports
121 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
122 _lastReceivedSRNTPsecs = 0;
123 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000124
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000125 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000126}
127
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000128uint32_t RTCPReceiver::RemoteSSRC() const {
danilchap7c9426c2016-04-14 03:05:31 -0700129 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000130 return _remoteSSRC;
131}
132
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000133void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
134 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000135 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000136 {
danilchap7c9426c2016-04-14 03:05:31 -0700137 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000138 old_ssrc = main_ssrc_;
139 main_ssrc_ = main_ssrc;
140 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000141 }
142 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000143 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
144 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000145 }
146 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000147}
148
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000149int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000150 int64_t* RTT,
151 int64_t* avgRTT,
152 int64_t* minRTT,
153 int64_t* maxRTT) const {
danilchap7c9426c2016-04-14 03:05:31 -0700154 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000155
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000156 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000157 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000158
159 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000160 return -1;
161 }
162 if (RTT) {
163 *RTT = reportBlock->RTT;
164 }
165 if (avgRTT) {
166 *avgRTT = reportBlock->avgRTT;
167 }
168 if (minRTT) {
169 *minRTT = reportBlock->minRTT;
170 }
171 if (maxRTT) {
172 *maxRTT = reportBlock->maxRTT;
173 }
174 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000175}
176
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100177void RTCPReceiver::SetRtcpXrRrtrStatus(bool enable) {
danilchap7c9426c2016-04-14 03:05:31 -0700178 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100179 xr_rrtr_status_ = enable;
180}
181
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000182bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000183 assert(rtt_ms);
danilchap7c9426c2016-04-14 03:05:31 -0700184 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000185 if (xr_rr_rtt_ms_ == 0) {
186 return false;
187 }
188 *rtt_ms = xr_rr_rtt_ms_;
189 xr_rr_rtt_ms_ = 0;
190 return true;
191}
192
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000193// TODO(pbos): Make this fail when we haven't received NTP.
194bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
195 uint32_t* ReceivedNTPfrac,
196 uint32_t* RTCPArrivalTimeSecs,
197 uint32_t* RTCPArrivalTimeFrac,
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 }
danilchap2b616392016-08-18 06:17:42 -0700448 // Update that this remote is alive.
449 ptrReceiveInfo->last_time_received_ms = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000450
451 rtcpPacketType = rtcpParser.Iterate();
452
Erik Språng242e22b2015-05-11 10:17:43 +0200453 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000454 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000455 rtcpPacketType = rtcpParser.Iterate();
456 }
457}
458
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000459void RTCPReceiver::HandleReportBlock(
460 const RTCPUtility::RTCPPacket& rtcpPacket,
461 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000462 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000463 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000464 // This will be called once per report block in the RTCP packet.
465 // We filter out all report blocks that are not for us.
466 // Each packet has max 31 RR blocks.
467 //
468 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000469
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000470 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
471 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000472
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000473 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000474 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
475 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000476 // This block is not for us ignore it.
477 return;
478 }
479
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000480 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000481 CreateOrGetReportBlockInformation(remoteSSRC,
482 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000483 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000484 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
485 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000486 return;
487 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000488
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000489 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000490 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
491 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
492 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
493 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
494 reportBlock->remoteReceiveBlock.cumulativeLost =
495 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000496 if (rb.ExtendedHighestSequenceNumber >
497 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
498 // We have successfully delivered new RTP packets to the remote side after
499 // the last RR was sent from the remote side.
500 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000501 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000502 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
503 rb.ExtendedHighestSequenceNumber;
504 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
505 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
506 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
507
508 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
509 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
510 }
511
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100512 int64_t rtt = 0;
Danil Chapovalova094fd12016-02-22 18:59:36 +0100513 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100514 // RFC3550, section 6.4.1, LSR field discription states:
515 // If no SR has been received yet, the field is set to zero.
516 // Receiver rtp_rtcp module is not expected to calculate rtt using
517 // Sender Reports even if it accidentally can.
518 if (!receiver_only_ && send_time != 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100519 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
520 // Local NTP time.
521 uint32_t receive_time = CompactNtp(NtpTime(*_clock));
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000522
Danil Chapovalova094fd12016-02-22 18:59:36 +0100523 // RTT in 1/(2^16) seconds.
524 uint32_t rtt_ntp = receive_time - delay - send_time;
525 // Convert to 1/1000 seconds (milliseconds).
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100526 rtt = CompactNtpRttToMs(rtt_ntp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100527 if (rtt > reportBlock->maxRTT) {
528 // Store max RTT.
529 reportBlock->maxRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000530 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000531 if (reportBlock->minRTT == 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100532 // First RTT.
533 reportBlock->minRTT = rtt;
534 } else if (rtt < reportBlock->minRTT) {
535 // Store min RTT.
536 reportBlock->minRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000537 }
Danil Chapovalova094fd12016-02-22 18:59:36 +0100538 // Store last RTT.
539 reportBlock->RTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000540
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000541 // store average RTT
542 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000543 float ac = static_cast<float>(reportBlock->numAverageCalcs);
544 float newAverage =
Danil Chapovalova094fd12016-02-22 18:59:36 +0100545 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000546 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000547 } else {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100548 // First RTT.
549 reportBlock->avgRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000550 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000551 reportBlock->numAverageCalcs++;
552 }
553
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000554 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
Danil Chapovalova094fd12016-02-22 18:59:36 +0100555 rtt);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000556
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000557 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000558}
559
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000560RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
561 uint32_t remote_ssrc,
562 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000563 RTCPReportBlockInformation* info =
564 GetReportBlockInformation(remote_ssrc, source_ssrc);
565 if (info == NULL) {
566 info = new RTCPReportBlockInformation;
567 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000568 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000569 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000570}
571
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000572RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
573 uint32_t remote_ssrc,
574 uint32_t source_ssrc) const {
575 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000576 if (it == _receivedReportBlockMap.end()) {
577 return NULL;
578 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000579 const ReportBlockInfoMap* info_map = &(it->second);
580 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
581 if (it_info == info_map->end()) {
582 return NULL;
583 }
584 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000585}
586
587RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000588RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700589 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000590
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000591 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000592 _receivedCnameMap.find(remoteSSRC);
593
594 if (it != _receivedCnameMap.end()) {
595 return it->second;
596 }
597 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000598 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000599 _receivedCnameMap[remoteSSRC] = cnameInfo;
600 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000601}
602
603RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000604RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
danilchap7c9426c2016-04-14 03:05:31 -0700605 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000606
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000607 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000608 _receivedCnameMap.find(remoteSSRC);
609
610 if (it == _receivedCnameMap.end()) {
611 return NULL;
612 }
613 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000614}
615
616RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000617RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700618 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000619
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000620 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000621 _receivedInfoMap.find(remoteSSRC);
622
623 if (it != _receivedInfoMap.end()) {
624 return it->second;
625 }
626 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
627 _receivedInfoMap[remoteSSRC] = receiveInfo;
628 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000629}
630
631RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000632RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
danilchap7c9426c2016-04-14 03:05:31 -0700633 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000634
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000635 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000636 _receivedInfoMap.find(remoteSSRC);
637 if (it == _receivedInfoMap.end()) {
638 return NULL;
639 }
640 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000641}
642
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000643bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
danilchap7c9426c2016-04-14 03:05:31 -0700644 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000645 if (_lastReceivedRrMs == 0)
646 return false;
647
648 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000649 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000650 // Reset the timer to only trigger one log.
651 _lastReceivedRrMs = 0;
652 return true;
653 }
654 return false;
655}
656
657bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
danilchap7c9426c2016-04-14 03:05:31 -0700658 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000659 if (_lastIncreasedSequenceNumberMs == 0)
660 return false;
661
662 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000663 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000664 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000665 // Reset the timer to only trigger one log.
666 _lastIncreasedSequenceNumberMs = 0;
667 return true;
668 }
669 return false;
670}
671
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000672bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
danilchap7c9426c2016-04-14 03:05:31 -0700673 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000674
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000675 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000676 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000677
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000678 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000679 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000680
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000681 while (receiveInfoIt != _receivedInfoMap.end()) {
682 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
683 if (receiveInfo == NULL) {
684 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000685 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000686 // time since last received rtcp packet
687 // when we dont have a lastTimeReceived and the object is marked
688 // readyForDelete it's removed from the map
danilchap2b616392016-08-18 06:17:42 -0700689 if (receiveInfo->last_time_received_ms > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000690 /// use audio define since we don't know what interval the remote peer is
691 // using
danilchap2b616392016-08-18 06:17:42 -0700692 if ((timeNow - receiveInfo->last_time_received_ms) >
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000693 5 * RTCP_INTERVAL_AUDIO_MS) {
694 // no rtcp packet for the last five regular intervals, reset limitations
danilchap2b616392016-08-18 06:17:42 -0700695 receiveInfo->ClearTmmbr();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000696 // prevent that we call this over and over again
danilchap2b616392016-08-18 06:17:42 -0700697 receiveInfo->last_time_received_ms = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000698 // send new TMMBN to all channels using the default codec
699 updateBoundingSet = true;
700 }
701 receiveInfoIt++;
danilchap2b616392016-08-18 06:17:42 -0700702 } else if (receiveInfo->ready_for_delete) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000703 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000704 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000705 receiveInfoItemToBeErased = receiveInfoIt;
706 receiveInfoIt++;
707 delete receiveInfoItemToBeErased->second;
708 _receivedInfoMap.erase(receiveInfoItemToBeErased);
709 } else {
710 receiveInfoIt++;
711 }
712 }
713 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000714}
715
danilchap2b616392016-08-18 06:17:42 -0700716std::vector<rtcp::TmmbItem> RTCPReceiver::BoundingSet(bool* tmmbr_owner) {
danilchap7c9426c2016-04-14 03:05:31 -0700717 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000718
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000719 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000720 _receivedInfoMap.find(_remoteSSRC);
721
722 if (receiveInfoIt == _receivedInfoMap.end()) {
danilchap2b616392016-08-18 06:17:42 -0700723 return std::vector<rtcp::TmmbItem>();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000724 }
725 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
danilchap2b616392016-08-18 06:17:42 -0700726 RTC_DCHECK(receiveInfo);
727
728 *tmmbr_owner = TMMBRHelp::IsOwner(receiveInfo->tmmbn, main_ssrc_);
729 return receiveInfo->tmmbn;
niklase@google.com470e71d2011-07-07 08:21:25 +0000730}
731
Erik Språnga38233a2015-07-24 09:58:18 +0200732void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
733 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000734 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200735 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000736 HandleSDESChunk(rtcpParser);
737 pktType = rtcpParser.Iterate();
738 }
Erik Språnga38233a2015-07-24 09:58:18 +0200739 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000740}
741
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000742void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
743 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
744 RTCPCnameInformation* cnameInfo =
745 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
746 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000747
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000748 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
749 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000750 {
danilchap7c9426c2016-04-14 03:05:31 -0700751 rtc::CritScope lock(&_criticalSectionFeedbacks);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000752 if (stats_callback_ != NULL) {
753 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
754 rtcpPacket.CName.SenderSSRC);
755 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000756 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000757}
758
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000759void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
760 RTCPPacketInformation& rtcpPacketInformation) {
761 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200762 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000763 // Not to us.
764 rtcpParser.Iterate();
765 return;
766 }
767 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000768
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000769 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200770 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000771 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
772 pktType = rtcpParser.Iterate();
773 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000774
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000775 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
776 ++packet_type_counter_.nack_packets;
777 packet_type_counter_.nack_requests = nack_stats_.requests();
778 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
779 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000780}
781
niklase@google.com470e71d2011-07-07 08:21:25 +0000782void
783RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000784 RTCPPacketInformation& rtcpPacketInformation) {
785 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
786 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000787
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000788 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
789 if (bitMask) {
790 for (int i=1; i <= 16; ++i) {
791 if (bitMask & 0x01) {
792 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
793 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
794 }
795 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000796 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000797 }
798 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000799}
800
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000801void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
802 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000803
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000804 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000805 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
806 for (; it != _receivedReportBlockMap.end(); ++it) {
807 ReportBlockInfoMap* info_map = &(it->second);
808 ReportBlockInfoMap::iterator it_info = info_map->find(
809 rtcpPacket.BYE.SenderSSRC);
810 if (it_info != info_map->end()) {
811 delete it_info->second;
812 info_map->erase(it_info);
813 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000814 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000815
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000816 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000817 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000818 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000819
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000820 if (receiveInfoIt != _receivedInfoMap.end()) {
danilchap2b616392016-08-18 06:17:42 -0700821 receiveInfoIt->second->ready_for_delete = true;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000822 }
823
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000824 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000825 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
826
827 if (cnameInfoIt != _receivedCnameMap.end()) {
828 delete cnameInfoIt->second;
829 _receivedCnameMap.erase(cnameInfoIt);
830 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000831 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000832 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000833}
834
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000835void RTCPReceiver::HandleXrHeader(
836 RTCPUtility::RTCPParserV2& parser,
837 RTCPPacketInformation& rtcpPacketInformation) {
838 const RTCPUtility::RTCPPacket& packet = parser.Packet();
839
840 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
841
842 parser.Iterate();
843}
844
845void RTCPReceiver::HandleXrReceiveReferenceTime(
846 RTCPUtility::RTCPParserV2& parser,
847 RTCPPacketInformation& rtcpPacketInformation) {
848 const RTCPUtility::RTCPPacket& packet = parser.Packet();
849
850 _remoteXRReceiveTimeInfo.sourceSSRC =
851 rtcpPacketInformation.xr_originator_ssrc;
852
853 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
854 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
855 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
856
857 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
858
859 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
860
861 parser.Iterate();
862}
863
864void RTCPReceiver::HandleXrDlrrReportBlock(
865 RTCPUtility::RTCPParserV2& parser,
866 RTCPPacketInformation& rtcpPacketInformation) {
867 const RTCPUtility::RTCPPacket& packet = parser.Packet();
868 // Iterate through sub-block(s), if any.
869 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
870
Erik Språng242e22b2015-05-11 10:17:43 +0200871 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000872 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
873 packet_type = parser.Iterate();
874 }
875}
876
877void RTCPReceiver::HandleXrDlrrReportBlockItem(
878 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000879 RTCPPacketInformation& rtcpPacketInformation)
880 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000881 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
882 registered_ssrcs_.end()) {
883 // Not to us.
884 return;
885 }
886
887 rtcpPacketInformation.xr_dlrr_item = true;
888
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100889 // Caller should explicitly enable rtt calculation using extended reports.
890 if (!xr_rrtr_status_)
891 return;
892
Danil Chapovalova094fd12016-02-22 18:59:36 +0100893 // The send_time and delay_rr fields are in units of 1/2^16 sec.
894 uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100895 // RFC3611, section 4.5, LRR field discription states:
Danil Chapovalova094fd12016-02-22 18:59:36 +0100896 // If no such block has been received, the field is set to zero.
897 if (send_time == 0)
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000898 return;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000899
Danil Chapovalova094fd12016-02-22 18:59:36 +0100900 uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
901 uint32_t now = CompactNtp(NtpTime(*_clock));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000902
Danil Chapovalova094fd12016-02-22 18:59:36 +0100903 uint32_t rtt_ntp = now - delay_rr - send_time;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100904 xr_rr_rtt_ms_ = CompactNtpRttToMs(rtt_ntp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000905
906 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
907}
908
niklase@google.com470e71d2011-07-07 08:21:25 +0000909void
910RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
911 RTCPPacketInformation& rtcpPacketInformation)
912{
913 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
914
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000915 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000916 {
917 // Store VoIP metrics block if it's about me
918 // from OriginatorSSRC do we filter it?
919 // rtcpPacket.XR.OriginatorSSRC;
920
921 RTCPVoIPMetric receivedVoIPMetrics;
922 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
923 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
924 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
925 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
926 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
927 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
928 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
929 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
930 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
931 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
932 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
933 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
934 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
935 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
936 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
937 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
938 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
939 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
940 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
941 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
942
943 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
944
945 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
946 }
947 rtcpParser.Iterate();
948}
949
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000950void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
951 RTCPPacketInformation& rtcpPacketInformation) {
952 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000953 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000954 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000955
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000956 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000957 // Received a signal that we need to send a new key frame.
958 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
959 }
960 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000961}
962
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000963void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
964 RTCPPacketInformation& rtcpPacketInformation) {
965 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000966
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000967 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
968 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
969 if (ptrReceiveInfo == NULL) {
970 // This remote SSRC must be saved before.
971 rtcpParser.Iterate();
972 return;
973 }
974 if (rtcpPacket.TMMBR.MediaSSRC) {
975 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
976 // in relay mode this is a valid number
977 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
978 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000979
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000980 // Use packet length to calc max number of TMMBR blocks
981 // each TMMBR block is 8 bytes
982 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +0000983
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000984 // sanity, we can't have more than what's in one packet
985 if (maxNumOfTMMBRBlocks > 200) {
986 assert(false);
987 rtcpParser.Iterate();
988 return;
989 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000990
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000991 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200992 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000993 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
994 pktType = rtcpParser.Iterate();
995 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000996}
997
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000998void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
999 const RTCPUtility::RTCPPacket& rtcpPacket,
1000 RTCPPacketInformation& rtcpPacketInformation,
1001 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001002 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1003 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
danilchap2b616392016-08-18 06:17:42 -07001004 receiveInfo.InsertTmmbrItem(
1005 senderSSRC,
1006 rtcp::TmmbItem(rtcpPacket.TMMBRItem.SSRC,
1007 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate * 1000,
1008 rtcpPacket.TMMBRItem.MeasuredOverhead),
1009 _clock->TimeInMilliseconds());
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001010 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1011 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001012}
1013
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001014void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1015 RTCPPacketInformation& rtcpPacketInformation) {
1016 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1017 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1018 rtcpPacket.TMMBN.SenderSSRC);
1019 if (ptrReceiveInfo == NULL) {
1020 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001021 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001022 return;
1023 }
1024 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1025 // Use packet length to calc max number of TMMBN blocks
1026 // each TMMBN block is 8 bytes
1027 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1028
1029 // sanity, we cant have more than what's in one packet
1030 if (maxNumOfTMMBNBlocks > 200) {
1031 assert(false);
1032 rtcpParser.Iterate();
1033 return;
1034 }
1035
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001036 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001037 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001038 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1039 pktType = rtcpParser.Iterate();
1040 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001041}
1042
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001043void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1044 RTCPPacketInformation& rtcpPacketInformation) {
1045 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1046 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001047}
1048
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001049void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1050 const RTCPUtility::RTCPPacket& rtcpPacket) {
danilchap2b616392016-08-18 06:17:42 -07001051 receiveInfo.tmmbn.emplace_back(
1052 rtcpPacket.TMMBNItem.SSRC,
1053 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate * 1000,
1054 rtcpPacket.TMMBNItem.MeasuredOverhead);
niklase@google.com470e71d2011-07-07 08:21:25 +00001055}
1056
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001057void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1058 RTCPPacketInformation& rtcpPacketInformation) {
1059 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1060 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001061 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001062 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1063 pktType = rtcpParser.Iterate();
1064 }
1065}
1066
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001067void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1068 RTCPPacketInformation& rtcpPacketInformation) {
1069 // in theory there could be multiple slices lost
1070 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1071 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001072}
1073
1074void
1075RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1076 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1077{
1078 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001079 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
danilchap90a13512016-04-11 10:05:02 -07001080 if (pktType == RTCPPacketTypes::kPsfbRpsiItem) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001081 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1082 {
1083 // to us unknown
1084 // continue
1085 rtcpParser.Iterate();
1086 return;
1087 }
danilchap90a13512016-04-11 10:05:02 -07001088 // Received signal that we have a confirmed reference picture.
1089 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi;
niklase@google.com470e71d2011-07-07 08:21:25 +00001090 rtcpPacketInformation.rpsiPictureId = 0;
1091
1092 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001093 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1094 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001095 {
1096 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1097 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1098 }
1099 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1100 }
1101}
1102
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001103void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1104 RTCPPacketInformation& rtcpPacketInformation) {
1105 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001106 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001107 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001108 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001109 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1110 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001111 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001112 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001113}
1114
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001115void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1116 RTCPPacketInformation& rtcpPacketInformation) {
1117 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001118
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001119 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001120 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001121 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1122 pktType = rtcpParser.Iterate();
1123 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001124}
1125
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001126void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1127 RTCPPacketInformation& rtcpPacketInformation) {
1128 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1129 rtcpPacketInformation.interArrivalJitter =
1130 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001131}
1132
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001133void RTCPReceiver::HandleREMBItem(
1134 RTCPUtility::RTCPParserV2& rtcpParser,
1135 RTCPPacketInformation& rtcpPacketInformation) {
1136 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1137 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1138 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1139 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001140}
1141
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001142void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1143 RTCPPacketInformation& rtcpPacketInformation) {
1144 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1145 RTCPReceiveInformation* ptrReceiveInfo =
1146 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001147
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001148 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001149 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001150 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1151 pktType = rtcpParser.Iterate();
1152 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001153}
1154
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001155void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1156 const RTCPUtility::RTCPPacket& rtcpPacket,
1157 RTCPPacketInformation& rtcpPacketInformation) {
1158 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001159 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001160 return;
1161 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001162
1163 ++packet_type_counter_.fir_packets;
1164
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001165 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1166 // we don't know who this originate from
1167 if (receiveInfo) {
1168 // check if we have reported this FIRSequenceNumber before
1169 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
danilchap2b616392016-08-18 06:17:42 -07001170 receiveInfo->last_fir_sequence_number) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001171 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001172 // sanity; don't go crazy with the callbacks
danilchap2b616392016-08-18 06:17:42 -07001173 if ((now - receiveInfo->last_fir_request_ms) > RTCP_MIN_FRAME_LENGTH_MS) {
1174 receiveInfo->last_fir_request_ms = now;
1175 receiveInfo->last_fir_sequence_number =
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001176 rtcpPacket.FIRItem.CommandSequenceNumber;
1177 // received signal that we need to send a new key frame
1178 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1179 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001180 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001181 } else {
1182 // received signal that we need to send a new key frame
1183 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1184 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001185}
1186
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001187void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1188 RTCPPacketInformation& rtcpPacketInformation) {
1189 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001190
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001191 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1192 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1193 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001194
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001195 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001196}
1197
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001198void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1199 RTCPPacketInformation& rtcpPacketInformation) {
1200 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001201
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001202 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001203
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001204 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001205}
1206
Erik Språng6b8d3552015-09-24 15:06:57 +02001207void RTCPReceiver::HandleTransportFeedback(
1208 RTCPUtility::RTCPParserV2* rtcp_parser,
1209 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1210 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1211 RTC_DCHECK(packet != nullptr);
1212 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1213 rtcp_packet_information->transport_feedback_.reset(
1214 static_cast<rtcp::TransportFeedback*>(packet));
1215
1216 rtcp_parser->Iterate();
1217}
danilchap287e5482016-08-16 15:15:39 -07001218
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001219int32_t RTCPReceiver::UpdateTMMBR() {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001220 // Find bounding set
danilchap2f69ce92016-08-16 03:21:38 -07001221 std::vector<rtcp::TmmbItem> bounding =
danilchap287e5482016-08-16 15:15:39 -07001222 TMMBRHelp::FindBoundingSet(TMMBRReceived());
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001223 // Set bounding set
1224 // Inform remote clients about the new bandwidth
1225 // inform the remote client
Danil Chapovalovdaa90a72016-08-10 11:29:50 +02001226 _rtpRtcp.SetTMMBN(&bounding);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001227
1228 // might trigger a TMMBN
Danil Chapovalovdaa90a72016-08-10 11:29:50 +02001229 if (bounding.empty()) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001230 // owner of max bitrate request has timed out
1231 // empty bounding set has been sent
1232 return 0;
1233 }
danilchap2f69ce92016-08-16 03:21:38 -07001234 // We have a new bandwidth estimate on this channel.
1235 if (_cbRtcpBandwidthObserver) {
1236 uint64_t bitrate_bps = TMMBRHelp::CalcMinBitrateBps(bounding);
1237 if (bitrate_bps <= std::numeric_limits<uint32_t>::max())
1238 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate_bps);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001239 }
1240 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001241}
1242
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001243void RTCPReceiver::RegisterRtcpStatisticsCallback(
1244 RtcpStatisticsCallback* callback) {
danilchap7c9426c2016-04-14 03:05:31 -07001245 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001246 stats_callback_ = callback;
1247}
1248
1249RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
danilchap7c9426c2016-04-14 03:05:31 -07001250 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001251 return stats_callback_;
1252}
1253
niklase@google.com470e71d2011-07-07 08:21:25 +00001254// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001255void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001256 RTCPPacketInformation& rtcpPacketInformation) {
1257 // Process TMMBR and REMB first to avoid multiple callbacks
1258 // to OnNetworkChanged.
1259 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001260 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1261 UpdateTMMBR();
1262 }
sprang7dc39f32015-10-13 09:17:48 -07001263 uint32_t local_ssrc;
1264 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001265 {
1266 // We don't want to hold this critsect when triggering the callbacks below.
danilchap7c9426c2016-04-14 03:05:31 -07001267 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001268 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001269 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001270 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001271 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001272 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001273 _rtpRtcp.OnRequestSendReport();
1274 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001275 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001276 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001277 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001278 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001279 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001280 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001281 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001282 }
1283 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001284 // We need feedback that we have received a report block(s) so that we
1285 // can generate a new packet in a conference relay scenario, one received
1286 // report can generate several RTCP packets, based on number relayed/mixed
1287 // a send report block should go out to all receivers.
1288 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001289 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001290 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1291 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1292 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001293 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001294 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001295 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001296 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001297 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001298 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001299 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001300 }
1301 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1302 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001303 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001304 }
1305 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1306 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001307 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001308 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001309 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001310 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001311 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001312 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001313 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001314 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001315 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1316 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1317 }
Erik Språng242e22b2015-05-11 10:17:43 +02001318 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1319 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001320 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001321 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001322 rtcpPacketInformation.report_blocks,
1323 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001324 now);
1325 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001326 }
isheriff6b4b5f32016-06-08 00:24:21 -07001327 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1328 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
1329 _rtpRtcp.OnReceivedRtcpReportBlocks(rtcpPacketInformation.report_blocks);
1330 }
1331
Erik Språng6b8d3552015-09-24 15:06:57 +02001332 if (_cbTransportFeedbackObserver &&
1333 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1334 uint32_t media_source_ssrc =
1335 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001336 if (media_source_ssrc == local_ssrc ||
1337 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001338 _cbTransportFeedbackObserver->OnTransportFeedback(
1339 *rtcpPacketInformation.transport_feedback_.get());
1340 }
1341 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001342 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001343
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001344 if (!receiver_only_) {
danilchap7c9426c2016-04-14 03:05:31 -07001345 rtc::CritScope cs(&_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001346 if (stats_callback_) {
1347 for (ReportBlockList::const_iterator it =
1348 rtcpPacketInformation.report_blocks.begin();
1349 it != rtcpPacketInformation.report_blocks.end();
1350 ++it) {
1351 RtcpStatistics stats;
1352 stats.cumulative_lost = it->cumulativeLost;
1353 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1354 stats.fraction_lost = it->fractionLost;
1355 stats.jitter = it->jitter;
1356
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001357 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001358 }
1359 }
1360 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001361}
1362
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001363int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001364 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001365 assert(cName);
1366
danilchap7c9426c2016-04-14 03:05:31 -07001367 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001368 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001369 if (cnameInfo == NULL) {
1370 return -1;
1371 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001372 cName[RTCP_CNAME_SIZE - 1] = 0;
1373 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1374 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001375}
1376
danilchap287e5482016-08-16 15:15:39 -07001377std::vector<rtcp::TmmbItem> RTCPReceiver::TMMBRReceived() const {
danilchap7c9426c2016-04-14 03:05:31 -07001378 rtc::CritScope lock(&_criticalSectionRTCPReceiver);
danilchap287e5482016-08-16 15:15:39 -07001379 std::vector<rtcp::TmmbItem> candidates;
niklase@google.com470e71d2011-07-07 08:21:25 +00001380
danilchap287e5482016-08-16 15:15:39 -07001381 int64_t now_ms = _clock->TimeInMilliseconds();
1382
1383 for (const auto& kv : _receivedInfoMap) {
1384 RTCPReceiveInformation* receive_info = kv.second;
1385 RTC_DCHECK(receive_info);
danilchap2b616392016-08-18 06:17:42 -07001386 receive_info->GetTmmbrSet(now_ms, &candidates);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001387 }
danilchap287e5482016-08-16 15:15:39 -07001388 return candidates;
niklase@google.com470e71d2011-07-07 08:21:25 +00001389}
1390
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001391} // namespace webrtc