blob: e8a943f23eecaacb7889137feb98ba9719a2aff2 [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(),
71 _packetTimeOutMS(0),
72 _lastReceivedRrMs(0),
73 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000074 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020075 packet_type_counter_observer_(packet_type_counter_observer),
76 num_skipped_packets_(0),
77 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000078 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000079}
80
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000081RTCPReceiver::~RTCPReceiver() {
82 delete _criticalSectionRTCPReceiver;
83 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000084
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000085 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
86 for (; it != _receivedReportBlockMap.end(); ++it) {
87 ReportBlockInfoMap* info_map = &(it->second);
88 while (!info_map->empty()) {
89 ReportBlockInfoMap::iterator it_info = info_map->begin();
90 delete it_info->second;
91 info_map->erase(it_info);
92 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000093 }
94 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000095 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000096 _receivedInfoMap.begin();
97 delete first->second;
98 _receivedInfoMap.erase(first);
99 }
100 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000101 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000102 _receivedCnameMap.begin();
103 delete first->second;
104 _receivedCnameMap.erase(first);
105 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000106}
107
pbosda903ea2015-10-02 02:36:56 -0700108RtcpMode RTCPReceiver::Status() const {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000109 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
110 return _method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000111}
112
pbosda903ea2015-10-02 02:36:56 -0700113void RTCPReceiver::SetRTCPStatus(RtcpMode method) {
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000114 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
115 _method = method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000116}
117
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000118int64_t RTCPReceiver::LastReceived() {
119 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
120 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000121}
122
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000123int64_t RTCPReceiver::LastReceivedReceiverReport() const {
124 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
125 int64_t last_received_rr = -1;
126 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
127 it != _receivedInfoMap.end(); ++it) {
128 if (it->second->lastTimeReceived > last_received_rr) {
129 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000130 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000131 }
132 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000133}
134
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000135void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
136 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000137
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000138 // new SSRC reset old reports
139 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
140 _lastReceivedSRNTPsecs = 0;
141 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000142
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000143 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000144}
145
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000146uint32_t RTCPReceiver::RemoteSSRC() const {
147 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
148 return _remoteSSRC;
149}
150
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000151void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
152 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000153 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000154 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000155 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000156 old_ssrc = main_ssrc_;
157 main_ssrc_ = main_ssrc;
158 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000159 }
160 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000161 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
162 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000163 }
164 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000165}
166
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000167int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000168 int64_t* RTT,
169 int64_t* avgRTT,
170 int64_t* minRTT,
171 int64_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000172 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000173
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000174 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000175 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000176
177 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000178 return -1;
179 }
180 if (RTT) {
181 *RTT = reportBlock->RTT;
182 }
183 if (avgRTT) {
184 *avgRTT = reportBlock->avgRTT;
185 }
186 if (minRTT) {
187 *minRTT = reportBlock->minRTT;
188 }
189 if (maxRTT) {
190 *maxRTT = reportBlock->maxRTT;
191 }
192 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000193}
194
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000195bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000196 assert(rtt_ms);
197 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
198 if (xr_rr_rtt_ms_ == 0) {
199 return false;
200 }
201 *rtt_ms = xr_rr_rtt_ms_;
202 xr_rr_rtt_ms_ = 0;
203 return true;
204}
205
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000206// TODO(pbos): Make this fail when we haven't received NTP.
207bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
208 uint32_t* ReceivedNTPfrac,
209 uint32_t* RTCPArrivalTimeSecs,
210 uint32_t* RTCPArrivalTimeFrac,
211 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000212{
213 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
214 if(ReceivedNTPsecs)
215 {
216 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
217 }
218 if(ReceivedNTPfrac)
219 {
220 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
221 }
222 if(RTCPArrivalTimeFrac)
223 {
224 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
225 }
226 if(RTCPArrivalTimeSecs)
227 {
228 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
229 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000230 if (rtcp_timestamp) {
231 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
232 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000233 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000234}
235
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000236bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
237 RtcpReceiveTimeInfo* info) const {
238 assert(info);
239 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
240 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
241 return false;
242 }
243
244 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
245 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
246
247 // Get the delay since last received report (RFC 3611).
248 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
249 _lastReceivedXRNTPfrac);
250
251 uint32_t ntp_sec = 0;
252 uint32_t ntp_frac = 0;
253 _clock->CurrentNtp(ntp_sec, ntp_frac);
254 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
255
256 info->delaySinceLastRR = now - receive_time;
257 return true;
258}
259
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000260int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
261 assert(senderInfo);
262 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
263 if (_lastReceivedSRNTPsecs == 0) {
264 return -1;
265 }
266 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
267 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000268}
269
270// statistics
271// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000272int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000273 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000274 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000275 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000276 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
277 for (; it != _receivedReportBlockMap.end(); ++it) {
278 const ReportBlockInfoMap* info_map = &(it->second);
279 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
280 for (; it_info != info_map->end(); ++it_info) {
281 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
282 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000283 }
284 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000285}
286
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000287int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000288RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
289 RTCPUtility::RTCPParserV2* rtcpParser)
290{
291 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
292
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000293 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000294
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000295 if (packet_type_counter_.first_packet_time_ms == -1) {
296 packet_type_counter_.first_packet_time_ms = _lastReceived;
297 }
298
niklase@google.com470e71d2011-07-07 08:21:25 +0000299 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200300 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000301 // Each "case" is responsible for iterate the parser to the
302 // next top level packet.
303 switch (pktType)
304 {
Erik Språng242e22b2015-05-11 10:17:43 +0200305 case RTCPPacketTypes::kSr:
306 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000307 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
308 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200309 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200310 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000311 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200312 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000313 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
314 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200315 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000316 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
317 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200318 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000319 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
320 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200321 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000322 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
323 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200324 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000325 HandleBYE(*rtcpParser);
326 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200327 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 HandleNACK(*rtcpParser, rtcpPacketInformation);
329 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200330 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
332 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200333 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000334 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000335 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200336 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000337 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
338 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200339 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 HandlePLI(*rtcpParser, rtcpPacketInformation);
341 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200342 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 HandleSLI(*rtcpParser, rtcpPacketInformation);
344 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200345 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 HandleRPSI(*rtcpParser, rtcpPacketInformation);
347 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200348 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000349 HandleIJ(*rtcpParser, rtcpPacketInformation);
350 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200351 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000352 HandleFIR(*rtcpParser, rtcpPacketInformation);
353 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200354 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000355 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
356 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200357 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000358 // generic application messages
359 HandleAPP(*rtcpParser, rtcpPacketInformation);
360 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200361 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000362 // generic application messages
363 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
364 break;
Erik Språng6b8d3552015-09-24 15:06:57 +0200365 case RTCPPacketTypes::kTransportFeedback:
366 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
367 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000368 default:
369 rtcpParser->Iterate();
370 break;
371 }
372 pktType = rtcpParser->PacketType();
373 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000374
375 if (packet_type_counter_observer_ != NULL) {
376 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
377 main_ssrc_, packet_type_counter_);
378 }
379
Erik Språng6b8d3552015-09-24 15:06:57 +0200380 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
381
382 int64_t now = _clock->TimeInMilliseconds();
383 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
384 num_skipped_packets_ > 0) {
385 last_skipped_packets_warning_ = now;
386 LOG(LS_WARNING)
387 << num_skipped_packets_
388 << " RTCP blocks were skipped due to being malformed or of "
389 "unrecognized/unsupported type, during the past "
390 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
391 }
392
niklase@google.com470e71d2011-07-07 08:21:25 +0000393 return 0;
394}
395
niklase@google.com470e71d2011-07-07 08:21:25 +0000396void
397RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
398 RTCPPacketInformation& rtcpPacketInformation)
399{
400 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
401 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
402
Erik Språng242e22b2015-05-11 10:17:43 +0200403 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
404 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000405
406 // SR.SenderSSRC
407 // The synchronization source identifier for the originator of this SR packet
408
409 // rtcpPacket.RR.SenderSSRC
410 // The source of the packet sender, same as of SR? or is this a CE?
411
Erik Språng242e22b2015-05-11 10:17:43 +0200412 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
413 ? rtcpPacket.RR.SenderSSRC
414 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000415
416 rtcpPacketInformation.remoteSSRC = remoteSSRC;
417
418 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
419 if (!ptrReceiveInfo)
420 {
421 rtcpParser.Iterate();
422 return;
423 }
424
Erik Språng242e22b2015-05-11 10:17:43 +0200425 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000426 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
427 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000428
niklase@google.com470e71d2011-07-07 08:21:25 +0000429 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
430 {
431 // only signal that we have received a SR when we accept one
432 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
433
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000434 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
435 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
436 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
437
niklase@google.com470e71d2011-07-07 08:21:25 +0000438 // We will only store the send report from one source, but
439 // we will store all the receive block
440
441 // Save the NTP time of this report
442 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
443 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
444 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
445 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
446 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
447
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000448 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000449 }
450 else
451 {
452 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
453 }
454 } else
455 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000456 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
457 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000458
459 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
460 }
461 UpdateReceiveInformation(*ptrReceiveInfo);
462
463 rtcpPacketType = rtcpParser.Iterate();
464
Erik Språng242e22b2015-05-11 10:17:43 +0200465 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000466 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000467 rtcpPacketType = rtcpParser.Iterate();
468 }
469}
470
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000471void RTCPReceiver::HandleReportBlock(
472 const RTCPUtility::RTCPPacket& rtcpPacket,
473 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000474 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000475 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000476 // This will be called once per report block in the RTCP packet.
477 // We filter out all report blocks that are not for us.
478 // Each packet has max 31 RR blocks.
479 //
480 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000481
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000482 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
483 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000484
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000485 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000486 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
487 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000488 // This block is not for us ignore it.
489 return;
490 }
491
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000492 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000493 CreateOrGetReportBlockInformation(remoteSSRC,
494 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000495 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000496 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
497 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000498 return;
499 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000500
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000501 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000502 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
503 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
504 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
505 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
506 reportBlock->remoteReceiveBlock.cumulativeLost =
507 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000508 if (rb.ExtendedHighestSequenceNumber >
509 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
510 // We have successfully delivered new RTP packets to the remote side after
511 // the last RR was sent from the remote side.
512 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000513 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000514 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
515 rb.ExtendedHighestSequenceNumber;
516 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
517 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
518 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
519
520 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
521 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
522 }
523
Danil Chapovalova094fd12016-02-22 18:59:36 +0100524 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
525 uint32_t rtt = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000526
Danil Chapovalova094fd12016-02-22 18:59:36 +0100527 if (send_time > 0) {
528 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
529 // Local NTP time.
530 uint32_t receive_time = CompactNtp(NtpTime(*_clock));
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000531
Danil Chapovalova094fd12016-02-22 18:59:36 +0100532 // RTT in 1/(2^16) seconds.
533 uint32_t rtt_ntp = receive_time - delay - send_time;
534 // Convert to 1/1000 seconds (milliseconds).
535 uint32_t rtt_ms = CompactNtpIntervalToMs(rtt_ntp);
536 rtt = std::max<uint32_t>(rtt_ms, 1);
537 if (rtt > reportBlock->maxRTT) {
538 // Store max RTT.
539 reportBlock->maxRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000540 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000541 if (reportBlock->minRTT == 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100542 // First RTT.
543 reportBlock->minRTT = rtt;
544 } else if (rtt < reportBlock->minRTT) {
545 // Store min RTT.
546 reportBlock->minRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000547 }
Danil Chapovalova094fd12016-02-22 18:59:36 +0100548 // Store last RTT.
549 reportBlock->RTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000550
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000551 // store average RTT
552 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000553 float ac = static_cast<float>(reportBlock->numAverageCalcs);
554 float newAverage =
Danil Chapovalova094fd12016-02-22 18:59:36 +0100555 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000556 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000557 } else {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100558 // First RTT.
559 reportBlock->avgRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000560 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000561 reportBlock->numAverageCalcs++;
562 }
563
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000564 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
Danil Chapovalova094fd12016-02-22 18:59:36 +0100565 rtt);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000566
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000567 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000568}
569
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000570RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
571 uint32_t remote_ssrc,
572 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000573 RTCPReportBlockInformation* info =
574 GetReportBlockInformation(remote_ssrc, source_ssrc);
575 if (info == NULL) {
576 info = new RTCPReportBlockInformation;
577 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000578 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000579 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000580}
581
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000582RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
583 uint32_t remote_ssrc,
584 uint32_t source_ssrc) const {
585 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000586 if (it == _receivedReportBlockMap.end()) {
587 return NULL;
588 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000589 const ReportBlockInfoMap* info_map = &(it->second);
590 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
591 if (it_info == info_map->end()) {
592 return NULL;
593 }
594 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000595}
596
597RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000598RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000599 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000600
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000601 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000602 _receivedCnameMap.find(remoteSSRC);
603
604 if (it != _receivedCnameMap.end()) {
605 return it->second;
606 }
607 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000608 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000609 _receivedCnameMap[remoteSSRC] = cnameInfo;
610 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000611}
612
613RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000614RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000615 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000616
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000617 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000618 _receivedCnameMap.find(remoteSSRC);
619
620 if (it == _receivedCnameMap.end()) {
621 return NULL;
622 }
623 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000624}
625
626RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000627RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000628 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000629
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000630 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000631 _receivedInfoMap.find(remoteSSRC);
632
633 if (it != _receivedInfoMap.end()) {
634 return it->second;
635 }
636 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
637 _receivedInfoMap[remoteSSRC] = receiveInfo;
638 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000639}
640
641RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000642RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000643 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000644
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000645 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000646 _receivedInfoMap.find(remoteSSRC);
647 if (it == _receivedInfoMap.end()) {
648 return NULL;
649 }
650 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000651}
652
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000653void RTCPReceiver::UpdateReceiveInformation(
654 RTCPReceiveInformation& receiveInformation) {
655 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000656 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000657}
658
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000659bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
660 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
661 if (_lastReceivedRrMs == 0)
662 return false;
663
664 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000665 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000666 // Reset the timer to only trigger one log.
667 _lastReceivedRrMs = 0;
668 return true;
669 }
670 return false;
671}
672
673bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
674 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
675 if (_lastIncreasedSequenceNumberMs == 0)
676 return false;
677
678 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000679 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000680 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000681 // Reset the timer to only trigger one log.
682 _lastIncreasedSequenceNumberMs = 0;
683 return true;
684 }
685 return false;
686}
687
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000688bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
689 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000690
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000691 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000692 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000693
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000694 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000695 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000696
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000697 while (receiveInfoIt != _receivedInfoMap.end()) {
698 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
699 if (receiveInfo == NULL) {
700 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000701 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000702 // time since last received rtcp packet
703 // when we dont have a lastTimeReceived and the object is marked
704 // readyForDelete it's removed from the map
705 if (receiveInfo->lastTimeReceived) {
706 /// use audio define since we don't know what interval the remote peer is
707 // using
708 if ((timeNow - receiveInfo->lastTimeReceived) >
709 5 * RTCP_INTERVAL_AUDIO_MS) {
710 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000711 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000712 // prevent that we call this over and over again
713 receiveInfo->lastTimeReceived = 0;
714 // send new TMMBN to all channels using the default codec
715 updateBoundingSet = true;
716 }
717 receiveInfoIt++;
718 } else if (receiveInfo->readyForDelete) {
719 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000720 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000721 receiveInfoItemToBeErased = receiveInfoIt;
722 receiveInfoIt++;
723 delete receiveInfoItemToBeErased->second;
724 _receivedInfoMap.erase(receiveInfoItemToBeErased);
725 } else {
726 receiveInfoIt++;
727 }
728 }
729 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000730}
731
danilchap6db6cdc2015-12-15 02:54:47 -0800732int32_t RTCPReceiver::BoundingSet(bool* tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000733 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000734
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000735 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000736 _receivedInfoMap.find(_remoteSSRC);
737
738 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000739 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000740 }
741 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
742 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000743 return -1;
744 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000745 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000746 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000747 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000748 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000749 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000750 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000751 // owner of bounding set
danilchap6db6cdc2015-12-15 02:54:47 -0800752 *tmmbrOwner = true;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000753 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000754 boundingSetRec->SetEntry(i,
755 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
756 receiveInfo->TmmbnBoundingSet.PacketOH(i),
757 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000758 }
759 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000760 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000761}
762
Erik Språnga38233a2015-07-24 09:58:18 +0200763void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
764 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000765 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200766 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000767 HandleSDESChunk(rtcpParser);
768 pktType = rtcpParser.Iterate();
769 }
Erik Språnga38233a2015-07-24 09:58:18 +0200770 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000771}
772
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000773void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
774 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
775 RTCPCnameInformation* cnameInfo =
776 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
777 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000778
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000779 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
780 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000781 {
782 CriticalSectionScoped lock(_criticalSectionFeedbacks);
783 if (stats_callback_ != NULL) {
784 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
785 rtcpPacket.CName.SenderSSRC);
786 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000787 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000788}
789
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000790void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
791 RTCPPacketInformation& rtcpPacketInformation) {
792 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200793 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000794 // Not to us.
795 rtcpParser.Iterate();
796 return;
797 }
798 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000799
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000800 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200801 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000802 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
803 pktType = rtcpParser.Iterate();
804 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000805
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000806 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
807 ++packet_type_counter_.nack_packets;
808 packet_type_counter_.nack_requests = nack_stats_.requests();
809 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
810 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000811}
812
niklase@google.com470e71d2011-07-07 08:21:25 +0000813void
814RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000815 RTCPPacketInformation& rtcpPacketInformation) {
816 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
817 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000818
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000819 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
820 if (bitMask) {
821 for (int i=1; i <= 16; ++i) {
822 if (bitMask & 0x01) {
823 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
824 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
825 }
826 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000827 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000828 }
829 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000830}
831
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000832void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
833 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000834
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000835 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000836 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
837 for (; it != _receivedReportBlockMap.end(); ++it) {
838 ReportBlockInfoMap* info_map = &(it->second);
839 ReportBlockInfoMap::iterator it_info = info_map->find(
840 rtcpPacket.BYE.SenderSSRC);
841 if (it_info != info_map->end()) {
842 delete it_info->second;
843 info_map->erase(it_info);
844 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000845 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000846
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000847 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000848 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000849 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000850
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000851 if (receiveInfoIt != _receivedInfoMap.end()) {
852 receiveInfoIt->second->readyForDelete = true;
853 }
854
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000855 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000856 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
857
858 if (cnameInfoIt != _receivedCnameMap.end()) {
859 delete cnameInfoIt->second;
860 _receivedCnameMap.erase(cnameInfoIt);
861 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000862 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000863 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000864}
865
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000866void RTCPReceiver::HandleXrHeader(
867 RTCPUtility::RTCPParserV2& parser,
868 RTCPPacketInformation& rtcpPacketInformation) {
869 const RTCPUtility::RTCPPacket& packet = parser.Packet();
870
871 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
872
873 parser.Iterate();
874}
875
876void RTCPReceiver::HandleXrReceiveReferenceTime(
877 RTCPUtility::RTCPParserV2& parser,
878 RTCPPacketInformation& rtcpPacketInformation) {
879 const RTCPUtility::RTCPPacket& packet = parser.Packet();
880
881 _remoteXRReceiveTimeInfo.sourceSSRC =
882 rtcpPacketInformation.xr_originator_ssrc;
883
884 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
885 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
886 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
887
888 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
889
890 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
891
892 parser.Iterate();
893}
894
895void RTCPReceiver::HandleXrDlrrReportBlock(
896 RTCPUtility::RTCPParserV2& parser,
897 RTCPPacketInformation& rtcpPacketInformation) {
898 const RTCPUtility::RTCPPacket& packet = parser.Packet();
899 // Iterate through sub-block(s), if any.
900 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
901
Erik Språng242e22b2015-05-11 10:17:43 +0200902 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000903 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
904 packet_type = parser.Iterate();
905 }
906}
907
908void RTCPReceiver::HandleXrDlrrReportBlockItem(
909 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000910 RTCPPacketInformation& rtcpPacketInformation)
911 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000912 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
913 registered_ssrcs_.end()) {
914 // Not to us.
915 return;
916 }
917
918 rtcpPacketInformation.xr_dlrr_item = true;
919
Danil Chapovalova094fd12016-02-22 18:59:36 +0100920 // The send_time and delay_rr fields are in units of 1/2^16 sec.
921 uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
922 // RFC3411, section 4.5, LRR field discription states:
923 // If no such block has been received, the field is set to zero.
924 if (send_time == 0)
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000925 return;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000926
Danil Chapovalova094fd12016-02-22 18:59:36 +0100927 uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
928 uint32_t now = CompactNtp(NtpTime(*_clock));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000929
Danil Chapovalova094fd12016-02-22 18:59:36 +0100930 uint32_t rtt_ntp = now - delay_rr - send_time;
931 uint32_t rtt_ms = CompactNtpIntervalToMs(rtt_ntp);
932 xr_rr_rtt_ms_ = std::max<uint32_t>(rtt_ms, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000933
934 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
935}
936
niklase@google.com470e71d2011-07-07 08:21:25 +0000937void
938RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
939 RTCPPacketInformation& rtcpPacketInformation)
940{
941 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
942
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000943 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000944 {
945 // Store VoIP metrics block if it's about me
946 // from OriginatorSSRC do we filter it?
947 // rtcpPacket.XR.OriginatorSSRC;
948
949 RTCPVoIPMetric receivedVoIPMetrics;
950 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
951 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
952 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
953 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
954 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
955 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
956 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
957 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
958 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
959 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
960 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
961 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
962 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
963 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
964 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
965 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
966 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
967 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
968 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
969 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
970
971 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
972
973 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
974 }
975 rtcpParser.Iterate();
976}
977
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000978void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
979 RTCPPacketInformation& rtcpPacketInformation) {
980 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000981 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000982 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000983
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000984 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000985 // Received a signal that we need to send a new key frame.
986 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
987 }
988 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000989}
990
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000991void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
992 RTCPPacketInformation& rtcpPacketInformation) {
993 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000994
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000995 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
996 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
997 if (ptrReceiveInfo == NULL) {
998 // This remote SSRC must be saved before.
999 rtcpParser.Iterate();
1000 return;
1001 }
1002 if (rtcpPacket.TMMBR.MediaSSRC) {
1003 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1004 // in relay mode this is a valid number
1005 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1006 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001007
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001008 // Use packet length to calc max number of TMMBR blocks
1009 // each TMMBR block is 8 bytes
1010 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001011
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001012 // sanity, we can't have more than what's in one packet
1013 if (maxNumOfTMMBRBlocks > 200) {
1014 assert(false);
1015 rtcpParser.Iterate();
1016 return;
1017 }
1018 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001019
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001020 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001021 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001022 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1023 pktType = rtcpParser.Iterate();
1024 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001025}
1026
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001027void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1028 const RTCPUtility::RTCPPacket& rtcpPacket,
1029 RTCPPacketInformation& rtcpPacketInformation,
1030 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001031 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1032 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1033 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1034 _clock->TimeInMilliseconds());
1035 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1036 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001037}
1038
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001039void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1040 RTCPPacketInformation& rtcpPacketInformation) {
1041 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1042 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1043 rtcpPacket.TMMBN.SenderSSRC);
1044 if (ptrReceiveInfo == NULL) {
1045 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001046 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001047 return;
1048 }
1049 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1050 // Use packet length to calc max number of TMMBN blocks
1051 // each TMMBN block is 8 bytes
1052 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1053
1054 // sanity, we cant have more than what's in one packet
1055 if (maxNumOfTMMBNBlocks > 200) {
1056 assert(false);
1057 rtcpParser.Iterate();
1058 return;
1059 }
1060
1061 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1062
1063 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001064 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001065 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1066 pktType = rtcpParser.Iterate();
1067 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001068}
1069
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001070void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1071 RTCPPacketInformation& rtcpPacketInformation) {
1072 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1073 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001074}
1075
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001076void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1077 const RTCPUtility::RTCPPacket& rtcpPacket) {
1078 receiveInfo.TmmbnBoundingSet.AddEntry(
1079 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1080 rtcpPacket.TMMBNItem.MeasuredOverhead,
1081 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001082}
1083
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001084void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1085 RTCPPacketInformation& rtcpPacketInformation) {
1086 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1087 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001088 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001089 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1090 pktType = rtcpParser.Iterate();
1091 }
1092}
1093
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001094void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1095 RTCPPacketInformation& rtcpPacketInformation) {
1096 // in theory there could be multiple slices lost
1097 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1098 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001099}
1100
1101void
1102RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1103 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1104{
1105 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001106 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001107 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001108 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1109 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1110 {
1111 // to us unknown
1112 // continue
1113 rtcpParser.Iterate();
1114 return;
1115 }
1116 rtcpPacketInformation.rpsiPictureId = 0;
1117
1118 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001119 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1120 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001121 {
1122 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1123 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1124 }
1125 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1126 }
1127}
1128
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001129void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1130 RTCPPacketInformation& rtcpPacketInformation) {
1131 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001132 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001133 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001134 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001135 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1136 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001137 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001138 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001139}
1140
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001141void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1142 RTCPPacketInformation& rtcpPacketInformation) {
1143 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001144
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001145 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001146 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001147 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1148 pktType = rtcpParser.Iterate();
1149 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001150}
1151
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001152void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1153 RTCPPacketInformation& rtcpPacketInformation) {
1154 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1155 rtcpPacketInformation.interArrivalJitter =
1156 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001157}
1158
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001159void RTCPReceiver::HandleREMBItem(
1160 RTCPUtility::RTCPParserV2& rtcpParser,
1161 RTCPPacketInformation& rtcpPacketInformation) {
1162 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1163 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1164 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1165 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001166}
1167
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001168void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1169 RTCPPacketInformation& rtcpPacketInformation) {
1170 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1171 RTCPReceiveInformation* ptrReceiveInfo =
1172 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001173
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001174 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001175 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001176 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1177 pktType = rtcpParser.Iterate();
1178 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001179}
1180
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001181void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1182 const RTCPUtility::RTCPPacket& rtcpPacket,
1183 RTCPPacketInformation& rtcpPacketInformation) {
1184 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001185 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001186 return;
1187 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001188
1189 ++packet_type_counter_.fir_packets;
1190
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001191 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1192 // we don't know who this originate from
1193 if (receiveInfo) {
1194 // check if we have reported this FIRSequenceNumber before
1195 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1196 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001197 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001198 // sanity; don't go crazy with the callbacks
1199 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1200 receiveInfo->lastFIRRequest = now;
1201 receiveInfo->lastFIRSequenceNumber =
1202 rtcpPacket.FIRItem.CommandSequenceNumber;
1203 // received signal that we need to send a new key frame
1204 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1205 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001206 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001207 } else {
1208 // received signal that we need to send a new key frame
1209 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1210 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001211}
1212
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001213void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1214 RTCPPacketInformation& rtcpPacketInformation) {
1215 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001216
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001217 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1218 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1219 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001220
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001221 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001222}
1223
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001224void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1225 RTCPPacketInformation& rtcpPacketInformation) {
1226 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001227
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001228 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001229
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001230 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001231}
1232
Erik Språng6b8d3552015-09-24 15:06:57 +02001233void RTCPReceiver::HandleTransportFeedback(
1234 RTCPUtility::RTCPParserV2* rtcp_parser,
1235 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1236 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1237 RTC_DCHECK(packet != nullptr);
1238 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1239 rtcp_packet_information->transport_feedback_.reset(
1240 static_cast<rtcp::TransportFeedback*>(packet));
1241
1242 rtcp_parser->Iterate();
1243}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001244int32_t RTCPReceiver::UpdateTMMBR() {
1245 int32_t numBoundingSet = 0;
1246 uint32_t bitrate = 0;
1247 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001248
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001249 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001250 if (size > 0) {
1251 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1252 // Get candidate set from receiver.
1253 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1254 } else {
1255 // Candidate set empty.
1256 VerifyAndAllocateCandidateSet(0); // resets candidate set
1257 }
1258 // Find bounding set
1259 TMMBRSet* boundingSet = NULL;
1260 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1261 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001262 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001263 return -1;
1264 }
1265 // Set bounding set
1266 // Inform remote clients about the new bandwidth
1267 // inform the remote client
1268 _rtpRtcp.SetTMMBN(boundingSet);
1269
1270 // might trigger a TMMBN
1271 if (numBoundingSet == 0) {
1272 // owner of max bitrate request has timed out
1273 // empty bounding set has been sent
1274 return 0;
1275 }
1276 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001277 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001278 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001279 if (_cbRtcpBandwidthObserver) {
1280 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001281 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001282 }
1283 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001284}
1285
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001286void RTCPReceiver::RegisterRtcpStatisticsCallback(
1287 RtcpStatisticsCallback* callback) {
1288 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001289 stats_callback_ = callback;
1290}
1291
1292RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1293 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1294 return stats_callback_;
1295}
1296
niklase@google.com470e71d2011-07-07 08:21:25 +00001297// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001298void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001299 RTCPPacketInformation& rtcpPacketInformation) {
1300 // Process TMMBR and REMB first to avoid multiple callbacks
1301 // to OnNetworkChanged.
1302 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001303 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1304 UpdateTMMBR();
1305 }
sprang7dc39f32015-10-13 09:17:48 -07001306 uint32_t local_ssrc;
1307 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001308 {
1309 // We don't want to hold this critsect when triggering the callbacks below.
1310 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001311 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001312 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001313 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001314 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001315 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001316 _rtpRtcp.OnRequestSendReport();
1317 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001318 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001319 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001320 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001321 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001322 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001323 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001324 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001325 }
1326 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001327 // We need feedback that we have received a report block(s) so that we
1328 // can generate a new packet in a conference relay scenario, one received
1329 // report can generate several RTCP packets, based on number relayed/mixed
1330 // a send report block should go out to all receivers.
1331 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001332 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001333 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1334 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1335 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001336 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001337 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001338 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001339 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001340 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001341 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001342 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001343 }
1344 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1345 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001346 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001347 }
1348 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1349 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001350 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001351 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001352 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001353 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001354 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001355 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001356 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001357 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001358 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1359 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1360 }
Erik Språng242e22b2015-05-11 10:17:43 +02001361 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1362 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001363 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001364 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001365 rtcpPacketInformation.report_blocks,
1366 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001367 now);
1368 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001369 }
Erik Språng6b8d3552015-09-24 15:06:57 +02001370 if (_cbTransportFeedbackObserver &&
1371 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1372 uint32_t media_source_ssrc =
1373 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001374 if (media_source_ssrc == local_ssrc ||
1375 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001376 _cbTransportFeedbackObserver->OnTransportFeedback(
1377 *rtcpPacketInformation.transport_feedback_.get());
1378 }
1379 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001380 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001381
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001382 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001383 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1384 if (stats_callback_) {
1385 for (ReportBlockList::const_iterator it =
1386 rtcpPacketInformation.report_blocks.begin();
1387 it != rtcpPacketInformation.report_blocks.end();
1388 ++it) {
1389 RtcpStatistics stats;
1390 stats.cumulative_lost = it->cumulativeLost;
1391 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1392 stats.fraction_lost = it->fractionLost;
1393 stats.jitter = it->jitter;
1394
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001395 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001396 }
1397 }
1398 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001399}
1400
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001401int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001402 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001403 assert(cName);
1404
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001405 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1406 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001407 if (cnameInfo == NULL) {
1408 return -1;
1409 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001410 cName[RTCP_CNAME_SIZE - 1] = 0;
1411 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1412 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001413}
1414
1415// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001416int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1417 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001418 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001419 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001420
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001421 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001422 receiveInfoIt = _receivedInfoMap.begin();
1423 if (receiveInfoIt == _receivedInfoMap.end()) {
1424 return -1;
1425 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001426 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001427 if (candidateSet) {
1428 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1429 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1430 if (receiveInfo == NULL) {
1431 return 0;
1432 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001433 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001434 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001435 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001436 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001437 num++;
1438 }
1439 }
1440 receiveInfoIt++;
1441 }
1442 } else {
1443 while (receiveInfoIt != _receivedInfoMap.end()) {
1444 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1445 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001446 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001447 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001448 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001449 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001450 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001451 }
1452 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001453}
1454
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001455} // namespace webrtc