blob: 0259b73ff4e12fd666fda20d4b986df85d9d22bd [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
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000016#include <algorithm>
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"
25#include "webrtc/system_wrappers/include/ntp_time.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000026
niklase@google.com470e71d2011-07-07 08:21:25 +000027namespace webrtc {
danilchap6a6f0892015-12-10 12:39:08 -080028using RTCPHelp::RTCPPacketInformation;
29using RTCPHelp::RTCPReceiveInformation;
30using RTCPHelp::RTCPReportBlockInformation;
31using RTCPUtility::kBtVoipMetric;
32using RTCPUtility::RTCPCnameInformation;
33using RTCPUtility::RTCPPacketReportBlockItem;
34using RTCPUtility::RTCPPacketTypes;
niklase@google.com470e71d2011-07-07 08:21:25 +000035
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000036// The number of RTCP time intervals needed to trigger a timeout.
37const int kRrTimeoutIntervals = 3;
38
Erik Språng6b8d3552015-09-24 15:06:57 +020039const int64_t kMaxWarningLogIntervalMs = 10000;
40
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000041RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000042 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020043 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000044 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000045 RtcpBandwidthObserver* rtcp_bandwidth_observer,
46 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020047 TransportFeedbackObserver* transport_feedback_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000048 ModuleRtpRtcpImpl* owner)
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000049 : TMMBRHelp(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000050 _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020051 receiver_only_(receiver_only),
pbosda903ea2015-10-02 02:36:56 -070052 _method(RtcpMode::kOff),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000053 _lastReceived(0),
54 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000055 _criticalSectionFeedbacks(
56 CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000057 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
58 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020059 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000060 _criticalSectionRTCPReceiver(
61 CriticalSectionWrapper::CreateCriticalSection()),
62 main_ssrc_(0),
63 _remoteSSRC(0),
64 _remoteSenderInfo(),
65 _lastReceivedSRNTPsecs(0),
66 _lastReceivedSRNTPfrac(0),
67 _lastReceivedXRNTPsecs(0),
68 _lastReceivedXRNTPfrac(0),
69 xr_rr_rtt_ms_(0),
70 _receivedInfoMap(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000071 _lastReceivedRrMs(0),
72 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000073 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020074 packet_type_counter_observer_(packet_type_counter_observer),
75 num_skipped_packets_(0),
76 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000077 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000078}
79
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000080RTCPReceiver::~RTCPReceiver() {
81 delete _criticalSectionRTCPReceiver;
82 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000083
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000084 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
85 for (; it != _receivedReportBlockMap.end(); ++it) {
86 ReportBlockInfoMap* info_map = &(it->second);
87 while (!info_map->empty()) {
88 ReportBlockInfoMap::iterator it_info = info_map->begin();
89 delete it_info->second;
90 info_map->erase(it_info);
91 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000092 }
93 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000094 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000095 _receivedInfoMap.begin();
96 delete first->second;
97 _receivedInfoMap.erase(first);
98 }
99 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000100 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000101 _receivedCnameMap.begin();
102 delete first->second;
103 _receivedCnameMap.erase(first);
104 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000105}
106
pbosda903ea2015-10-02 02:36:56 -0700107RtcpMode RTCPReceiver::Status() const {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000108 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
109 return _method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000110}
111
pbosda903ea2015-10-02 02:36:56 -0700112void RTCPReceiver::SetRTCPStatus(RtcpMode method) {
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000113 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
114 _method = method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000115}
116
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000117int64_t RTCPReceiver::LastReceived() {
118 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
119 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000120}
121
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000122int64_t RTCPReceiver::LastReceivedReceiverReport() const {
123 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
124 int64_t last_received_rr = -1;
125 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
126 it != _receivedInfoMap.end(); ++it) {
127 if (it->second->lastTimeReceived > last_received_rr) {
128 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000129 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000130 }
131 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000132}
133
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000134void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
135 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000136
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000137 // new SSRC reset old reports
138 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
139 _lastReceivedSRNTPsecs = 0;
140 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000141
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000142 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000143}
144
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000145uint32_t RTCPReceiver::RemoteSSRC() const {
146 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
147 return _remoteSSRC;
148}
149
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000150void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
151 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000152 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000153 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000154 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000155 old_ssrc = main_ssrc_;
156 main_ssrc_ = main_ssrc;
157 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000158 }
159 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000160 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
161 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000162 }
163 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000164}
165
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000166int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000167 int64_t* RTT,
168 int64_t* avgRTT,
169 int64_t* minRTT,
170 int64_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000171 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000172
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000173 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000174 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000175
176 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000177 return -1;
178 }
179 if (RTT) {
180 *RTT = reportBlock->RTT;
181 }
182 if (avgRTT) {
183 *avgRTT = reportBlock->avgRTT;
184 }
185 if (minRTT) {
186 *minRTT = reportBlock->minRTT;
187 }
188 if (maxRTT) {
189 *maxRTT = reportBlock->maxRTT;
190 }
191 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000192}
193
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000194bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000195 assert(rtt_ms);
196 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
197 if (xr_rr_rtt_ms_ == 0) {
198 return false;
199 }
200 *rtt_ms = xr_rr_rtt_ms_;
201 xr_rr_rtt_ms_ = 0;
202 return true;
203}
204
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000205// TODO(pbos): Make this fail when we haven't received NTP.
206bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
207 uint32_t* ReceivedNTPfrac,
208 uint32_t* RTCPArrivalTimeSecs,
209 uint32_t* RTCPArrivalTimeFrac,
210 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000211{
212 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
213 if(ReceivedNTPsecs)
214 {
215 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
216 }
217 if(ReceivedNTPfrac)
218 {
219 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
220 }
221 if(RTCPArrivalTimeFrac)
222 {
223 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
224 }
225 if(RTCPArrivalTimeSecs)
226 {
227 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
228 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000229 if (rtcp_timestamp) {
230 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
231 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000232 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000233}
234
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000235bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
236 RtcpReceiveTimeInfo* info) const {
237 assert(info);
238 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
239 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
240 return false;
241 }
242
243 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
244 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
245
246 // Get the delay since last received report (RFC 3611).
247 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
248 _lastReceivedXRNTPfrac);
249
250 uint32_t ntp_sec = 0;
251 uint32_t ntp_frac = 0;
252 _clock->CurrentNtp(ntp_sec, ntp_frac);
253 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
254
255 info->delaySinceLastRR = now - receive_time;
256 return true;
257}
258
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000259int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
260 assert(senderInfo);
261 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
262 if (_lastReceivedSRNTPsecs == 0) {
263 return -1;
264 }
265 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
266 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000267}
268
269// statistics
270// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000271int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000272 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000273 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000274 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000275 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
276 for (; it != _receivedReportBlockMap.end(); ++it) {
277 const ReportBlockInfoMap* info_map = &(it->second);
278 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
279 for (; it_info != info_map->end(); ++it_info) {
280 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
281 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000282 }
283 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000284}
285
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000286int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000287RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
288 RTCPUtility::RTCPParserV2* rtcpParser)
289{
290 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
291
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000292 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000293
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000294 if (packet_type_counter_.first_packet_time_ms == -1) {
295 packet_type_counter_.first_packet_time_ms = _lastReceived;
296 }
297
niklase@google.com470e71d2011-07-07 08:21:25 +0000298 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200299 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000300 // Each "case" is responsible for iterate the parser to the
301 // next top level packet.
302 switch (pktType)
303 {
Erik Språng242e22b2015-05-11 10:17:43 +0200304 case RTCPPacketTypes::kSr:
305 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000306 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
307 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200308 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200309 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000310 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200311 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000312 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
313 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200314 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000315 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
316 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200317 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000318 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
319 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200320 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000321 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
322 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200323 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000324 HandleBYE(*rtcpParser);
325 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200326 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000327 HandleNACK(*rtcpParser, rtcpPacketInformation);
328 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200329 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000330 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
331 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200332 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000333 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200335 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000336 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
337 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200338 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 HandlePLI(*rtcpParser, rtcpPacketInformation);
340 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200341 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000342 HandleSLI(*rtcpParser, rtcpPacketInformation);
343 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200344 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000345 HandleRPSI(*rtcpParser, rtcpPacketInformation);
346 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200347 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000348 HandleIJ(*rtcpParser, rtcpPacketInformation);
349 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200350 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000351 HandleFIR(*rtcpParser, rtcpPacketInformation);
352 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200353 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000354 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
355 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200356 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000357 // generic application messages
358 HandleAPP(*rtcpParser, rtcpPacketInformation);
359 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200360 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000361 // generic application messages
362 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
363 break;
Erik Språng6b8d3552015-09-24 15:06:57 +0200364 case RTCPPacketTypes::kTransportFeedback:
365 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
366 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000367 default:
368 rtcpParser->Iterate();
369 break;
370 }
371 pktType = rtcpParser->PacketType();
372 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000373
374 if (packet_type_counter_observer_ != NULL) {
375 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
376 main_ssrc_, packet_type_counter_);
377 }
378
Erik Språng6b8d3552015-09-24 15:06:57 +0200379 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
380
381 int64_t now = _clock->TimeInMilliseconds();
382 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
383 num_skipped_packets_ > 0) {
384 last_skipped_packets_warning_ = now;
385 LOG(LS_WARNING)
386 << num_skipped_packets_
387 << " RTCP blocks were skipped due to being malformed or of "
388 "unrecognized/unsupported type, during the past "
389 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
390 }
391
niklase@google.com470e71d2011-07-07 08:21:25 +0000392 return 0;
393}
394
niklase@google.com470e71d2011-07-07 08:21:25 +0000395void
396RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
397 RTCPPacketInformation& rtcpPacketInformation)
398{
399 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
400 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
401
Erik Språng242e22b2015-05-11 10:17:43 +0200402 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
403 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000404
405 // SR.SenderSSRC
406 // The synchronization source identifier for the originator of this SR packet
407
408 // rtcpPacket.RR.SenderSSRC
409 // The source of the packet sender, same as of SR? or is this a CE?
410
Erik Språng242e22b2015-05-11 10:17:43 +0200411 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
412 ? rtcpPacket.RR.SenderSSRC
413 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000414
415 rtcpPacketInformation.remoteSSRC = remoteSSRC;
416
417 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
418 if (!ptrReceiveInfo)
419 {
420 rtcpParser.Iterate();
421 return;
422 }
423
Erik Språng242e22b2015-05-11 10:17:43 +0200424 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000425 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
426 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000427
niklase@google.com470e71d2011-07-07 08:21:25 +0000428 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
429 {
430 // only signal that we have received a SR when we accept one
431 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
432
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000433 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
434 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
435 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
436
niklase@google.com470e71d2011-07-07 08:21:25 +0000437 // We will only store the send report from one source, but
438 // we will store all the receive block
439
440 // Save the NTP time of this report
441 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
442 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
443 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
444 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
445 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
446
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000447 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000448 }
449 else
450 {
451 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
452 }
453 } else
454 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000455 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
456 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000457
458 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
459 }
460 UpdateReceiveInformation(*ptrReceiveInfo);
461
462 rtcpPacketType = rtcpParser.Iterate();
463
Erik Språng242e22b2015-05-11 10:17:43 +0200464 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000465 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000466 rtcpPacketType = rtcpParser.Iterate();
467 }
468}
469
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000470void RTCPReceiver::HandleReportBlock(
471 const RTCPUtility::RTCPPacket& rtcpPacket,
472 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000473 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000474 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000475 // This will be called once per report block in the RTCP packet.
476 // We filter out all report blocks that are not for us.
477 // Each packet has max 31 RR blocks.
478 //
479 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000480
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000481 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
482 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000483
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000484 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000485 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
486 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000487 // This block is not for us ignore it.
488 return;
489 }
490
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000491 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000492 CreateOrGetReportBlockInformation(remoteSSRC,
493 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000494 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000495 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
496 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000497 return;
498 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000499
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000500 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000501 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
502 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
503 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
504 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
505 reportBlock->remoteReceiveBlock.cumulativeLost =
506 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000507 if (rb.ExtendedHighestSequenceNumber >
508 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
509 // We have successfully delivered new RTP packets to the remote side after
510 // the last RR was sent from the remote side.
511 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000512 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000513 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
514 rb.ExtendedHighestSequenceNumber;
515 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
516 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
517 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
518
519 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
520 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
521 }
522
Danil Chapovalova094fd12016-02-22 18:59:36 +0100523 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
524 uint32_t rtt = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000525
Danil Chapovalova094fd12016-02-22 18:59:36 +0100526 if (send_time > 0) {
527 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
528 // Local NTP time.
529 uint32_t receive_time = CompactNtp(NtpTime(*_clock));
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000530
Danil Chapovalova094fd12016-02-22 18:59:36 +0100531 // RTT in 1/(2^16) seconds.
532 uint32_t rtt_ntp = receive_time - delay - send_time;
533 // Convert to 1/1000 seconds (milliseconds).
534 uint32_t rtt_ms = CompactNtpIntervalToMs(rtt_ntp);
535 rtt = std::max<uint32_t>(rtt_ms, 1);
536 if (rtt > reportBlock->maxRTT) {
537 // Store max RTT.
538 reportBlock->maxRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000539 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000540 if (reportBlock->minRTT == 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100541 // First RTT.
542 reportBlock->minRTT = rtt;
543 } else if (rtt < reportBlock->minRTT) {
544 // Store min RTT.
545 reportBlock->minRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000546 }
Danil Chapovalova094fd12016-02-22 18:59:36 +0100547 // Store last RTT.
548 reportBlock->RTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000549
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000550 // store average RTT
551 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000552 float ac = static_cast<float>(reportBlock->numAverageCalcs);
553 float newAverage =
Danil Chapovalova094fd12016-02-22 18:59:36 +0100554 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000555 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000556 } else {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100557 // First RTT.
558 reportBlock->avgRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000559 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000560 reportBlock->numAverageCalcs++;
561 }
562
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000563 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
Danil Chapovalova094fd12016-02-22 18:59:36 +0100564 rtt);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000565
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000566 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000567}
568
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000569RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
570 uint32_t remote_ssrc,
571 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000572 RTCPReportBlockInformation* info =
573 GetReportBlockInformation(remote_ssrc, source_ssrc);
574 if (info == NULL) {
575 info = new RTCPReportBlockInformation;
576 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000577 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000578 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000579}
580
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000581RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
582 uint32_t remote_ssrc,
583 uint32_t source_ssrc) const {
584 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000585 if (it == _receivedReportBlockMap.end()) {
586 return NULL;
587 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000588 const ReportBlockInfoMap* info_map = &(it->second);
589 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
590 if (it_info == info_map->end()) {
591 return NULL;
592 }
593 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000594}
595
596RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000597RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000598 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000599
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000600 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000601 _receivedCnameMap.find(remoteSSRC);
602
603 if (it != _receivedCnameMap.end()) {
604 return it->second;
605 }
606 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000607 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000608 _receivedCnameMap[remoteSSRC] = cnameInfo;
609 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000610}
611
612RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000613RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000614 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000615
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000616 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000617 _receivedCnameMap.find(remoteSSRC);
618
619 if (it == _receivedCnameMap.end()) {
620 return NULL;
621 }
622 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000623}
624
625RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000626RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000627 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000628
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000629 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000630 _receivedInfoMap.find(remoteSSRC);
631
632 if (it != _receivedInfoMap.end()) {
633 return it->second;
634 }
635 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
636 _receivedInfoMap[remoteSSRC] = receiveInfo;
637 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000638}
639
640RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000641RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000642 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000643
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000644 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000645 _receivedInfoMap.find(remoteSSRC);
646 if (it == _receivedInfoMap.end()) {
647 return NULL;
648 }
649 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000650}
651
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000652void RTCPReceiver::UpdateReceiveInformation(
653 RTCPReceiveInformation& receiveInformation) {
654 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000655 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000656}
657
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000658bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
659 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
660 if (_lastReceivedRrMs == 0)
661 return false;
662
663 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000664 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000665 // Reset the timer to only trigger one log.
666 _lastReceivedRrMs = 0;
667 return true;
668 }
669 return false;
670}
671
672bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
673 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
674 if (_lastIncreasedSequenceNumberMs == 0)
675 return false;
676
677 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000678 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000679 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000680 // Reset the timer to only trigger one log.
681 _lastIncreasedSequenceNumberMs = 0;
682 return true;
683 }
684 return false;
685}
686
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000687bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
688 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000689
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000690 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000691 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000692
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000693 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000694 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000695
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000696 while (receiveInfoIt != _receivedInfoMap.end()) {
697 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
698 if (receiveInfo == NULL) {
699 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000700 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000701 // time since last received rtcp packet
702 // when we dont have a lastTimeReceived and the object is marked
703 // readyForDelete it's removed from the map
704 if (receiveInfo->lastTimeReceived) {
705 /// use audio define since we don't know what interval the remote peer is
706 // using
707 if ((timeNow - receiveInfo->lastTimeReceived) >
708 5 * RTCP_INTERVAL_AUDIO_MS) {
709 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000710 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000711 // prevent that we call this over and over again
712 receiveInfo->lastTimeReceived = 0;
713 // send new TMMBN to all channels using the default codec
714 updateBoundingSet = true;
715 }
716 receiveInfoIt++;
717 } else if (receiveInfo->readyForDelete) {
718 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000719 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000720 receiveInfoItemToBeErased = receiveInfoIt;
721 receiveInfoIt++;
722 delete receiveInfoItemToBeErased->second;
723 _receivedInfoMap.erase(receiveInfoItemToBeErased);
724 } else {
725 receiveInfoIt++;
726 }
727 }
728 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000729}
730
danilchap6db6cdc2015-12-15 02:54:47 -0800731int32_t RTCPReceiver::BoundingSet(bool* tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000732 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000733
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000734 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000735 _receivedInfoMap.find(_remoteSSRC);
736
737 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000738 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000739 }
740 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
741 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000742 return -1;
743 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000744 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000745 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000746 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000747 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000748 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000749 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000750 // owner of bounding set
danilchap6db6cdc2015-12-15 02:54:47 -0800751 *tmmbrOwner = true;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000752 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000753 boundingSetRec->SetEntry(i,
754 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
755 receiveInfo->TmmbnBoundingSet.PacketOH(i),
756 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000757 }
758 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000759 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000760}
761
Erik Språnga38233a2015-07-24 09:58:18 +0200762void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
763 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000764 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200765 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000766 HandleSDESChunk(rtcpParser);
767 pktType = rtcpParser.Iterate();
768 }
Erik Språnga38233a2015-07-24 09:58:18 +0200769 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000770}
771
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000772void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
773 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
774 RTCPCnameInformation* cnameInfo =
775 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
776 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000777
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000778 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
779 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000780 {
781 CriticalSectionScoped lock(_criticalSectionFeedbacks);
782 if (stats_callback_ != NULL) {
783 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
784 rtcpPacket.CName.SenderSSRC);
785 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000786 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000787}
788
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000789void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
790 RTCPPacketInformation& rtcpPacketInformation) {
791 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200792 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000793 // Not to us.
794 rtcpParser.Iterate();
795 return;
796 }
797 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000798
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000799 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200800 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000801 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
802 pktType = rtcpParser.Iterate();
803 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000804
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000805 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
806 ++packet_type_counter_.nack_packets;
807 packet_type_counter_.nack_requests = nack_stats_.requests();
808 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
809 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000810}
811
niklase@google.com470e71d2011-07-07 08:21:25 +0000812void
813RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000814 RTCPPacketInformation& rtcpPacketInformation) {
815 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
816 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000817
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000818 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
819 if (bitMask) {
820 for (int i=1; i <= 16; ++i) {
821 if (bitMask & 0x01) {
822 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
823 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
824 }
825 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000826 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000827 }
828 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000829}
830
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000831void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
832 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000833
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000834 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000835 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
836 for (; it != _receivedReportBlockMap.end(); ++it) {
837 ReportBlockInfoMap* info_map = &(it->second);
838 ReportBlockInfoMap::iterator it_info = info_map->find(
839 rtcpPacket.BYE.SenderSSRC);
840 if (it_info != info_map->end()) {
841 delete it_info->second;
842 info_map->erase(it_info);
843 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000844 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000845
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000846 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000847 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000848 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000849
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000850 if (receiveInfoIt != _receivedInfoMap.end()) {
851 receiveInfoIt->second->readyForDelete = true;
852 }
853
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000854 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000855 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
856
857 if (cnameInfoIt != _receivedCnameMap.end()) {
858 delete cnameInfoIt->second;
859 _receivedCnameMap.erase(cnameInfoIt);
860 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000861 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000862 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000863}
864
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000865void RTCPReceiver::HandleXrHeader(
866 RTCPUtility::RTCPParserV2& parser,
867 RTCPPacketInformation& rtcpPacketInformation) {
868 const RTCPUtility::RTCPPacket& packet = parser.Packet();
869
870 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
871
872 parser.Iterate();
873}
874
875void RTCPReceiver::HandleXrReceiveReferenceTime(
876 RTCPUtility::RTCPParserV2& parser,
877 RTCPPacketInformation& rtcpPacketInformation) {
878 const RTCPUtility::RTCPPacket& packet = parser.Packet();
879
880 _remoteXRReceiveTimeInfo.sourceSSRC =
881 rtcpPacketInformation.xr_originator_ssrc;
882
883 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
884 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
885 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
886
887 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
888
889 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
890
891 parser.Iterate();
892}
893
894void RTCPReceiver::HandleXrDlrrReportBlock(
895 RTCPUtility::RTCPParserV2& parser,
896 RTCPPacketInformation& rtcpPacketInformation) {
897 const RTCPUtility::RTCPPacket& packet = parser.Packet();
898 // Iterate through sub-block(s), if any.
899 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
900
Erik Språng242e22b2015-05-11 10:17:43 +0200901 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000902 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
903 packet_type = parser.Iterate();
904 }
905}
906
907void RTCPReceiver::HandleXrDlrrReportBlockItem(
908 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000909 RTCPPacketInformation& rtcpPacketInformation)
910 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000911 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
912 registered_ssrcs_.end()) {
913 // Not to us.
914 return;
915 }
916
917 rtcpPacketInformation.xr_dlrr_item = true;
918
Danil Chapovalova094fd12016-02-22 18:59:36 +0100919 // The send_time and delay_rr fields are in units of 1/2^16 sec.
920 uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
921 // RFC3411, section 4.5, LRR field discription states:
922 // If no such block has been received, the field is set to zero.
923 if (send_time == 0)
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000924 return;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000925
Danil Chapovalova094fd12016-02-22 18:59:36 +0100926 uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
927 uint32_t now = CompactNtp(NtpTime(*_clock));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000928
Danil Chapovalova094fd12016-02-22 18:59:36 +0100929 uint32_t rtt_ntp = now - delay_rr - send_time;
930 uint32_t rtt_ms = CompactNtpIntervalToMs(rtt_ntp);
931 xr_rr_rtt_ms_ = std::max<uint32_t>(rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000932
933 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
934}
935
niklase@google.com470e71d2011-07-07 08:21:25 +0000936void
937RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
938 RTCPPacketInformation& rtcpPacketInformation)
939{
940 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
941
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000942 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000943 {
944 // Store VoIP metrics block if it's about me
945 // from OriginatorSSRC do we filter it?
946 // rtcpPacket.XR.OriginatorSSRC;
947
948 RTCPVoIPMetric receivedVoIPMetrics;
949 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
950 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
951 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
952 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
953 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
954 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
955 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
956 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
957 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
958 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
959 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
960 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
961 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
962 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
963 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
964 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
965 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
966 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
967 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
968 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
969
970 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
971
972 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
973 }
974 rtcpParser.Iterate();
975}
976
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000977void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
978 RTCPPacketInformation& rtcpPacketInformation) {
979 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000980 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000981 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000982
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000983 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000984 // Received a signal that we need to send a new key frame.
985 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
986 }
987 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000988}
989
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000990void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
991 RTCPPacketInformation& rtcpPacketInformation) {
992 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000993
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000994 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
995 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
996 if (ptrReceiveInfo == NULL) {
997 // This remote SSRC must be saved before.
998 rtcpParser.Iterate();
999 return;
1000 }
1001 if (rtcpPacket.TMMBR.MediaSSRC) {
1002 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1003 // in relay mode this is a valid number
1004 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1005 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001006
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001007 // Use packet length to calc max number of TMMBR blocks
1008 // each TMMBR block is 8 bytes
1009 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001010
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001011 // sanity, we can't have more than what's in one packet
1012 if (maxNumOfTMMBRBlocks > 200) {
1013 assert(false);
1014 rtcpParser.Iterate();
1015 return;
1016 }
1017 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001018
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001019 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001020 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001021 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1022 pktType = rtcpParser.Iterate();
1023 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001024}
1025
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001026void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1027 const RTCPUtility::RTCPPacket& rtcpPacket,
1028 RTCPPacketInformation& rtcpPacketInformation,
1029 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001030 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1031 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1032 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1033 _clock->TimeInMilliseconds());
1034 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1035 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001036}
1037
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001038void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1039 RTCPPacketInformation& rtcpPacketInformation) {
1040 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1041 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1042 rtcpPacket.TMMBN.SenderSSRC);
1043 if (ptrReceiveInfo == NULL) {
1044 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001045 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001046 return;
1047 }
1048 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1049 // Use packet length to calc max number of TMMBN blocks
1050 // each TMMBN block is 8 bytes
1051 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1052
1053 // sanity, we cant have more than what's in one packet
1054 if (maxNumOfTMMBNBlocks > 200) {
1055 assert(false);
1056 rtcpParser.Iterate();
1057 return;
1058 }
1059
1060 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1061
1062 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001063 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001064 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1065 pktType = rtcpParser.Iterate();
1066 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001067}
1068
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001069void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1070 RTCPPacketInformation& rtcpPacketInformation) {
1071 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1072 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001073}
1074
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001075void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1076 const RTCPUtility::RTCPPacket& rtcpPacket) {
1077 receiveInfo.TmmbnBoundingSet.AddEntry(
1078 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1079 rtcpPacket.TMMBNItem.MeasuredOverhead,
1080 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001081}
1082
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001083void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1084 RTCPPacketInformation& rtcpPacketInformation) {
1085 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1086 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001087 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001088 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1089 pktType = rtcpParser.Iterate();
1090 }
1091}
1092
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001093void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1094 RTCPPacketInformation& rtcpPacketInformation) {
1095 // in theory there could be multiple slices lost
1096 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1097 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001098}
1099
1100void
1101RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1102 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1103{
1104 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001105 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001106 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001107 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1108 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1109 {
1110 // to us unknown
1111 // continue
1112 rtcpParser.Iterate();
1113 return;
1114 }
1115 rtcpPacketInformation.rpsiPictureId = 0;
1116
1117 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001118 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1119 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001120 {
1121 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1122 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1123 }
1124 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1125 }
1126}
1127
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001128void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1129 RTCPPacketInformation& rtcpPacketInformation) {
1130 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001131 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001132 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001133 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001134 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1135 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001136 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001137 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001138}
1139
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001140void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1141 RTCPPacketInformation& rtcpPacketInformation) {
1142 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001143
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001144 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001145 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001146 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1147 pktType = rtcpParser.Iterate();
1148 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001149}
1150
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001151void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1152 RTCPPacketInformation& rtcpPacketInformation) {
1153 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1154 rtcpPacketInformation.interArrivalJitter =
1155 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001156}
1157
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001158void RTCPReceiver::HandleREMBItem(
1159 RTCPUtility::RTCPParserV2& rtcpParser,
1160 RTCPPacketInformation& rtcpPacketInformation) {
1161 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1162 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1163 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1164 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001165}
1166
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001167void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1168 RTCPPacketInformation& rtcpPacketInformation) {
1169 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1170 RTCPReceiveInformation* ptrReceiveInfo =
1171 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001172
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001173 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001174 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001175 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1176 pktType = rtcpParser.Iterate();
1177 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001178}
1179
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001180void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1181 const RTCPUtility::RTCPPacket& rtcpPacket,
1182 RTCPPacketInformation& rtcpPacketInformation) {
1183 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001184 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001185 return;
1186 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001187
1188 ++packet_type_counter_.fir_packets;
1189
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001190 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1191 // we don't know who this originate from
1192 if (receiveInfo) {
1193 // check if we have reported this FIRSequenceNumber before
1194 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1195 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001196 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001197 // sanity; don't go crazy with the callbacks
1198 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1199 receiveInfo->lastFIRRequest = now;
1200 receiveInfo->lastFIRSequenceNumber =
1201 rtcpPacket.FIRItem.CommandSequenceNumber;
1202 // received signal that we need to send a new key frame
1203 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1204 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001205 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001206 } else {
1207 // received signal that we need to send a new key frame
1208 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1209 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001210}
1211
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001212void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1213 RTCPPacketInformation& rtcpPacketInformation) {
1214 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001215
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001216 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1217 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1218 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001219
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001220 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001221}
1222
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001223void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1224 RTCPPacketInformation& rtcpPacketInformation) {
1225 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001226
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001227 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001228
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001229 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001230}
1231
Erik Språng6b8d3552015-09-24 15:06:57 +02001232void RTCPReceiver::HandleTransportFeedback(
1233 RTCPUtility::RTCPParserV2* rtcp_parser,
1234 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1235 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1236 RTC_DCHECK(packet != nullptr);
1237 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1238 rtcp_packet_information->transport_feedback_.reset(
1239 static_cast<rtcp::TransportFeedback*>(packet));
1240
1241 rtcp_parser->Iterate();
1242}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001243int32_t RTCPReceiver::UpdateTMMBR() {
1244 int32_t numBoundingSet = 0;
1245 uint32_t bitrate = 0;
1246 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001247
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001248 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001249 if (size > 0) {
1250 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1251 // Get candidate set from receiver.
1252 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1253 } else {
1254 // Candidate set empty.
1255 VerifyAndAllocateCandidateSet(0); // resets candidate set
1256 }
1257 // Find bounding set
1258 TMMBRSet* boundingSet = NULL;
1259 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1260 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001261 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001262 return -1;
1263 }
1264 // Set bounding set
1265 // Inform remote clients about the new bandwidth
1266 // inform the remote client
1267 _rtpRtcp.SetTMMBN(boundingSet);
1268
1269 // might trigger a TMMBN
1270 if (numBoundingSet == 0) {
1271 // owner of max bitrate request has timed out
1272 // empty bounding set has been sent
1273 return 0;
1274 }
1275 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001276 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001277 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001278 if (_cbRtcpBandwidthObserver) {
1279 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001280 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001281 }
1282 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001283}
1284
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001285void RTCPReceiver::RegisterRtcpStatisticsCallback(
1286 RtcpStatisticsCallback* callback) {
1287 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001288 stats_callback_ = callback;
1289}
1290
1291RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1292 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1293 return stats_callback_;
1294}
1295
niklase@google.com470e71d2011-07-07 08:21:25 +00001296// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001297void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001298 RTCPPacketInformation& rtcpPacketInformation) {
1299 // Process TMMBR and REMB first to avoid multiple callbacks
1300 // to OnNetworkChanged.
1301 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001302 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1303 UpdateTMMBR();
1304 }
sprang7dc39f32015-10-13 09:17:48 -07001305 uint32_t local_ssrc;
1306 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001307 {
1308 // We don't want to hold this critsect when triggering the callbacks below.
1309 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001310 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001311 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001312 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001313 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001314 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001315 _rtpRtcp.OnRequestSendReport();
1316 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001317 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001318 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001319 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001320 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001321 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001322 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001323 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001324 }
1325 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001326 // We need feedback that we have received a report block(s) so that we
1327 // can generate a new packet in a conference relay scenario, one received
1328 // report can generate several RTCP packets, based on number relayed/mixed
1329 // a send report block should go out to all receivers.
1330 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001331 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001332 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1333 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1334 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001335 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001336 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001337 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001338 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001339 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001340 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001341 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001342 }
1343 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1344 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001345 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001346 }
1347 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1348 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001349 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001350 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001351 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001352 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001353 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001354 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001355 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001356 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001357 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1358 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1359 }
Erik Språng242e22b2015-05-11 10:17:43 +02001360 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1361 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001362 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001363 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001364 rtcpPacketInformation.report_blocks,
1365 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001366 now);
1367 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001368 }
Erik Språng6b8d3552015-09-24 15:06:57 +02001369 if (_cbTransportFeedbackObserver &&
1370 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1371 uint32_t media_source_ssrc =
1372 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001373 if (media_source_ssrc == local_ssrc ||
1374 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001375 _cbTransportFeedbackObserver->OnTransportFeedback(
1376 *rtcpPacketInformation.transport_feedback_.get());
1377 }
1378 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001379 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001380
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001381 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001382 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1383 if (stats_callback_) {
1384 for (ReportBlockList::const_iterator it =
1385 rtcpPacketInformation.report_blocks.begin();
1386 it != rtcpPacketInformation.report_blocks.end();
1387 ++it) {
1388 RtcpStatistics stats;
1389 stats.cumulative_lost = it->cumulativeLost;
1390 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1391 stats.fraction_lost = it->fractionLost;
1392 stats.jitter = it->jitter;
1393
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001394 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001395 }
1396 }
1397 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001398}
1399
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001400int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001401 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001402 assert(cName);
1403
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001404 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1405 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001406 if (cnameInfo == NULL) {
1407 return -1;
1408 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001409 cName[RTCP_CNAME_SIZE - 1] = 0;
1410 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1411 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001412}
1413
1414// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001415int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1416 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001417 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001418 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001419
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001420 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001421 receiveInfoIt = _receivedInfoMap.begin();
1422 if (receiveInfoIt == _receivedInfoMap.end()) {
1423 return -1;
1424 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001425 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001426 if (candidateSet) {
1427 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1428 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1429 if (receiveInfo == NULL) {
1430 return 0;
1431 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001432 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001433 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001434 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001435 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001436 num++;
1437 }
1438 }
1439 receiveInfoIt++;
1440 }
1441 } else {
1442 while (receiveInfoIt != _receivedInfoMap.end()) {
1443 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1444 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001445 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001446 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001447 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001448 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001449 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001450 }
1451 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001452}
1453
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001454} // namespace webrtc