blob: e1721394f8eff96b56a43951967d6d6c901c1612 [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"
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),
67 xr_rr_rtt_ms_(0),
68 _receivedInfoMap(),
69 _packetTimeOutMS(0),
70 _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
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000193bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000194 assert(rtt_ms);
195 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
196 if (xr_rr_rtt_ms_ == 0) {
197 return false;
198 }
199 *rtt_ms = xr_rr_rtt_ms_;
200 xr_rr_rtt_ms_ = 0;
201 return true;
202}
203
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000204// TODO(pbos): Make this fail when we haven't received NTP.
205bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
206 uint32_t* ReceivedNTPfrac,
207 uint32_t* RTCPArrivalTimeSecs,
208 uint32_t* RTCPArrivalTimeFrac,
209 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000210{
211 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
212 if(ReceivedNTPsecs)
213 {
214 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
215 }
216 if(ReceivedNTPfrac)
217 {
218 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
219 }
220 if(RTCPArrivalTimeFrac)
221 {
222 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
223 }
224 if(RTCPArrivalTimeSecs)
225 {
226 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
227 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000228 if (rtcp_timestamp) {
229 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
230 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000231 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000232}
233
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000234bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
235 RtcpReceiveTimeInfo* info) const {
236 assert(info);
237 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
238 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
239 return false;
240 }
241
242 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
243 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
244
245 // Get the delay since last received report (RFC 3611).
246 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
247 _lastReceivedXRNTPfrac);
248
249 uint32_t ntp_sec = 0;
250 uint32_t ntp_frac = 0;
251 _clock->CurrentNtp(ntp_sec, ntp_frac);
252 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
253
254 info->delaySinceLastRR = now - receive_time;
255 return true;
256}
257
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000258int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
259 assert(senderInfo);
260 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
261 if (_lastReceivedSRNTPsecs == 0) {
262 return -1;
263 }
264 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
265 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000266}
267
268// statistics
269// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000270int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000271 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000272 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000273 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000274 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
275 for (; it != _receivedReportBlockMap.end(); ++it) {
276 const ReportBlockInfoMap* info_map = &(it->second);
277 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
278 for (; it_info != info_map->end(); ++it_info) {
279 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
280 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000281 }
282 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000283}
284
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000285int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000286RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
287 RTCPUtility::RTCPParserV2* rtcpParser)
288{
289 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
290
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000291 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000292
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000293 if (packet_type_counter_.first_packet_time_ms == -1) {
294 packet_type_counter_.first_packet_time_ms = _lastReceived;
295 }
296
niklase@google.com470e71d2011-07-07 08:21:25 +0000297 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200298 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000299 // Each "case" is responsible for iterate the parser to the
300 // next top level packet.
301 switch (pktType)
302 {
Erik Språng242e22b2015-05-11 10:17:43 +0200303 case RTCPPacketTypes::kSr:
304 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000305 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
306 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200307 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200308 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000309 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200310 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000311 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
312 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200313 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000314 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
315 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200316 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000317 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
318 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200319 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000320 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
321 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200322 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000323 HandleBYE(*rtcpParser);
324 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200325 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000326 HandleNACK(*rtcpParser, rtcpPacketInformation);
327 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200328 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000329 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
330 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200331 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000332 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200334 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000335 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
336 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200337 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000338 HandlePLI(*rtcpParser, rtcpPacketInformation);
339 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200340 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000341 HandleSLI(*rtcpParser, rtcpPacketInformation);
342 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200343 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000344 HandleRPSI(*rtcpParser, rtcpPacketInformation);
345 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200346 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000347 HandleIJ(*rtcpParser, rtcpPacketInformation);
348 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200349 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000350 HandleFIR(*rtcpParser, rtcpPacketInformation);
351 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200352 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000353 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
354 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200355 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000356 // generic application messages
357 HandleAPP(*rtcpParser, rtcpPacketInformation);
358 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200359 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000360 // generic application messages
361 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
362 break;
Erik Språng6b8d3552015-09-24 15:06:57 +0200363 case RTCPPacketTypes::kTransportFeedback:
364 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
365 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000366 default:
367 rtcpParser->Iterate();
368 break;
369 }
370 pktType = rtcpParser->PacketType();
371 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000372
373 if (packet_type_counter_observer_ != NULL) {
374 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
375 main_ssrc_, packet_type_counter_);
376 }
377
Erik Språng6b8d3552015-09-24 15:06:57 +0200378 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
379
380 int64_t now = _clock->TimeInMilliseconds();
381 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
382 num_skipped_packets_ > 0) {
383 last_skipped_packets_warning_ = now;
384 LOG(LS_WARNING)
385 << num_skipped_packets_
386 << " RTCP blocks were skipped due to being malformed or of "
387 "unrecognized/unsupported type, during the past "
388 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
389 }
390
niklase@google.com470e71d2011-07-07 08:21:25 +0000391 return 0;
392}
393
niklase@google.com470e71d2011-07-07 08:21:25 +0000394void
395RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
396 RTCPPacketInformation& rtcpPacketInformation)
397{
398 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
399 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
400
Erik Språng242e22b2015-05-11 10:17:43 +0200401 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
402 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000403
404 // SR.SenderSSRC
405 // The synchronization source identifier for the originator of this SR packet
406
407 // rtcpPacket.RR.SenderSSRC
408 // The source of the packet sender, same as of SR? or is this a CE?
409
Erik Språng242e22b2015-05-11 10:17:43 +0200410 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
411 ? rtcpPacket.RR.SenderSSRC
412 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000413
414 rtcpPacketInformation.remoteSSRC = remoteSSRC;
415
416 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
417 if (!ptrReceiveInfo)
418 {
419 rtcpParser.Iterate();
420 return;
421 }
422
Erik Språng242e22b2015-05-11 10:17:43 +0200423 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000424 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
425 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000426
niklase@google.com470e71d2011-07-07 08:21:25 +0000427 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
428 {
429 // only signal that we have received a SR when we accept one
430 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
431
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000432 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
433 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
434 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
435
niklase@google.com470e71d2011-07-07 08:21:25 +0000436 // We will only store the send report from one source, but
437 // we will store all the receive block
438
439 // Save the NTP time of this report
440 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
441 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
442 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
443 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
444 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
445
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000446 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000447 }
448 else
449 {
450 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
451 }
452 } else
453 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000454 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
455 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000456
457 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
458 }
459 UpdateReceiveInformation(*ptrReceiveInfo);
460
461 rtcpPacketType = rtcpParser.Iterate();
462
Erik Språng242e22b2015-05-11 10:17:43 +0200463 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000464 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000465 rtcpPacketType = rtcpParser.Iterate();
466 }
467}
468
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000469void RTCPReceiver::HandleReportBlock(
470 const RTCPUtility::RTCPPacket& rtcpPacket,
471 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000472 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000473 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000474 // This will be called once per report block in the RTCP packet.
475 // We filter out all report blocks that are not for us.
476 // Each packet has max 31 RR blocks.
477 //
478 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000479
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000480 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
481 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000482
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000483 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000484 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
485 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000486 // This block is not for us ignore it.
487 return;
488 }
489
490 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
491 // _criticalSectionRTCPReceiver.
492 _criticalSectionRTCPReceiver->Leave();
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000493 int64_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000494 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
495 _criticalSectionRTCPReceiver->Enter();
496
497 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000498 CreateOrGetReportBlockInformation(remoteSSRC,
499 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000500 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000501 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
502 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000503 return;
504 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000505
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000506 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000507 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
508 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
509 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
510 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
511 reportBlock->remoteReceiveBlock.cumulativeLost =
512 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000513 if (rb.ExtendedHighestSequenceNumber >
514 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
515 // We have successfully delivered new RTP packets to the remote side after
516 // the last RR was sent from the remote side.
517 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000518 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000519 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
520 rb.ExtendedHighestSequenceNumber;
521 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
522 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
523 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
524
525 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
526 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
527 }
528
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000529 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000530 rtcpPacket.ReportBlockItem.DelayLastSR;
531
532 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000533 uint32_t lastReceivedRRNTPsecs = 0;
534 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000535
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000536 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000537
538 // time when we received this in MS
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000539 int64_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
540 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000541
542 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000543 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000544 d /= 65536;
545 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
546
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000547 int64_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000548
549 if (sendTimeMS > 0) {
550 RTT = receiveTimeMS - d - sendTimeMS;
551 if (RTT <= 0) {
552 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000553 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000554 if (RTT > reportBlock->maxRTT) {
555 // store max RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000556 reportBlock->maxRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000557 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000558 if (reportBlock->minRTT == 0) {
559 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000560 reportBlock->minRTT = RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000561 } else if (RTT < reportBlock->minRTT) {
562 // Store min RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000563 reportBlock->minRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000564 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000565 // store last RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000566 reportBlock->RTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000567
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000568 // store average RTT
569 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000570 float ac = static_cast<float>(reportBlock->numAverageCalcs);
571 float newAverage =
572 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * RTT);
573 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000574 } else {
575 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000576 reportBlock->avgRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000577 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000578 reportBlock->numAverageCalcs++;
579 }
580
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000581 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
582 RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000583
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000584 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000585}
586
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000587RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
588 uint32_t remote_ssrc,
589 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000590 RTCPReportBlockInformation* info =
591 GetReportBlockInformation(remote_ssrc, source_ssrc);
592 if (info == NULL) {
593 info = new RTCPReportBlockInformation;
594 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000595 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000596 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000597}
598
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000599RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
600 uint32_t remote_ssrc,
601 uint32_t source_ssrc) const {
602 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000603 if (it == _receivedReportBlockMap.end()) {
604 return NULL;
605 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000606 const ReportBlockInfoMap* info_map = &(it->second);
607 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
608 if (it_info == info_map->end()) {
609 return NULL;
610 }
611 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000612}
613
614RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000615RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000616 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000617
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000618 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000619 _receivedCnameMap.find(remoteSSRC);
620
621 if (it != _receivedCnameMap.end()) {
622 return it->second;
623 }
624 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000625 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000626 _receivedCnameMap[remoteSSRC] = cnameInfo;
627 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000628}
629
630RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000631RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000632 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000633
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000634 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000635 _receivedCnameMap.find(remoteSSRC);
636
637 if (it == _receivedCnameMap.end()) {
638 return NULL;
639 }
640 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000641}
642
643RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000644RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000645 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000646
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000647 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000648 _receivedInfoMap.find(remoteSSRC);
649
650 if (it != _receivedInfoMap.end()) {
651 return it->second;
652 }
653 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
654 _receivedInfoMap[remoteSSRC] = receiveInfo;
655 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000656}
657
658RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000659RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000660 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000661
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000662 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000663 _receivedInfoMap.find(remoteSSRC);
664 if (it == _receivedInfoMap.end()) {
665 return NULL;
666 }
667 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000668}
669
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000670void RTCPReceiver::UpdateReceiveInformation(
671 RTCPReceiveInformation& receiveInformation) {
672 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000673 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000674}
675
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000676bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
677 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
678 if (_lastReceivedRrMs == 0)
679 return false;
680
681 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000682 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000683 // Reset the timer to only trigger one log.
684 _lastReceivedRrMs = 0;
685 return true;
686 }
687 return false;
688}
689
690bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
691 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
692 if (_lastIncreasedSequenceNumberMs == 0)
693 return false;
694
695 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000696 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000697 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000698 // Reset the timer to only trigger one log.
699 _lastIncreasedSequenceNumberMs = 0;
700 return true;
701 }
702 return false;
703}
704
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000705bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
706 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000707
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000708 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000709 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000710
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000711 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000712 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000713
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000714 while (receiveInfoIt != _receivedInfoMap.end()) {
715 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
716 if (receiveInfo == NULL) {
717 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000718 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000719 // time since last received rtcp packet
720 // when we dont have a lastTimeReceived and the object is marked
721 // readyForDelete it's removed from the map
722 if (receiveInfo->lastTimeReceived) {
723 /// use audio define since we don't know what interval the remote peer is
724 // using
725 if ((timeNow - receiveInfo->lastTimeReceived) >
726 5 * RTCP_INTERVAL_AUDIO_MS) {
727 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000728 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000729 // prevent that we call this over and over again
730 receiveInfo->lastTimeReceived = 0;
731 // send new TMMBN to all channels using the default codec
732 updateBoundingSet = true;
733 }
734 receiveInfoIt++;
735 } else if (receiveInfo->readyForDelete) {
736 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000737 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000738 receiveInfoItemToBeErased = receiveInfoIt;
739 receiveInfoIt++;
740 delete receiveInfoItemToBeErased->second;
741 _receivedInfoMap.erase(receiveInfoItemToBeErased);
742 } else {
743 receiveInfoIt++;
744 }
745 }
746 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000747}
748
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000749int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000750 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000751
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000752 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000753 _receivedInfoMap.find(_remoteSSRC);
754
755 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000756 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000757 }
758 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
759 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000760 return -1;
761 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000762 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000763 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000764 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000765 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000766 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000767 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000768 // owner of bounding set
769 tmmbrOwner = true;
770 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000771 boundingSetRec->SetEntry(i,
772 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
773 receiveInfo->TmmbnBoundingSet.PacketOH(i),
774 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000775 }
776 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000777 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000778}
779
Erik Språnga38233a2015-07-24 09:58:18 +0200780void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
781 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000782 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200783 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000784 HandleSDESChunk(rtcpParser);
785 pktType = rtcpParser.Iterate();
786 }
Erik Språnga38233a2015-07-24 09:58:18 +0200787 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000788}
789
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000790void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
791 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
792 RTCPCnameInformation* cnameInfo =
793 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
794 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000795
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000796 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
797 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000798 {
799 CriticalSectionScoped lock(_criticalSectionFeedbacks);
800 if (stats_callback_ != NULL) {
801 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
802 rtcpPacket.CName.SenderSSRC);
803 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000804 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000805}
806
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000807void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
808 RTCPPacketInformation& rtcpPacketInformation) {
809 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200810 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000811 // Not to us.
812 rtcpParser.Iterate();
813 return;
814 }
815 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000816
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000817 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200818 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000819 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
820 pktType = rtcpParser.Iterate();
821 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000822
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000823 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
824 ++packet_type_counter_.nack_packets;
825 packet_type_counter_.nack_requests = nack_stats_.requests();
826 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
827 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000828}
829
niklase@google.com470e71d2011-07-07 08:21:25 +0000830void
831RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000832 RTCPPacketInformation& rtcpPacketInformation) {
833 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
834 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000835
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000836 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
837 if (bitMask) {
838 for (int i=1; i <= 16; ++i) {
839 if (bitMask & 0x01) {
840 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
841 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
842 }
843 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000844 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000845 }
846 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000847}
848
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000849void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
850 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000851
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000852 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000853 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
854 for (; it != _receivedReportBlockMap.end(); ++it) {
855 ReportBlockInfoMap* info_map = &(it->second);
856 ReportBlockInfoMap::iterator it_info = info_map->find(
857 rtcpPacket.BYE.SenderSSRC);
858 if (it_info != info_map->end()) {
859 delete it_info->second;
860 info_map->erase(it_info);
861 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000862 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000863
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000864 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000865 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000866 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000867
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000868 if (receiveInfoIt != _receivedInfoMap.end()) {
869 receiveInfoIt->second->readyForDelete = true;
870 }
871
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000872 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000873 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
874
875 if (cnameInfoIt != _receivedCnameMap.end()) {
876 delete cnameInfoIt->second;
877 _receivedCnameMap.erase(cnameInfoIt);
878 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000879 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000880 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000881}
882
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000883void RTCPReceiver::HandleXrHeader(
884 RTCPUtility::RTCPParserV2& parser,
885 RTCPPacketInformation& rtcpPacketInformation) {
886 const RTCPUtility::RTCPPacket& packet = parser.Packet();
887
888 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
889
890 parser.Iterate();
891}
892
893void RTCPReceiver::HandleXrReceiveReferenceTime(
894 RTCPUtility::RTCPParserV2& parser,
895 RTCPPacketInformation& rtcpPacketInformation) {
896 const RTCPUtility::RTCPPacket& packet = parser.Packet();
897
898 _remoteXRReceiveTimeInfo.sourceSSRC =
899 rtcpPacketInformation.xr_originator_ssrc;
900
901 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
902 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
903 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
904
905 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
906
907 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
908
909 parser.Iterate();
910}
911
912void RTCPReceiver::HandleXrDlrrReportBlock(
913 RTCPUtility::RTCPParserV2& parser,
914 RTCPPacketInformation& rtcpPacketInformation) {
915 const RTCPUtility::RTCPPacket& packet = parser.Packet();
916 // Iterate through sub-block(s), if any.
917 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
918
Erik Språng242e22b2015-05-11 10:17:43 +0200919 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000920 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
921 packet_type = parser.Iterate();
922 }
923}
924
925void RTCPReceiver::HandleXrDlrrReportBlockItem(
926 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000927 RTCPPacketInformation& rtcpPacketInformation)
928 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000929 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
930 registered_ssrcs_.end()) {
931 // Not to us.
932 return;
933 }
934
935 rtcpPacketInformation.xr_dlrr_item = true;
936
937 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
938 // _criticalSectionRTCPReceiver.
939 _criticalSectionRTCPReceiver->Leave();
940
941 int64_t send_time_ms;
942 bool found = _rtpRtcp.SendTimeOfXrRrReport(
943 packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
944
945 _criticalSectionRTCPReceiver->Enter();
946
947 if (!found) {
948 return;
949 }
950
951 // The DelayLastRR field is in units of 1/65536 sec.
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000952 uint32_t delay_rr_ms =
953 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
954 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000955
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000956 int64_t rtt = _clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000957
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000958 xr_rr_rtt_ms_ = std::max<int64_t>(rtt, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000959
960 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
961}
962
niklase@google.com470e71d2011-07-07 08:21:25 +0000963void
964RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
965 RTCPPacketInformation& rtcpPacketInformation)
966{
967 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
968
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000969 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000970 {
971 // Store VoIP metrics block if it's about me
972 // from OriginatorSSRC do we filter it?
973 // rtcpPacket.XR.OriginatorSSRC;
974
975 RTCPVoIPMetric receivedVoIPMetrics;
976 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
977 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
978 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
979 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
980 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
981 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
982 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
983 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
984 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
985 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
986 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
987 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
988 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
989 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
990 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
991 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
992 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
993 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
994 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
995 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
996
997 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
998
999 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
1000 }
1001 rtcpParser.Iterate();
1002}
1003
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001004void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
1005 RTCPPacketInformation& rtcpPacketInformation) {
1006 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001007 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +00001008 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +00001009
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001010 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001011 // Received a signal that we need to send a new key frame.
1012 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
1013 }
1014 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001015}
1016
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001017void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
1018 RTCPPacketInformation& rtcpPacketInformation) {
1019 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001020
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001021 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
1022 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
1023 if (ptrReceiveInfo == NULL) {
1024 // This remote SSRC must be saved before.
1025 rtcpParser.Iterate();
1026 return;
1027 }
1028 if (rtcpPacket.TMMBR.MediaSSRC) {
1029 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1030 // in relay mode this is a valid number
1031 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1032 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001033
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001034 // Use packet length to calc max number of TMMBR blocks
1035 // each TMMBR block is 8 bytes
1036 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001037
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001038 // sanity, we can't have more than what's in one packet
1039 if (maxNumOfTMMBRBlocks > 200) {
1040 assert(false);
1041 rtcpParser.Iterate();
1042 return;
1043 }
1044 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001045
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001046 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001047 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001048 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1049 pktType = rtcpParser.Iterate();
1050 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001051}
1052
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001053void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1054 const RTCPUtility::RTCPPacket& rtcpPacket,
1055 RTCPPacketInformation& rtcpPacketInformation,
1056 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001057 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1058 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1059 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1060 _clock->TimeInMilliseconds());
1061 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1062 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001063}
1064
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001065void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1066 RTCPPacketInformation& rtcpPacketInformation) {
1067 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1068 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1069 rtcpPacket.TMMBN.SenderSSRC);
1070 if (ptrReceiveInfo == NULL) {
1071 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001072 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001073 return;
1074 }
1075 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1076 // Use packet length to calc max number of TMMBN blocks
1077 // each TMMBN block is 8 bytes
1078 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1079
1080 // sanity, we cant have more than what's in one packet
1081 if (maxNumOfTMMBNBlocks > 200) {
1082 assert(false);
1083 rtcpParser.Iterate();
1084 return;
1085 }
1086
1087 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1088
1089 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001090 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001091 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1092 pktType = rtcpParser.Iterate();
1093 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001094}
1095
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001096void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1097 RTCPPacketInformation& rtcpPacketInformation) {
1098 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1099 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001100}
1101
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001102void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1103 const RTCPUtility::RTCPPacket& rtcpPacket) {
1104 receiveInfo.TmmbnBoundingSet.AddEntry(
1105 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1106 rtcpPacket.TMMBNItem.MeasuredOverhead,
1107 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001108}
1109
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001110void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1111 RTCPPacketInformation& rtcpPacketInformation) {
1112 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1113 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001114 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001115 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1116 pktType = rtcpParser.Iterate();
1117 }
1118}
1119
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001120void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1121 RTCPPacketInformation& rtcpPacketInformation) {
1122 // in theory there could be multiple slices lost
1123 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1124 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001125}
1126
1127void
1128RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1129 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1130{
1131 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001132 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001133 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001134 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1135 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1136 {
1137 // to us unknown
1138 // continue
1139 rtcpParser.Iterate();
1140 return;
1141 }
1142 rtcpPacketInformation.rpsiPictureId = 0;
1143
1144 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001145 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1146 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001147 {
1148 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1149 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1150 }
1151 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1152 }
1153}
1154
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001155void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1156 RTCPPacketInformation& rtcpPacketInformation) {
1157 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001158 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001159 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001160 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001161 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1162 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001163 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001164 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001165}
1166
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001167void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1168 RTCPPacketInformation& rtcpPacketInformation) {
1169 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001170
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001171 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001172 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001173 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1174 pktType = rtcpParser.Iterate();
1175 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001176}
1177
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001178void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1179 RTCPPacketInformation& rtcpPacketInformation) {
1180 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1181 rtcpPacketInformation.interArrivalJitter =
1182 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001183}
1184
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001185void RTCPReceiver::HandleREMBItem(
1186 RTCPUtility::RTCPParserV2& rtcpParser,
1187 RTCPPacketInformation& rtcpPacketInformation) {
1188 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1189 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1190 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1191 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001192}
1193
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001194void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1195 RTCPPacketInformation& rtcpPacketInformation) {
1196 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1197 RTCPReceiveInformation* ptrReceiveInfo =
1198 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001199
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001200 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001201 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001202 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1203 pktType = rtcpParser.Iterate();
1204 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001205}
1206
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001207void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1208 const RTCPUtility::RTCPPacket& rtcpPacket,
1209 RTCPPacketInformation& rtcpPacketInformation) {
1210 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001211 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001212 return;
1213 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001214
1215 ++packet_type_counter_.fir_packets;
1216
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001217 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1218 // we don't know who this originate from
1219 if (receiveInfo) {
1220 // check if we have reported this FIRSequenceNumber before
1221 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1222 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001223 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001224 // sanity; don't go crazy with the callbacks
1225 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1226 receiveInfo->lastFIRRequest = now;
1227 receiveInfo->lastFIRSequenceNumber =
1228 rtcpPacket.FIRItem.CommandSequenceNumber;
1229 // received signal that we need to send a new key frame
1230 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1231 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001232 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001233 } else {
1234 // received signal that we need to send a new key frame
1235 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1236 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001237}
1238
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001239void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1240 RTCPPacketInformation& rtcpPacketInformation) {
1241 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001242
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001243 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1244 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1245 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001246
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001247 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001248}
1249
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001250void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1251 RTCPPacketInformation& rtcpPacketInformation) {
1252 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001253
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001254 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001255
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001256 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001257}
1258
Erik Språng6b8d3552015-09-24 15:06:57 +02001259void RTCPReceiver::HandleTransportFeedback(
1260 RTCPUtility::RTCPParserV2* rtcp_parser,
1261 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1262 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1263 RTC_DCHECK(packet != nullptr);
1264 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1265 rtcp_packet_information->transport_feedback_.reset(
1266 static_cast<rtcp::TransportFeedback*>(packet));
1267
1268 rtcp_parser->Iterate();
1269}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001270int32_t RTCPReceiver::UpdateTMMBR() {
1271 int32_t numBoundingSet = 0;
1272 uint32_t bitrate = 0;
1273 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001274
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001275 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001276 if (size > 0) {
1277 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1278 // Get candidate set from receiver.
1279 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1280 } else {
1281 // Candidate set empty.
1282 VerifyAndAllocateCandidateSet(0); // resets candidate set
1283 }
1284 // Find bounding set
1285 TMMBRSet* boundingSet = NULL;
1286 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1287 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001288 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001289 return -1;
1290 }
1291 // Set bounding set
1292 // Inform remote clients about the new bandwidth
1293 // inform the remote client
1294 _rtpRtcp.SetTMMBN(boundingSet);
1295
1296 // might trigger a TMMBN
1297 if (numBoundingSet == 0) {
1298 // owner of max bitrate request has timed out
1299 // empty bounding set has been sent
1300 return 0;
1301 }
1302 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001303 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001304 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001305 if (_cbRtcpBandwidthObserver) {
1306 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001307 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001308 }
1309 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001310}
1311
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001312void RTCPReceiver::RegisterRtcpStatisticsCallback(
1313 RtcpStatisticsCallback* callback) {
1314 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001315 stats_callback_ = callback;
1316}
1317
1318RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1319 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1320 return stats_callback_;
1321}
1322
niklase@google.com470e71d2011-07-07 08:21:25 +00001323// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001324void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001325 RTCPPacketInformation& rtcpPacketInformation) {
1326 // Process TMMBR and REMB first to avoid multiple callbacks
1327 // to OnNetworkChanged.
1328 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001329 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1330 UpdateTMMBR();
1331 }
sprang7dc39f32015-10-13 09:17:48 -07001332 uint32_t local_ssrc;
1333 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001334 {
1335 // We don't want to hold this critsect when triggering the callbacks below.
1336 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001337 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001338 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001339 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001340 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001341 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001342 _rtpRtcp.OnRequestSendReport();
1343 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001344 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001345 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001346 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001347 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001348 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001349 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001350 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001351 }
1352 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001353 // We need feedback that we have received a report block(s) so that we
1354 // can generate a new packet in a conference relay scenario, one received
1355 // report can generate several RTCP packets, based on number relayed/mixed
1356 // a send report block should go out to all receivers.
1357 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001358 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001359 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1360 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1361 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001362 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001363 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001364 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001365 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001366 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001367 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001368 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001369 }
1370 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1371 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001372 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001373 }
1374 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1375 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001376 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001377 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001378 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001379 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001380 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001381 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001382 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001383 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001384 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1385 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1386 }
Erik Språng242e22b2015-05-11 10:17:43 +02001387 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1388 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001389 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001390 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001391 rtcpPacketInformation.report_blocks,
1392 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001393 now);
1394 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001395 }
Erik Språng6b8d3552015-09-24 15:06:57 +02001396 if (_cbTransportFeedbackObserver &&
1397 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1398 uint32_t media_source_ssrc =
1399 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001400 if (media_source_ssrc == local_ssrc ||
1401 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001402 _cbTransportFeedbackObserver->OnTransportFeedback(
1403 *rtcpPacketInformation.transport_feedback_.get());
1404 }
1405 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001406 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001407
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001408 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001409 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1410 if (stats_callback_) {
1411 for (ReportBlockList::const_iterator it =
1412 rtcpPacketInformation.report_blocks.begin();
1413 it != rtcpPacketInformation.report_blocks.end();
1414 ++it) {
1415 RtcpStatistics stats;
1416 stats.cumulative_lost = it->cumulativeLost;
1417 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1418 stats.fraction_lost = it->fractionLost;
1419 stats.jitter = it->jitter;
1420
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001421 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001422 }
1423 }
1424 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001425}
1426
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001427int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001428 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001429 assert(cName);
1430
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001431 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1432 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001433 if (cnameInfo == NULL) {
1434 return -1;
1435 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001436 cName[RTCP_CNAME_SIZE - 1] = 0;
1437 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1438 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001439}
1440
1441// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001442int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1443 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001444 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001445 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001446
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001447 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001448 receiveInfoIt = _receivedInfoMap.begin();
1449 if (receiveInfoIt == _receivedInfoMap.end()) {
1450 return -1;
1451 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001452 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001453 if (candidateSet) {
1454 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1455 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1456 if (receiveInfo == NULL) {
1457 return 0;
1458 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001459 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001460 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001461 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001462 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001463 num++;
1464 }
1465 }
1466 receiveInfoIt++;
1467 }
1468 } else {
1469 while (receiveInfoIt != _receivedInfoMap.end()) {
1470 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1471 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001472 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001473 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001474 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001475 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001476 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001477 }
1478 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001479}
1480
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001481} // namespace webrtc