blob: 0873254f6346f92c824fb62945a87ec1b7249bf0 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000011#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
Peter Boströmfe7a80c2015-04-23 17:53:17 +020013#include <assert.h>
14#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000015
Peter Boströmfe7a80c2015-04-23 17:53:17 +020016#include "webrtc/base/checks.h"
Peter Boströmebc0b4e2015-10-28 16:39:33 +010017#include "webrtc/base/logging.h"
tommie4f96502015-10-20 23:00:48 -070018#include "webrtc/base/trace_event.h"
Erik Språng6b8d3552015-09-24 15:06:57 +020019#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
tommie4f96502015-10-20 23:00:48 -070020#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000021#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010022#include "webrtc/modules/rtp_rtcp/source/time_util.h"
23#include "webrtc/system_wrappers/include/ntp_time.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000024
niklase@google.com470e71d2011-07-07 08:21:25 +000025namespace webrtc {
danilchap6a6f0892015-12-10 12:39:08 -080026using RTCPHelp::RTCPPacketInformation;
27using RTCPHelp::RTCPReceiveInformation;
28using RTCPHelp::RTCPReportBlockInformation;
29using RTCPUtility::kBtVoipMetric;
30using RTCPUtility::RTCPCnameInformation;
31using RTCPUtility::RTCPPacketReportBlockItem;
32using RTCPUtility::RTCPPacketTypes;
niklase@google.com470e71d2011-07-07 08:21:25 +000033
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000034// The number of RTCP time intervals needed to trigger a timeout.
35const int kRrTimeoutIntervals = 3;
36
Erik Språng6b8d3552015-09-24 15:06:57 +020037const int64_t kMaxWarningLogIntervalMs = 10000;
38
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000039RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000040 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020041 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000042 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000043 RtcpBandwidthObserver* rtcp_bandwidth_observer,
44 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020045 TransportFeedbackObserver* transport_feedback_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000046 ModuleRtpRtcpImpl* owner)
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000047 : TMMBRHelp(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000048 _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020049 receiver_only_(receiver_only),
pbosda903ea2015-10-02 02:36:56 -070050 _method(RtcpMode::kOff),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000051 _lastReceived(0),
52 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000053 _criticalSectionFeedbacks(
54 CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000055 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
56 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020057 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000058 _criticalSectionRTCPReceiver(
59 CriticalSectionWrapper::CreateCriticalSection()),
60 main_ssrc_(0),
61 _remoteSSRC(0),
62 _remoteSenderInfo(),
63 _lastReceivedSRNTPsecs(0),
64 _lastReceivedSRNTPfrac(0),
65 _lastReceivedXRNTPsecs(0),
66 _lastReceivedXRNTPfrac(0),
Danil Chapovalovc1e55c72016-03-09 15:14:35 +010067 xr_rrtr_status_(false),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000068 xr_rr_rtt_ms_(0),
69 _receivedInfoMap(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000070 _lastReceivedRrMs(0),
71 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000072 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020073 packet_type_counter_observer_(packet_type_counter_observer),
74 num_skipped_packets_(0),
75 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000076 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000077}
78
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000079RTCPReceiver::~RTCPReceiver() {
80 delete _criticalSectionRTCPReceiver;
81 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000082
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000083 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
84 for (; it != _receivedReportBlockMap.end(); ++it) {
85 ReportBlockInfoMap* info_map = &(it->second);
86 while (!info_map->empty()) {
87 ReportBlockInfoMap::iterator it_info = info_map->begin();
88 delete it_info->second;
89 info_map->erase(it_info);
90 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000091 }
92 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000093 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000094 _receivedInfoMap.begin();
95 delete first->second;
96 _receivedInfoMap.erase(first);
97 }
98 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000099 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000100 _receivedCnameMap.begin();
101 delete first->second;
102 _receivedCnameMap.erase(first);
103 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000104}
105
pbosda903ea2015-10-02 02:36:56 -0700106RtcpMode RTCPReceiver::Status() const {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000107 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
108 return _method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000109}
110
pbosda903ea2015-10-02 02:36:56 -0700111void RTCPReceiver::SetRTCPStatus(RtcpMode method) {
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000112 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
113 _method = method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000114}
115
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000116int64_t RTCPReceiver::LastReceived() {
117 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
118 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000119}
120
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000121int64_t RTCPReceiver::LastReceivedReceiverReport() const {
122 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
123 int64_t last_received_rr = -1;
124 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
125 it != _receivedInfoMap.end(); ++it) {
126 if (it->second->lastTimeReceived > last_received_rr) {
127 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000128 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000129 }
130 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000131}
132
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000133void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
134 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000135
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000136 // new SSRC reset old reports
137 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
138 _lastReceivedSRNTPsecs = 0;
139 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000140
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000141 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000142}
143
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000144uint32_t RTCPReceiver::RemoteSSRC() const {
145 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
146 return _remoteSSRC;
147}
148
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000149void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
150 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000151 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000152 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000153 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000154 old_ssrc = main_ssrc_;
155 main_ssrc_ = main_ssrc;
156 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000157 }
158 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000159 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
160 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000161 }
162 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000163}
164
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000165int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000166 int64_t* RTT,
167 int64_t* avgRTT,
168 int64_t* minRTT,
169 int64_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000170 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000171
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000172 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000173 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000174
175 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000176 return -1;
177 }
178 if (RTT) {
179 *RTT = reportBlock->RTT;
180 }
181 if (avgRTT) {
182 *avgRTT = reportBlock->avgRTT;
183 }
184 if (minRTT) {
185 *minRTT = reportBlock->minRTT;
186 }
187 if (maxRTT) {
188 *maxRTT = reportBlock->maxRTT;
189 }
190 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000191}
192
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100193void RTCPReceiver::SetRtcpXrRrtrStatus(bool enable) {
194 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
195 xr_rrtr_status_ = enable;
196}
197
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000198bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000199 assert(rtt_ms);
200 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
201 if (xr_rr_rtt_ms_ == 0) {
202 return false;
203 }
204 *rtt_ms = xr_rr_rtt_ms_;
205 xr_rr_rtt_ms_ = 0;
206 return true;
207}
208
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000209// TODO(pbos): Make this fail when we haven't received NTP.
210bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
211 uint32_t* ReceivedNTPfrac,
212 uint32_t* RTCPArrivalTimeSecs,
213 uint32_t* RTCPArrivalTimeFrac,
214 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000215{
216 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
217 if(ReceivedNTPsecs)
218 {
219 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
220 }
221 if(ReceivedNTPfrac)
222 {
223 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
224 }
225 if(RTCPArrivalTimeFrac)
226 {
227 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
228 }
229 if(RTCPArrivalTimeSecs)
230 {
231 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
232 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000233 if (rtcp_timestamp) {
234 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
235 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000236 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000237}
238
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000239bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
240 RtcpReceiveTimeInfo* info) const {
241 assert(info);
242 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
243 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
244 return false;
245 }
246
247 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
248 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
249
250 // Get the delay since last received report (RFC 3611).
251 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
252 _lastReceivedXRNTPfrac);
253
254 uint32_t ntp_sec = 0;
255 uint32_t ntp_frac = 0;
256 _clock->CurrentNtp(ntp_sec, ntp_frac);
257 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
258
259 info->delaySinceLastRR = now - receive_time;
260 return true;
261}
262
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000263int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
264 assert(senderInfo);
265 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
266 if (_lastReceivedSRNTPsecs == 0) {
267 return -1;
268 }
269 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
270 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000271}
272
273// statistics
274// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000275int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000276 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000277 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000278 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000279 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
280 for (; it != _receivedReportBlockMap.end(); ++it) {
281 const ReportBlockInfoMap* info_map = &(it->second);
282 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
283 for (; it_info != info_map->end(); ++it_info) {
284 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
285 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000286 }
287 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000288}
289
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000290int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000291RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
292 RTCPUtility::RTCPParserV2* rtcpParser)
293{
294 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
295
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000296 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000297
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000298 if (packet_type_counter_.first_packet_time_ms == -1) {
299 packet_type_counter_.first_packet_time_ms = _lastReceived;
300 }
301
niklase@google.com470e71d2011-07-07 08:21:25 +0000302 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200303 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000304 // Each "case" is responsible for iterate the parser to the
305 // next top level packet.
306 switch (pktType)
307 {
Erik Språng242e22b2015-05-11 10:17:43 +0200308 case RTCPPacketTypes::kSr:
309 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000310 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
311 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200312 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200313 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000314 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200315 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000316 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
317 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200318 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000319 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
320 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200321 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000322 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
323 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200324 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000325 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
326 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200327 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 HandleBYE(*rtcpParser);
329 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200330 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 HandleNACK(*rtcpParser, rtcpPacketInformation);
332 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200333 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
335 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200336 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000337 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000338 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200339 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
341 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200342 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000343 HandlePLI(*rtcpParser, rtcpPacketInformation);
344 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200345 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 HandleSLI(*rtcpParser, rtcpPacketInformation);
347 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200348 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000349 HandleRPSI(*rtcpParser, rtcpPacketInformation);
350 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200351 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000352 HandleIJ(*rtcpParser, rtcpPacketInformation);
353 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200354 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000355 HandleFIR(*rtcpParser, rtcpPacketInformation);
356 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200357 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000358 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
359 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200360 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000361 // generic application messages
362 HandleAPP(*rtcpParser, rtcpPacketInformation);
363 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200364 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000365 // generic application messages
366 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
367 break;
Erik Språng6b8d3552015-09-24 15:06:57 +0200368 case RTCPPacketTypes::kTransportFeedback:
369 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
370 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000371 default:
372 rtcpParser->Iterate();
373 break;
374 }
375 pktType = rtcpParser->PacketType();
376 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000377
378 if (packet_type_counter_observer_ != NULL) {
379 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
380 main_ssrc_, packet_type_counter_);
381 }
382
Erik Språng6b8d3552015-09-24 15:06:57 +0200383 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
384
385 int64_t now = _clock->TimeInMilliseconds();
386 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
387 num_skipped_packets_ > 0) {
388 last_skipped_packets_warning_ = now;
389 LOG(LS_WARNING)
390 << num_skipped_packets_
391 << " RTCP blocks were skipped due to being malformed or of "
392 "unrecognized/unsupported type, during the past "
393 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
394 }
395
niklase@google.com470e71d2011-07-07 08:21:25 +0000396 return 0;
397}
398
niklase@google.com470e71d2011-07-07 08:21:25 +0000399void
400RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
401 RTCPPacketInformation& rtcpPacketInformation)
402{
403 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
404 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
405
Erik Språng242e22b2015-05-11 10:17:43 +0200406 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
407 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000408
409 // SR.SenderSSRC
410 // The synchronization source identifier for the originator of this SR packet
411
412 // rtcpPacket.RR.SenderSSRC
413 // The source of the packet sender, same as of SR? or is this a CE?
414
Erik Språng242e22b2015-05-11 10:17:43 +0200415 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
416 ? rtcpPacket.RR.SenderSSRC
417 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000418
419 rtcpPacketInformation.remoteSSRC = remoteSSRC;
420
421 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
422 if (!ptrReceiveInfo)
423 {
424 rtcpParser.Iterate();
425 return;
426 }
427
Erik Språng242e22b2015-05-11 10:17:43 +0200428 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000429 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
430 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000431
niklase@google.com470e71d2011-07-07 08:21:25 +0000432 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
433 {
434 // only signal that we have received a SR when we accept one
435 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
436
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000437 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
438 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
439 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
440
niklase@google.com470e71d2011-07-07 08:21:25 +0000441 // We will only store the send report from one source, but
442 // we will store all the receive block
443
444 // Save the NTP time of this report
445 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
446 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
447 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
448 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
449 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
450
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000451 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000452 }
453 else
454 {
455 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
456 }
457 } else
458 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000459 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
460 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000461
462 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
463 }
464 UpdateReceiveInformation(*ptrReceiveInfo);
465
466 rtcpPacketType = rtcpParser.Iterate();
467
Erik Språng242e22b2015-05-11 10:17:43 +0200468 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000469 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000470 rtcpPacketType = rtcpParser.Iterate();
471 }
472}
473
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000474void RTCPReceiver::HandleReportBlock(
475 const RTCPUtility::RTCPPacket& rtcpPacket,
476 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000477 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000478 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000479 // This will be called once per report block in the RTCP packet.
480 // We filter out all report blocks that are not for us.
481 // Each packet has max 31 RR blocks.
482 //
483 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000484
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000485 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
486 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000487
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000488 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000489 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
490 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000491 // This block is not for us ignore it.
492 return;
493 }
494
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000495 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000496 CreateOrGetReportBlockInformation(remoteSSRC,
497 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000498 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000499 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
500 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000501 return;
502 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000503
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000504 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000505 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
506 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
507 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
508 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
509 reportBlock->remoteReceiveBlock.cumulativeLost =
510 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000511 if (rb.ExtendedHighestSequenceNumber >
512 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
513 // We have successfully delivered new RTP packets to the remote side after
514 // the last RR was sent from the remote side.
515 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000516 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000517 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
518 rb.ExtendedHighestSequenceNumber;
519 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
520 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
521 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
522
523 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
524 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
525 }
526
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100527 int64_t rtt = 0;
Danil Chapovalova094fd12016-02-22 18:59:36 +0100528 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100529 // RFC3550, section 6.4.1, LSR field discription states:
530 // If no SR has been received yet, the field is set to zero.
531 // Receiver rtp_rtcp module is not expected to calculate rtt using
532 // Sender Reports even if it accidentally can.
533 if (!receiver_only_ && send_time != 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100534 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
535 // Local NTP time.
536 uint32_t receive_time = CompactNtp(NtpTime(*_clock));
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000537
Danil Chapovalova094fd12016-02-22 18:59:36 +0100538 // RTT in 1/(2^16) seconds.
539 uint32_t rtt_ntp = receive_time - delay - send_time;
540 // Convert to 1/1000 seconds (milliseconds).
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100541 rtt = CompactNtpRttToMs(rtt_ntp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100542 if (rtt > reportBlock->maxRTT) {
543 // Store max RTT.
544 reportBlock->maxRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000545 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000546 if (reportBlock->minRTT == 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100547 // First RTT.
548 reportBlock->minRTT = rtt;
549 } else if (rtt < reportBlock->minRTT) {
550 // Store min RTT.
551 reportBlock->minRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000552 }
Danil Chapovalova094fd12016-02-22 18:59:36 +0100553 // Store last RTT.
554 reportBlock->RTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000555
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000556 // store average RTT
557 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000558 float ac = static_cast<float>(reportBlock->numAverageCalcs);
559 float newAverage =
Danil Chapovalova094fd12016-02-22 18:59:36 +0100560 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000561 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000562 } else {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100563 // First RTT.
564 reportBlock->avgRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000565 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000566 reportBlock->numAverageCalcs++;
567 }
568
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000569 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
Danil Chapovalova094fd12016-02-22 18:59:36 +0100570 rtt);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000571
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000572 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000573}
574
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000575RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
576 uint32_t remote_ssrc,
577 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000578 RTCPReportBlockInformation* info =
579 GetReportBlockInformation(remote_ssrc, source_ssrc);
580 if (info == NULL) {
581 info = new RTCPReportBlockInformation;
582 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000583 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000584 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000585}
586
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000587RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
588 uint32_t remote_ssrc,
589 uint32_t source_ssrc) const {
590 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000591 if (it == _receivedReportBlockMap.end()) {
592 return NULL;
593 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000594 const ReportBlockInfoMap* info_map = &(it->second);
595 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
596 if (it_info == info_map->end()) {
597 return NULL;
598 }
599 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000600}
601
602RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000603RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000604 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000605
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000606 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000607 _receivedCnameMap.find(remoteSSRC);
608
609 if (it != _receivedCnameMap.end()) {
610 return it->second;
611 }
612 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000613 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000614 _receivedCnameMap[remoteSSRC] = cnameInfo;
615 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000616}
617
618RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000619RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000620 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000621
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000622 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000623 _receivedCnameMap.find(remoteSSRC);
624
625 if (it == _receivedCnameMap.end()) {
626 return NULL;
627 }
628 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000629}
630
631RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000632RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000633 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000634
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000635 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000636 _receivedInfoMap.find(remoteSSRC);
637
638 if (it != _receivedInfoMap.end()) {
639 return it->second;
640 }
641 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
642 _receivedInfoMap[remoteSSRC] = receiveInfo;
643 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000644}
645
646RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000647RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000648 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000649
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000650 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000651 _receivedInfoMap.find(remoteSSRC);
652 if (it == _receivedInfoMap.end()) {
653 return NULL;
654 }
655 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000656}
657
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000658void RTCPReceiver::UpdateReceiveInformation(
659 RTCPReceiveInformation& receiveInformation) {
660 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000661 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000662}
663
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000664bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
665 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
666 if (_lastReceivedRrMs == 0)
667 return false;
668
669 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000670 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000671 // Reset the timer to only trigger one log.
672 _lastReceivedRrMs = 0;
673 return true;
674 }
675 return false;
676}
677
678bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
679 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
680 if (_lastIncreasedSequenceNumberMs == 0)
681 return false;
682
683 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000684 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000685 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000686 // Reset the timer to only trigger one log.
687 _lastIncreasedSequenceNumberMs = 0;
688 return true;
689 }
690 return false;
691}
692
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000693bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
694 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000695
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000696 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000697 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000698
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000699 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000700 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000701
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000702 while (receiveInfoIt != _receivedInfoMap.end()) {
703 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
704 if (receiveInfo == NULL) {
705 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000706 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000707 // time since last received rtcp packet
708 // when we dont have a lastTimeReceived and the object is marked
709 // readyForDelete it's removed from the map
710 if (receiveInfo->lastTimeReceived) {
711 /// use audio define since we don't know what interval the remote peer is
712 // using
713 if ((timeNow - receiveInfo->lastTimeReceived) >
714 5 * RTCP_INTERVAL_AUDIO_MS) {
715 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000716 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000717 // prevent that we call this over and over again
718 receiveInfo->lastTimeReceived = 0;
719 // send new TMMBN to all channels using the default codec
720 updateBoundingSet = true;
721 }
722 receiveInfoIt++;
723 } else if (receiveInfo->readyForDelete) {
724 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000725 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000726 receiveInfoItemToBeErased = receiveInfoIt;
727 receiveInfoIt++;
728 delete receiveInfoItemToBeErased->second;
729 _receivedInfoMap.erase(receiveInfoItemToBeErased);
730 } else {
731 receiveInfoIt++;
732 }
733 }
734 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000735}
736
danilchap6db6cdc2015-12-15 02:54:47 -0800737int32_t RTCPReceiver::BoundingSet(bool* tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000738 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000739
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000740 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000741 _receivedInfoMap.find(_remoteSSRC);
742
743 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000744 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000745 }
746 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
747 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000748 return -1;
749 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000750 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000751 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000752 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000753 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000754 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000755 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000756 // owner of bounding set
danilchap6db6cdc2015-12-15 02:54:47 -0800757 *tmmbrOwner = true;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000758 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000759 boundingSetRec->SetEntry(i,
760 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
761 receiveInfo->TmmbnBoundingSet.PacketOH(i),
762 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000763 }
764 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000765 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000766}
767
Erik Språnga38233a2015-07-24 09:58:18 +0200768void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
769 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000770 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200771 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000772 HandleSDESChunk(rtcpParser);
773 pktType = rtcpParser.Iterate();
774 }
Erik Språnga38233a2015-07-24 09:58:18 +0200775 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000776}
777
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000778void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
779 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
780 RTCPCnameInformation* cnameInfo =
781 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
782 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000783
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000784 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
785 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000786 {
787 CriticalSectionScoped lock(_criticalSectionFeedbacks);
788 if (stats_callback_ != NULL) {
789 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
790 rtcpPacket.CName.SenderSSRC);
791 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000792 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000793}
794
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000795void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
796 RTCPPacketInformation& rtcpPacketInformation) {
797 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200798 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000799 // Not to us.
800 rtcpParser.Iterate();
801 return;
802 }
803 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000804
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000805 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200806 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000807 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
808 pktType = rtcpParser.Iterate();
809 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000810
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000811 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
812 ++packet_type_counter_.nack_packets;
813 packet_type_counter_.nack_requests = nack_stats_.requests();
814 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
815 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000816}
817
niklase@google.com470e71d2011-07-07 08:21:25 +0000818void
819RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000820 RTCPPacketInformation& rtcpPacketInformation) {
821 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
822 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000823
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000824 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
825 if (bitMask) {
826 for (int i=1; i <= 16; ++i) {
827 if (bitMask & 0x01) {
828 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
829 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
830 }
831 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000832 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000833 }
834 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000835}
836
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000837void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
838 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000839
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000840 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000841 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
842 for (; it != _receivedReportBlockMap.end(); ++it) {
843 ReportBlockInfoMap* info_map = &(it->second);
844 ReportBlockInfoMap::iterator it_info = info_map->find(
845 rtcpPacket.BYE.SenderSSRC);
846 if (it_info != info_map->end()) {
847 delete it_info->second;
848 info_map->erase(it_info);
849 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000850 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000851
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000852 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000853 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000854 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000855
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000856 if (receiveInfoIt != _receivedInfoMap.end()) {
857 receiveInfoIt->second->readyForDelete = true;
858 }
859
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000860 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000861 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
862
863 if (cnameInfoIt != _receivedCnameMap.end()) {
864 delete cnameInfoIt->second;
865 _receivedCnameMap.erase(cnameInfoIt);
866 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000867 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000868 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000869}
870
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000871void RTCPReceiver::HandleXrHeader(
872 RTCPUtility::RTCPParserV2& parser,
873 RTCPPacketInformation& rtcpPacketInformation) {
874 const RTCPUtility::RTCPPacket& packet = parser.Packet();
875
876 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
877
878 parser.Iterate();
879}
880
881void RTCPReceiver::HandleXrReceiveReferenceTime(
882 RTCPUtility::RTCPParserV2& parser,
883 RTCPPacketInformation& rtcpPacketInformation) {
884 const RTCPUtility::RTCPPacket& packet = parser.Packet();
885
886 _remoteXRReceiveTimeInfo.sourceSSRC =
887 rtcpPacketInformation.xr_originator_ssrc;
888
889 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
890 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
891 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
892
893 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
894
895 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
896
897 parser.Iterate();
898}
899
900void RTCPReceiver::HandleXrDlrrReportBlock(
901 RTCPUtility::RTCPParserV2& parser,
902 RTCPPacketInformation& rtcpPacketInformation) {
903 const RTCPUtility::RTCPPacket& packet = parser.Packet();
904 // Iterate through sub-block(s), if any.
905 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
906
Erik Språng242e22b2015-05-11 10:17:43 +0200907 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000908 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
909 packet_type = parser.Iterate();
910 }
911}
912
913void RTCPReceiver::HandleXrDlrrReportBlockItem(
914 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000915 RTCPPacketInformation& rtcpPacketInformation)
916 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000917 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
918 registered_ssrcs_.end()) {
919 // Not to us.
920 return;
921 }
922
923 rtcpPacketInformation.xr_dlrr_item = true;
924
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100925 // Caller should explicitly enable rtt calculation using extended reports.
926 if (!xr_rrtr_status_)
927 return;
928
Danil Chapovalova094fd12016-02-22 18:59:36 +0100929 // The send_time and delay_rr fields are in units of 1/2^16 sec.
930 uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100931 // RFC3611, section 4.5, LRR field discription states:
Danil Chapovalova094fd12016-02-22 18:59:36 +0100932 // If no such block has been received, the field is set to zero.
933 if (send_time == 0)
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000934 return;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000935
Danil Chapovalova094fd12016-02-22 18:59:36 +0100936 uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
937 uint32_t now = CompactNtp(NtpTime(*_clock));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000938
Danil Chapovalova094fd12016-02-22 18:59:36 +0100939 uint32_t rtt_ntp = now - delay_rr - send_time;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100940 xr_rr_rtt_ms_ = CompactNtpRttToMs(rtt_ntp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000941
942 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
943}
944
niklase@google.com470e71d2011-07-07 08:21:25 +0000945void
946RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
947 RTCPPacketInformation& rtcpPacketInformation)
948{
949 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
950
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000951 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000952 {
953 // Store VoIP metrics block if it's about me
954 // from OriginatorSSRC do we filter it?
955 // rtcpPacket.XR.OriginatorSSRC;
956
957 RTCPVoIPMetric receivedVoIPMetrics;
958 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
959 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
960 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
961 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
962 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
963 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
964 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
965 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
966 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
967 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
968 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
969 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
970 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
971 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
972 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
973 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
974 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
975 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
976 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
977 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
978
979 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
980
981 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
982 }
983 rtcpParser.Iterate();
984}
985
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000986void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
987 RTCPPacketInformation& rtcpPacketInformation) {
988 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000989 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000990 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000991
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000992 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000993 // Received a signal that we need to send a new key frame.
994 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
995 }
996 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000997}
998
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000999void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
1000 RTCPPacketInformation& rtcpPacketInformation) {
1001 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001002
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001003 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
1004 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
1005 if (ptrReceiveInfo == NULL) {
1006 // This remote SSRC must be saved before.
1007 rtcpParser.Iterate();
1008 return;
1009 }
1010 if (rtcpPacket.TMMBR.MediaSSRC) {
1011 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1012 // in relay mode this is a valid number
1013 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1014 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001015
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001016 // Use packet length to calc max number of TMMBR blocks
1017 // each TMMBR block is 8 bytes
1018 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001019
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001020 // sanity, we can't have more than what's in one packet
1021 if (maxNumOfTMMBRBlocks > 200) {
1022 assert(false);
1023 rtcpParser.Iterate();
1024 return;
1025 }
1026 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001027
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001028 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001029 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001030 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1031 pktType = rtcpParser.Iterate();
1032 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001033}
1034
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001035void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1036 const RTCPUtility::RTCPPacket& rtcpPacket,
1037 RTCPPacketInformation& rtcpPacketInformation,
1038 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001039 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1040 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1041 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1042 _clock->TimeInMilliseconds());
1043 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1044 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001045}
1046
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001047void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1048 RTCPPacketInformation& rtcpPacketInformation) {
1049 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1050 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1051 rtcpPacket.TMMBN.SenderSSRC);
1052 if (ptrReceiveInfo == NULL) {
1053 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001054 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001055 return;
1056 }
1057 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1058 // Use packet length to calc max number of TMMBN blocks
1059 // each TMMBN block is 8 bytes
1060 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1061
1062 // sanity, we cant have more than what's in one packet
1063 if (maxNumOfTMMBNBlocks > 200) {
1064 assert(false);
1065 rtcpParser.Iterate();
1066 return;
1067 }
1068
1069 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1070
1071 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001072 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001073 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1074 pktType = rtcpParser.Iterate();
1075 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001076}
1077
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001078void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1079 RTCPPacketInformation& rtcpPacketInformation) {
1080 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1081 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001082}
1083
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001084void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1085 const RTCPUtility::RTCPPacket& rtcpPacket) {
1086 receiveInfo.TmmbnBoundingSet.AddEntry(
1087 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1088 rtcpPacket.TMMBNItem.MeasuredOverhead,
1089 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001090}
1091
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001092void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1093 RTCPPacketInformation& rtcpPacketInformation) {
1094 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1095 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001096 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001097 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1098 pktType = rtcpParser.Iterate();
1099 }
1100}
1101
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001102void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1103 RTCPPacketInformation& rtcpPacketInformation) {
1104 // in theory there could be multiple slices lost
1105 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1106 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001107}
1108
1109void
1110RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1111 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1112{
1113 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001114 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001115 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001116 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1117 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1118 {
1119 // to us unknown
1120 // continue
1121 rtcpParser.Iterate();
1122 return;
1123 }
1124 rtcpPacketInformation.rpsiPictureId = 0;
1125
1126 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001127 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1128 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001129 {
1130 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1131 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1132 }
1133 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1134 }
1135}
1136
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001137void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1138 RTCPPacketInformation& rtcpPacketInformation) {
1139 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001140 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001141 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001142 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001143 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1144 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001145 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001146 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001147}
1148
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001149void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1150 RTCPPacketInformation& rtcpPacketInformation) {
1151 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001152
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001153 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001154 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001155 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1156 pktType = rtcpParser.Iterate();
1157 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001158}
1159
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001160void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1161 RTCPPacketInformation& rtcpPacketInformation) {
1162 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1163 rtcpPacketInformation.interArrivalJitter =
1164 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001165}
1166
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001167void RTCPReceiver::HandleREMBItem(
1168 RTCPUtility::RTCPParserV2& rtcpParser,
1169 RTCPPacketInformation& rtcpPacketInformation) {
1170 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1171 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1172 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1173 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001174}
1175
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001176void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1177 RTCPPacketInformation& rtcpPacketInformation) {
1178 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1179 RTCPReceiveInformation* ptrReceiveInfo =
1180 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001181
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001182 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001183 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001184 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1185 pktType = rtcpParser.Iterate();
1186 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001187}
1188
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001189void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1190 const RTCPUtility::RTCPPacket& rtcpPacket,
1191 RTCPPacketInformation& rtcpPacketInformation) {
1192 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001193 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001194 return;
1195 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001196
1197 ++packet_type_counter_.fir_packets;
1198
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001199 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1200 // we don't know who this originate from
1201 if (receiveInfo) {
1202 // check if we have reported this FIRSequenceNumber before
1203 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1204 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001205 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001206 // sanity; don't go crazy with the callbacks
1207 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1208 receiveInfo->lastFIRRequest = now;
1209 receiveInfo->lastFIRSequenceNumber =
1210 rtcpPacket.FIRItem.CommandSequenceNumber;
1211 // received signal that we need to send a new key frame
1212 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1213 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001214 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001215 } else {
1216 // received signal that we need to send a new key frame
1217 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1218 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001219}
1220
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001221void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1222 RTCPPacketInformation& rtcpPacketInformation) {
1223 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001224
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001225 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1226 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1227 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
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
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001232void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1233 RTCPPacketInformation& rtcpPacketInformation) {
1234 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001235
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001236 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001237
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001238 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001239}
1240
Erik Språng6b8d3552015-09-24 15:06:57 +02001241void RTCPReceiver::HandleTransportFeedback(
1242 RTCPUtility::RTCPParserV2* rtcp_parser,
1243 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1244 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1245 RTC_DCHECK(packet != nullptr);
1246 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1247 rtcp_packet_information->transport_feedback_.reset(
1248 static_cast<rtcp::TransportFeedback*>(packet));
1249
1250 rtcp_parser->Iterate();
1251}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001252int32_t RTCPReceiver::UpdateTMMBR() {
1253 int32_t numBoundingSet = 0;
1254 uint32_t bitrate = 0;
1255 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001256
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001257 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001258 if (size > 0) {
1259 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1260 // Get candidate set from receiver.
1261 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1262 } else {
1263 // Candidate set empty.
1264 VerifyAndAllocateCandidateSet(0); // resets candidate set
1265 }
1266 // Find bounding set
1267 TMMBRSet* boundingSet = NULL;
1268 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1269 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001270 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001271 return -1;
1272 }
1273 // Set bounding set
1274 // Inform remote clients about the new bandwidth
1275 // inform the remote client
1276 _rtpRtcp.SetTMMBN(boundingSet);
1277
1278 // might trigger a TMMBN
1279 if (numBoundingSet == 0) {
1280 // owner of max bitrate request has timed out
1281 // empty bounding set has been sent
1282 return 0;
1283 }
1284 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001285 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001286 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001287 if (_cbRtcpBandwidthObserver) {
1288 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001289 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001290 }
1291 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001292}
1293
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001294void RTCPReceiver::RegisterRtcpStatisticsCallback(
1295 RtcpStatisticsCallback* callback) {
1296 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001297 stats_callback_ = callback;
1298}
1299
1300RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1301 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1302 return stats_callback_;
1303}
1304
niklase@google.com470e71d2011-07-07 08:21:25 +00001305// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001306void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001307 RTCPPacketInformation& rtcpPacketInformation) {
1308 // Process TMMBR and REMB first to avoid multiple callbacks
1309 // to OnNetworkChanged.
1310 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001311 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1312 UpdateTMMBR();
1313 }
sprang7dc39f32015-10-13 09:17:48 -07001314 uint32_t local_ssrc;
1315 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001316 {
1317 // We don't want to hold this critsect when triggering the callbacks below.
1318 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001319 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001320 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001321 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001322 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001323 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001324 _rtpRtcp.OnRequestSendReport();
1325 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001326 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001327 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001328 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001329 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001330 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001331 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001332 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001333 }
1334 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001335 // We need feedback that we have received a report block(s) so that we
1336 // can generate a new packet in a conference relay scenario, one received
1337 // report can generate several RTCP packets, based on number relayed/mixed
1338 // a send report block should go out to all receivers.
1339 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001340 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001341 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1342 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1343 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001344 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001345 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001346 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001347 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001348 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001349 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001350 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001351 }
1352 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1353 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001354 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001355 }
1356 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1357 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001358 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001359 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001360 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001361 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001362 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001363 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001364 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001365 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001366 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1367 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1368 }
Erik Språng242e22b2015-05-11 10:17:43 +02001369 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1370 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001371 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001372 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001373 rtcpPacketInformation.report_blocks,
1374 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001375 now);
1376 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001377 }
Erik Språng6b8d3552015-09-24 15:06:57 +02001378 if (_cbTransportFeedbackObserver &&
1379 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1380 uint32_t media_source_ssrc =
1381 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001382 if (media_source_ssrc == local_ssrc ||
1383 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001384 _cbTransportFeedbackObserver->OnTransportFeedback(
1385 *rtcpPacketInformation.transport_feedback_.get());
1386 }
1387 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001388 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001389
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001390 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001391 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1392 if (stats_callback_) {
1393 for (ReportBlockList::const_iterator it =
1394 rtcpPacketInformation.report_blocks.begin();
1395 it != rtcpPacketInformation.report_blocks.end();
1396 ++it) {
1397 RtcpStatistics stats;
1398 stats.cumulative_lost = it->cumulativeLost;
1399 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1400 stats.fraction_lost = it->fractionLost;
1401 stats.jitter = it->jitter;
1402
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001403 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001404 }
1405 }
1406 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001407}
1408
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001409int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001410 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001411 assert(cName);
1412
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001413 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1414 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001415 if (cnameInfo == NULL) {
1416 return -1;
1417 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001418 cName[RTCP_CNAME_SIZE - 1] = 0;
1419 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1420 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001421}
1422
1423// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001424int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1425 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001426 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001427 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001428
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001429 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001430 receiveInfoIt = _receivedInfoMap.begin();
1431 if (receiveInfoIt == _receivedInfoMap.end()) {
1432 return -1;
1433 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001434 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001435 if (candidateSet) {
1436 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1437 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1438 if (receiveInfo == NULL) {
1439 return 0;
1440 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001441 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001442 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001443 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001444 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001445 num++;
1446 }
1447 }
1448 receiveInfoIt++;
1449 }
1450 } else {
1451 while (receiveInfoIt != _receivedInfoMap.end()) {
1452 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1453 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001454 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001455 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001456 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001457 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001458 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001459 }
1460 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001461}
1462
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001463} // namespace webrtc