blob: b914838109f418835f11d1b4970f285f144666d4 [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 {
26using namespace RTCPUtility;
27using namespace RTCPHelp;
28
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000029// The number of RTCP time intervals needed to trigger a timeout.
30const int kRrTimeoutIntervals = 3;
31
Erik Språng6b8d3552015-09-24 15:06:57 +020032const int64_t kMaxWarningLogIntervalMs = 10000;
33
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000034RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000035 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020036 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000037 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000038 RtcpBandwidthObserver* rtcp_bandwidth_observer,
39 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020040 TransportFeedbackObserver* transport_feedback_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000041 ModuleRtpRtcpImpl* owner)
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000042 : TMMBRHelp(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000043 _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020044 receiver_only_(receiver_only),
pbosda903ea2015-10-02 02:36:56 -070045 _method(RtcpMode::kOff),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000046 _lastReceived(0),
47 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000048 _criticalSectionFeedbacks(
49 CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000050 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
51 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020052 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000053 _criticalSectionRTCPReceiver(
54 CriticalSectionWrapper::CreateCriticalSection()),
55 main_ssrc_(0),
56 _remoteSSRC(0),
57 _remoteSenderInfo(),
58 _lastReceivedSRNTPsecs(0),
59 _lastReceivedSRNTPfrac(0),
60 _lastReceivedXRNTPsecs(0),
61 _lastReceivedXRNTPfrac(0),
62 xr_rr_rtt_ms_(0),
63 _receivedInfoMap(),
64 _packetTimeOutMS(0),
65 _lastReceivedRrMs(0),
66 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000067 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020068 packet_type_counter_observer_(packet_type_counter_observer),
69 num_skipped_packets_(0),
70 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000071 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000072}
73
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000074RTCPReceiver::~RTCPReceiver() {
75 delete _criticalSectionRTCPReceiver;
76 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000077
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000078 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
79 for (; it != _receivedReportBlockMap.end(); ++it) {
80 ReportBlockInfoMap* info_map = &(it->second);
81 while (!info_map->empty()) {
82 ReportBlockInfoMap::iterator it_info = info_map->begin();
83 delete it_info->second;
84 info_map->erase(it_info);
85 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000086 }
87 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000088 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000089 _receivedInfoMap.begin();
90 delete first->second;
91 _receivedInfoMap.erase(first);
92 }
93 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000094 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000095 _receivedCnameMap.begin();
96 delete first->second;
97 _receivedCnameMap.erase(first);
98 }
niklase@google.com470e71d2011-07-07 08:21:25 +000099}
100
pbosda903ea2015-10-02 02:36:56 -0700101RtcpMode RTCPReceiver::Status() const {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000102 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
103 return _method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000104}
105
pbosda903ea2015-10-02 02:36:56 -0700106void RTCPReceiver::SetRTCPStatus(RtcpMode method) {
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000107 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
108 _method = method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000109}
110
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000111int64_t RTCPReceiver::LastReceived() {
112 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
113 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000114}
115
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000116int64_t RTCPReceiver::LastReceivedReceiverReport() const {
117 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
118 int64_t last_received_rr = -1;
119 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
120 it != _receivedInfoMap.end(); ++it) {
121 if (it->second->lastTimeReceived > last_received_rr) {
122 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000123 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000124 }
125 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000126}
127
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000128void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
129 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000130
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000131 // new SSRC reset old reports
132 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
133 _lastReceivedSRNTPsecs = 0;
134 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000135
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000136 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000137}
138
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000139uint32_t RTCPReceiver::RemoteSSRC() const {
140 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
141 return _remoteSSRC;
142}
143
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000144void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
145 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000146 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000147 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000148 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000149 old_ssrc = main_ssrc_;
150 main_ssrc_ = main_ssrc;
151 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000152 }
153 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000154 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
155 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000156 }
157 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000158}
159
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000160int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000161 int64_t* RTT,
162 int64_t* avgRTT,
163 int64_t* minRTT,
164 int64_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000165 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000166
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000167 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000168 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000169
170 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000171 return -1;
172 }
173 if (RTT) {
174 *RTT = reportBlock->RTT;
175 }
176 if (avgRTT) {
177 *avgRTT = reportBlock->avgRTT;
178 }
179 if (minRTT) {
180 *minRTT = reportBlock->minRTT;
181 }
182 if (maxRTT) {
183 *maxRTT = reportBlock->maxRTT;
184 }
185 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000186}
187
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000188bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000189 assert(rtt_ms);
190 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
191 if (xr_rr_rtt_ms_ == 0) {
192 return false;
193 }
194 *rtt_ms = xr_rr_rtt_ms_;
195 xr_rr_rtt_ms_ = 0;
196 return true;
197}
198
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000199// TODO(pbos): Make this fail when we haven't received NTP.
200bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
201 uint32_t* ReceivedNTPfrac,
202 uint32_t* RTCPArrivalTimeSecs,
203 uint32_t* RTCPArrivalTimeFrac,
204 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000205{
206 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
207 if(ReceivedNTPsecs)
208 {
209 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
210 }
211 if(ReceivedNTPfrac)
212 {
213 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
214 }
215 if(RTCPArrivalTimeFrac)
216 {
217 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
218 }
219 if(RTCPArrivalTimeSecs)
220 {
221 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
222 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000223 if (rtcp_timestamp) {
224 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
225 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000226 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000227}
228
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000229bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
230 RtcpReceiveTimeInfo* info) const {
231 assert(info);
232 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
233 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
234 return false;
235 }
236
237 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
238 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
239
240 // Get the delay since last received report (RFC 3611).
241 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
242 _lastReceivedXRNTPfrac);
243
244 uint32_t ntp_sec = 0;
245 uint32_t ntp_frac = 0;
246 _clock->CurrentNtp(ntp_sec, ntp_frac);
247 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
248
249 info->delaySinceLastRR = now - receive_time;
250 return true;
251}
252
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000253int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
254 assert(senderInfo);
255 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
256 if (_lastReceivedSRNTPsecs == 0) {
257 return -1;
258 }
259 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
260 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000261}
262
263// statistics
264// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000265int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000266 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000267 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000268 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000269 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
270 for (; it != _receivedReportBlockMap.end(); ++it) {
271 const ReportBlockInfoMap* info_map = &(it->second);
272 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
273 for (; it_info != info_map->end(); ++it_info) {
274 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
275 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000276 }
277 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000278}
279
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000280int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000281RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
282 RTCPUtility::RTCPParserV2* rtcpParser)
283{
284 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
285
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000286 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000287
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000288 if (packet_type_counter_.first_packet_time_ms == -1) {
289 packet_type_counter_.first_packet_time_ms = _lastReceived;
290 }
291
niklase@google.com470e71d2011-07-07 08:21:25 +0000292 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200293 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000294 // Each "case" is responsible for iterate the parser to the
295 // next top level packet.
296 switch (pktType)
297 {
Erik Språng242e22b2015-05-11 10:17:43 +0200298 case RTCPPacketTypes::kSr:
299 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000300 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
301 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200302 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200303 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000304 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200305 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000306 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
307 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200308 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000309 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
310 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200311 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000312 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
313 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200314 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000315 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
316 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200317 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000318 HandleBYE(*rtcpParser);
319 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200320 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000321 HandleNACK(*rtcpParser, rtcpPacketInformation);
322 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200323 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000324 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
325 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200326 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000327 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200329 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000330 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
331 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200332 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 HandlePLI(*rtcpParser, rtcpPacketInformation);
334 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200335 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000336 HandleSLI(*rtcpParser, rtcpPacketInformation);
337 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200338 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 HandleRPSI(*rtcpParser, rtcpPacketInformation);
340 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200341 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000342 HandleIJ(*rtcpParser, rtcpPacketInformation);
343 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200344 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000345 HandleFIR(*rtcpParser, rtcpPacketInformation);
346 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200347 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000348 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
349 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200350 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000351 // generic application messages
352 HandleAPP(*rtcpParser, rtcpPacketInformation);
353 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200354 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000355 // generic application messages
356 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
357 break;
Erik Språng6b8d3552015-09-24 15:06:57 +0200358 case RTCPPacketTypes::kTransportFeedback:
359 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
360 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000361 default:
362 rtcpParser->Iterate();
363 break;
364 }
365 pktType = rtcpParser->PacketType();
366 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000367
368 if (packet_type_counter_observer_ != NULL) {
369 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
370 main_ssrc_, packet_type_counter_);
371 }
372
Erik Språng6b8d3552015-09-24 15:06:57 +0200373 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
374
375 int64_t now = _clock->TimeInMilliseconds();
376 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
377 num_skipped_packets_ > 0) {
378 last_skipped_packets_warning_ = now;
379 LOG(LS_WARNING)
380 << num_skipped_packets_
381 << " RTCP blocks were skipped due to being malformed or of "
382 "unrecognized/unsupported type, during the past "
383 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
384 }
385
niklase@google.com470e71d2011-07-07 08:21:25 +0000386 return 0;
387}
388
niklase@google.com470e71d2011-07-07 08:21:25 +0000389void
390RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
391 RTCPPacketInformation& rtcpPacketInformation)
392{
393 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
394 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
395
Erik Språng242e22b2015-05-11 10:17:43 +0200396 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
397 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000398
399 // SR.SenderSSRC
400 // The synchronization source identifier for the originator of this SR packet
401
402 // rtcpPacket.RR.SenderSSRC
403 // The source of the packet sender, same as of SR? or is this a CE?
404
Erik Språng242e22b2015-05-11 10:17:43 +0200405 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
406 ? rtcpPacket.RR.SenderSSRC
407 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000408
409 rtcpPacketInformation.remoteSSRC = remoteSSRC;
410
411 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
412 if (!ptrReceiveInfo)
413 {
414 rtcpParser.Iterate();
415 return;
416 }
417
Erik Språng242e22b2015-05-11 10:17:43 +0200418 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000419 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
420 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000421
niklase@google.com470e71d2011-07-07 08:21:25 +0000422 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
423 {
424 // only signal that we have received a SR when we accept one
425 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
426
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000427 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
428 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
429 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
430
niklase@google.com470e71d2011-07-07 08:21:25 +0000431 // We will only store the send report from one source, but
432 // we will store all the receive block
433
434 // Save the NTP time of this report
435 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
436 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
437 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
438 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
439 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
440
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000441 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000442 }
443 else
444 {
445 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
446 }
447 } else
448 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000449 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
450 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000451
452 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
453 }
454 UpdateReceiveInformation(*ptrReceiveInfo);
455
456 rtcpPacketType = rtcpParser.Iterate();
457
Erik Språng242e22b2015-05-11 10:17:43 +0200458 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000459 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000460 rtcpPacketType = rtcpParser.Iterate();
461 }
462}
463
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000464void RTCPReceiver::HandleReportBlock(
465 const RTCPUtility::RTCPPacket& rtcpPacket,
466 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000467 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000468 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000469 // This will be called once per report block in the RTCP packet.
470 // We filter out all report blocks that are not for us.
471 // Each packet has max 31 RR blocks.
472 //
473 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000474
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000475 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
476 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000477
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000478 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000479 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
480 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000481 // This block is not for us ignore it.
482 return;
483 }
484
485 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
486 // _criticalSectionRTCPReceiver.
487 _criticalSectionRTCPReceiver->Leave();
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000488 int64_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000489 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
490 _criticalSectionRTCPReceiver->Enter();
491
492 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000493 CreateOrGetReportBlockInformation(remoteSSRC,
494 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000495 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000496 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
497 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000498 return;
499 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000500
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000501 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000502 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
503 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
504 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
505 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
506 reportBlock->remoteReceiveBlock.cumulativeLost =
507 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000508 if (rb.ExtendedHighestSequenceNumber >
509 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
510 // We have successfully delivered new RTP packets to the remote side after
511 // the last RR was sent from the remote side.
512 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000513 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000514 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
515 rb.ExtendedHighestSequenceNumber;
516 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
517 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
518 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
519
520 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
521 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
522 }
523
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000524 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000525 rtcpPacket.ReportBlockItem.DelayLastSR;
526
527 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000528 uint32_t lastReceivedRRNTPsecs = 0;
529 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000530
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000531 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000532
533 // time when we received this in MS
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000534 int64_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
535 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000536
537 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000538 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000539 d /= 65536;
540 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
541
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000542 int64_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000543
544 if (sendTimeMS > 0) {
545 RTT = receiveTimeMS - d - sendTimeMS;
546 if (RTT <= 0) {
547 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000548 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000549 if (RTT > reportBlock->maxRTT) {
550 // store max RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000551 reportBlock->maxRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000552 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000553 if (reportBlock->minRTT == 0) {
554 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000555 reportBlock->minRTT = RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000556 } else if (RTT < reportBlock->minRTT) {
557 // Store min RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000558 reportBlock->minRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000559 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000560 // store last RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000561 reportBlock->RTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000562
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000563 // store average RTT
564 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000565 float ac = static_cast<float>(reportBlock->numAverageCalcs);
566 float newAverage =
567 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * RTT);
568 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000569 } else {
570 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000571 reportBlock->avgRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000572 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000573 reportBlock->numAverageCalcs++;
574 }
575
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000576 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
577 RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000578
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000579 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000580}
581
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000582RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
583 uint32_t remote_ssrc,
584 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000585 RTCPReportBlockInformation* info =
586 GetReportBlockInformation(remote_ssrc, source_ssrc);
587 if (info == NULL) {
588 info = new RTCPReportBlockInformation;
589 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000590 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000591 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000592}
593
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000594RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
595 uint32_t remote_ssrc,
596 uint32_t source_ssrc) const {
597 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000598 if (it == _receivedReportBlockMap.end()) {
599 return NULL;
600 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000601 const ReportBlockInfoMap* info_map = &(it->second);
602 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
603 if (it_info == info_map->end()) {
604 return NULL;
605 }
606 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000607}
608
609RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000610RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000611 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000612
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000613 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000614 _receivedCnameMap.find(remoteSSRC);
615
616 if (it != _receivedCnameMap.end()) {
617 return it->second;
618 }
619 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000620 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000621 _receivedCnameMap[remoteSSRC] = cnameInfo;
622 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000623}
624
625RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000626RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000627 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000628
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000629 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000630 _receivedCnameMap.find(remoteSSRC);
631
632 if (it == _receivedCnameMap.end()) {
633 return NULL;
634 }
635 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000636}
637
638RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000639RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000640 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000641
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000642 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000643 _receivedInfoMap.find(remoteSSRC);
644
645 if (it != _receivedInfoMap.end()) {
646 return it->second;
647 }
648 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
649 _receivedInfoMap[remoteSSRC] = receiveInfo;
650 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000651}
652
653RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000654RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000655 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000656
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000657 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000658 _receivedInfoMap.find(remoteSSRC);
659 if (it == _receivedInfoMap.end()) {
660 return NULL;
661 }
662 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000663}
664
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000665void RTCPReceiver::UpdateReceiveInformation(
666 RTCPReceiveInformation& receiveInformation) {
667 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000668 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000669}
670
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000671bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
672 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
673 if (_lastReceivedRrMs == 0)
674 return false;
675
676 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000677 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000678 // Reset the timer to only trigger one log.
679 _lastReceivedRrMs = 0;
680 return true;
681 }
682 return false;
683}
684
685bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
686 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
687 if (_lastIncreasedSequenceNumberMs == 0)
688 return false;
689
690 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000691 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000692 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000693 // Reset the timer to only trigger one log.
694 _lastIncreasedSequenceNumberMs = 0;
695 return true;
696 }
697 return false;
698}
699
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000700bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
701 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000702
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000703 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000704 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000705
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000706 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000707 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000708
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000709 while (receiveInfoIt != _receivedInfoMap.end()) {
710 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
711 if (receiveInfo == NULL) {
712 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000713 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000714 // time since last received rtcp packet
715 // when we dont have a lastTimeReceived and the object is marked
716 // readyForDelete it's removed from the map
717 if (receiveInfo->lastTimeReceived) {
718 /// use audio define since we don't know what interval the remote peer is
719 // using
720 if ((timeNow - receiveInfo->lastTimeReceived) >
721 5 * RTCP_INTERVAL_AUDIO_MS) {
722 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000723 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000724 // prevent that we call this over and over again
725 receiveInfo->lastTimeReceived = 0;
726 // send new TMMBN to all channels using the default codec
727 updateBoundingSet = true;
728 }
729 receiveInfoIt++;
730 } else if (receiveInfo->readyForDelete) {
731 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000732 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000733 receiveInfoItemToBeErased = receiveInfoIt;
734 receiveInfoIt++;
735 delete receiveInfoItemToBeErased->second;
736 _receivedInfoMap.erase(receiveInfoItemToBeErased);
737 } else {
738 receiveInfoIt++;
739 }
740 }
741 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000742}
743
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000744int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000745 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000746
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000747 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000748 _receivedInfoMap.find(_remoteSSRC);
749
750 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000751 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000752 }
753 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
754 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000755 return -1;
756 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000757 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000758 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000759 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000760 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000761 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000762 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000763 // owner of bounding set
764 tmmbrOwner = true;
765 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000766 boundingSetRec->SetEntry(i,
767 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
768 receiveInfo->TmmbnBoundingSet.PacketOH(i),
769 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000770 }
771 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000772 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000773}
774
Erik Språnga38233a2015-07-24 09:58:18 +0200775void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
776 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000777 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200778 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000779 HandleSDESChunk(rtcpParser);
780 pktType = rtcpParser.Iterate();
781 }
Erik Språnga38233a2015-07-24 09:58:18 +0200782 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000783}
784
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000785void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
786 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
787 RTCPCnameInformation* cnameInfo =
788 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
789 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000790
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000791 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
792 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000793 {
794 CriticalSectionScoped lock(_criticalSectionFeedbacks);
795 if (stats_callback_ != NULL) {
796 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
797 rtcpPacket.CName.SenderSSRC);
798 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000799 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000800}
801
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000802void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
803 RTCPPacketInformation& rtcpPacketInformation) {
804 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200805 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000806 // Not to us.
807 rtcpParser.Iterate();
808 return;
809 }
810 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000811
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000812 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200813 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000814 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
815 pktType = rtcpParser.Iterate();
816 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000817
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000818 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
819 ++packet_type_counter_.nack_packets;
820 packet_type_counter_.nack_requests = nack_stats_.requests();
821 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
822 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000823}
824
niklase@google.com470e71d2011-07-07 08:21:25 +0000825void
826RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000827 RTCPPacketInformation& rtcpPacketInformation) {
828 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
829 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000830
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000831 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
832 if (bitMask) {
833 for (int i=1; i <= 16; ++i) {
834 if (bitMask & 0x01) {
835 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
836 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
837 }
838 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000839 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000840 }
841 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000842}
843
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000844void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
845 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000846
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000847 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000848 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
849 for (; it != _receivedReportBlockMap.end(); ++it) {
850 ReportBlockInfoMap* info_map = &(it->second);
851 ReportBlockInfoMap::iterator it_info = info_map->find(
852 rtcpPacket.BYE.SenderSSRC);
853 if (it_info != info_map->end()) {
854 delete it_info->second;
855 info_map->erase(it_info);
856 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000857 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000858
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000859 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000860 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000861 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000862
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000863 if (receiveInfoIt != _receivedInfoMap.end()) {
864 receiveInfoIt->second->readyForDelete = true;
865 }
866
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000867 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000868 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
869
870 if (cnameInfoIt != _receivedCnameMap.end()) {
871 delete cnameInfoIt->second;
872 _receivedCnameMap.erase(cnameInfoIt);
873 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000874 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000875 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000876}
877
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000878void RTCPReceiver::HandleXrHeader(
879 RTCPUtility::RTCPParserV2& parser,
880 RTCPPacketInformation& rtcpPacketInformation) {
881 const RTCPUtility::RTCPPacket& packet = parser.Packet();
882
883 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
884
885 parser.Iterate();
886}
887
888void RTCPReceiver::HandleXrReceiveReferenceTime(
889 RTCPUtility::RTCPParserV2& parser,
890 RTCPPacketInformation& rtcpPacketInformation) {
891 const RTCPUtility::RTCPPacket& packet = parser.Packet();
892
893 _remoteXRReceiveTimeInfo.sourceSSRC =
894 rtcpPacketInformation.xr_originator_ssrc;
895
896 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
897 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
898 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
899
900 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
901
902 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
903
904 parser.Iterate();
905}
906
907void RTCPReceiver::HandleXrDlrrReportBlock(
908 RTCPUtility::RTCPParserV2& parser,
909 RTCPPacketInformation& rtcpPacketInformation) {
910 const RTCPUtility::RTCPPacket& packet = parser.Packet();
911 // Iterate through sub-block(s), if any.
912 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
913
Erik Språng242e22b2015-05-11 10:17:43 +0200914 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000915 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
916 packet_type = parser.Iterate();
917 }
918}
919
920void RTCPReceiver::HandleXrDlrrReportBlockItem(
921 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000922 RTCPPacketInformation& rtcpPacketInformation)
923 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000924 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
925 registered_ssrcs_.end()) {
926 // Not to us.
927 return;
928 }
929
930 rtcpPacketInformation.xr_dlrr_item = true;
931
932 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
933 // _criticalSectionRTCPReceiver.
934 _criticalSectionRTCPReceiver->Leave();
935
936 int64_t send_time_ms;
937 bool found = _rtpRtcp.SendTimeOfXrRrReport(
938 packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
939
940 _criticalSectionRTCPReceiver->Enter();
941
942 if (!found) {
943 return;
944 }
945
946 // The DelayLastRR field is in units of 1/65536 sec.
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000947 uint32_t delay_rr_ms =
948 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
949 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000950
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000951 int64_t rtt = _clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000952
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000953 xr_rr_rtt_ms_ = std::max<int64_t>(rtt, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000954
955 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
956}
957
niklase@google.com470e71d2011-07-07 08:21:25 +0000958void
959RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
960 RTCPPacketInformation& rtcpPacketInformation)
961{
962 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
963
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000964 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000965 {
966 // Store VoIP metrics block if it's about me
967 // from OriginatorSSRC do we filter it?
968 // rtcpPacket.XR.OriginatorSSRC;
969
970 RTCPVoIPMetric receivedVoIPMetrics;
971 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
972 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
973 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
974 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
975 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
976 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
977 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
978 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
979 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
980 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
981 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
982 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
983 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
984 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
985 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
986 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
987 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
988 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
989 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
990 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
991
992 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
993
994 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
995 }
996 rtcpParser.Iterate();
997}
998
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000999void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
1000 RTCPPacketInformation& rtcpPacketInformation) {
1001 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001002 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +00001003 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +00001004
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001005 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001006 // Received a signal that we need to send a new key frame.
1007 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
1008 }
1009 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001010}
1011
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001012void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
1013 RTCPPacketInformation& rtcpPacketInformation) {
1014 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001015
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001016 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
1017 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
1018 if (ptrReceiveInfo == NULL) {
1019 // This remote SSRC must be saved before.
1020 rtcpParser.Iterate();
1021 return;
1022 }
1023 if (rtcpPacket.TMMBR.MediaSSRC) {
1024 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1025 // in relay mode this is a valid number
1026 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1027 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001028
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001029 // Use packet length to calc max number of TMMBR blocks
1030 // each TMMBR block is 8 bytes
1031 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001032
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001033 // sanity, we can't have more than what's in one packet
1034 if (maxNumOfTMMBRBlocks > 200) {
1035 assert(false);
1036 rtcpParser.Iterate();
1037 return;
1038 }
1039 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001040
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001041 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001042 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001043 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1044 pktType = rtcpParser.Iterate();
1045 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001046}
1047
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001048void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1049 const RTCPUtility::RTCPPacket& rtcpPacket,
1050 RTCPPacketInformation& rtcpPacketInformation,
1051 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001052 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1053 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1054 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1055 _clock->TimeInMilliseconds());
1056 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1057 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001058}
1059
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001060void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1061 RTCPPacketInformation& rtcpPacketInformation) {
1062 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1063 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1064 rtcpPacket.TMMBN.SenderSSRC);
1065 if (ptrReceiveInfo == NULL) {
1066 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001067 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001068 return;
1069 }
1070 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1071 // Use packet length to calc max number of TMMBN blocks
1072 // each TMMBN block is 8 bytes
1073 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1074
1075 // sanity, we cant have more than what's in one packet
1076 if (maxNumOfTMMBNBlocks > 200) {
1077 assert(false);
1078 rtcpParser.Iterate();
1079 return;
1080 }
1081
1082 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1083
1084 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001085 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001086 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1087 pktType = rtcpParser.Iterate();
1088 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001089}
1090
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001091void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1092 RTCPPacketInformation& rtcpPacketInformation) {
1093 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1094 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001095}
1096
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001097void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1098 const RTCPUtility::RTCPPacket& rtcpPacket) {
1099 receiveInfo.TmmbnBoundingSet.AddEntry(
1100 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1101 rtcpPacket.TMMBNItem.MeasuredOverhead,
1102 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001103}
1104
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001105void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1106 RTCPPacketInformation& rtcpPacketInformation) {
1107 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1108 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001109 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001110 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1111 pktType = rtcpParser.Iterate();
1112 }
1113}
1114
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001115void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1116 RTCPPacketInformation& rtcpPacketInformation) {
1117 // in theory there could be multiple slices lost
1118 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1119 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001120}
1121
1122void
1123RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1124 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1125{
1126 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001127 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001128 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001129 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1130 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1131 {
1132 // to us unknown
1133 // continue
1134 rtcpParser.Iterate();
1135 return;
1136 }
1137 rtcpPacketInformation.rpsiPictureId = 0;
1138
1139 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001140 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1141 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001142 {
1143 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1144 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1145 }
1146 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1147 }
1148}
1149
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001150void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1151 RTCPPacketInformation& rtcpPacketInformation) {
1152 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001153 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001154 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001155 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001156 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1157 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001158 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001159 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001160}
1161
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001162void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1163 RTCPPacketInformation& rtcpPacketInformation) {
1164 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001165
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001166 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001167 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001168 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1169 pktType = rtcpParser.Iterate();
1170 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001171}
1172
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001173void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1174 RTCPPacketInformation& rtcpPacketInformation) {
1175 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1176 rtcpPacketInformation.interArrivalJitter =
1177 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001178}
1179
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001180void RTCPReceiver::HandleREMBItem(
1181 RTCPUtility::RTCPParserV2& rtcpParser,
1182 RTCPPacketInformation& rtcpPacketInformation) {
1183 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1184 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1185 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1186 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001187}
1188
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001189void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1190 RTCPPacketInformation& rtcpPacketInformation) {
1191 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1192 RTCPReceiveInformation* ptrReceiveInfo =
1193 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001194
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001195 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001196 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001197 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1198 pktType = rtcpParser.Iterate();
1199 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001200}
1201
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001202void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1203 const RTCPUtility::RTCPPacket& rtcpPacket,
1204 RTCPPacketInformation& rtcpPacketInformation) {
1205 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001206 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001207 return;
1208 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001209
1210 ++packet_type_counter_.fir_packets;
1211
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001212 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1213 // we don't know who this originate from
1214 if (receiveInfo) {
1215 // check if we have reported this FIRSequenceNumber before
1216 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1217 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001218 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001219 // sanity; don't go crazy with the callbacks
1220 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1221 receiveInfo->lastFIRRequest = now;
1222 receiveInfo->lastFIRSequenceNumber =
1223 rtcpPacket.FIRItem.CommandSequenceNumber;
1224 // received signal that we need to send a new key frame
1225 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1226 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001227 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001228 } else {
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}
1233
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001234void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1235 RTCPPacketInformation& rtcpPacketInformation) {
1236 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001237
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001238 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1239 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1240 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001241
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001242 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001243}
1244
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001245void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1246 RTCPPacketInformation& rtcpPacketInformation) {
1247 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001248
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001249 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001250
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001251 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001252}
1253
Erik Språng6b8d3552015-09-24 15:06:57 +02001254void RTCPReceiver::HandleTransportFeedback(
1255 RTCPUtility::RTCPParserV2* rtcp_parser,
1256 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1257 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1258 RTC_DCHECK(packet != nullptr);
1259 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1260 rtcp_packet_information->transport_feedback_.reset(
1261 static_cast<rtcp::TransportFeedback*>(packet));
1262
1263 rtcp_parser->Iterate();
1264}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001265int32_t RTCPReceiver::UpdateTMMBR() {
1266 int32_t numBoundingSet = 0;
1267 uint32_t bitrate = 0;
1268 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001269
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001270 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001271 if (size > 0) {
1272 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1273 // Get candidate set from receiver.
1274 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1275 } else {
1276 // Candidate set empty.
1277 VerifyAndAllocateCandidateSet(0); // resets candidate set
1278 }
1279 // Find bounding set
1280 TMMBRSet* boundingSet = NULL;
1281 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1282 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001283 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001284 return -1;
1285 }
1286 // Set bounding set
1287 // Inform remote clients about the new bandwidth
1288 // inform the remote client
1289 _rtpRtcp.SetTMMBN(boundingSet);
1290
1291 // might trigger a TMMBN
1292 if (numBoundingSet == 0) {
1293 // owner of max bitrate request has timed out
1294 // empty bounding set has been sent
1295 return 0;
1296 }
1297 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001298 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001299 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001300 if (_cbRtcpBandwidthObserver) {
1301 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001302 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001303 }
1304 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001305}
1306
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001307void RTCPReceiver::RegisterRtcpStatisticsCallback(
1308 RtcpStatisticsCallback* callback) {
1309 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001310 stats_callback_ = callback;
1311}
1312
1313RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1314 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1315 return stats_callback_;
1316}
1317
niklase@google.com470e71d2011-07-07 08:21:25 +00001318// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001319void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001320 RTCPPacketInformation& rtcpPacketInformation) {
1321 // Process TMMBR and REMB first to avoid multiple callbacks
1322 // to OnNetworkChanged.
1323 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001324 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1325 UpdateTMMBR();
1326 }
sprang7dc39f32015-10-13 09:17:48 -07001327 uint32_t local_ssrc;
1328 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001329 {
1330 // We don't want to hold this critsect when triggering the callbacks below.
1331 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001332 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001333 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001334 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001335 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001336 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001337 _rtpRtcp.OnRequestSendReport();
1338 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001339 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001340 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001341 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001342 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001343 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001344 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001345 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001346 }
1347 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001348 // We need feedback that we have received a report block(s) so that we
1349 // can generate a new packet in a conference relay scenario, one received
1350 // report can generate several RTCP packets, based on number relayed/mixed
1351 // a send report block should go out to all receivers.
1352 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001353 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001354 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1355 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1356 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001357 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001358 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001359 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001360 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001361 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001362 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001363 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001364 }
1365 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1366 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001367 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001368 }
1369 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1370 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001371 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001372 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001373 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001374 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001375 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001376 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001377 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001378 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001379 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1380 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1381 }
Erik Språng242e22b2015-05-11 10:17:43 +02001382 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1383 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001384 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001385 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001386 rtcpPacketInformation.report_blocks,
1387 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001388 now);
1389 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001390 }
Erik Språng6b8d3552015-09-24 15:06:57 +02001391 if (_cbTransportFeedbackObserver &&
1392 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1393 uint32_t media_source_ssrc =
1394 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001395 if (media_source_ssrc == local_ssrc ||
1396 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001397 _cbTransportFeedbackObserver->OnTransportFeedback(
1398 *rtcpPacketInformation.transport_feedback_.get());
1399 }
1400 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001401 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001402
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001403 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001404 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1405 if (stats_callback_) {
1406 for (ReportBlockList::const_iterator it =
1407 rtcpPacketInformation.report_blocks.begin();
1408 it != rtcpPacketInformation.report_blocks.end();
1409 ++it) {
1410 RtcpStatistics stats;
1411 stats.cumulative_lost = it->cumulativeLost;
1412 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1413 stats.fraction_lost = it->fractionLost;
1414 stats.jitter = it->jitter;
1415
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001416 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001417 }
1418 }
1419 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001420}
1421
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001422int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001423 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001424 assert(cName);
1425
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001426 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1427 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001428 if (cnameInfo == NULL) {
1429 return -1;
1430 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001431 cName[RTCP_CNAME_SIZE - 1] = 0;
1432 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1433 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001434}
1435
1436// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001437int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1438 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001439 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001440 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001441
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001442 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001443 receiveInfoIt = _receivedInfoMap.begin();
1444 if (receiveInfoIt == _receivedInfoMap.end()) {
1445 return -1;
1446 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001447 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001448 if (candidateSet) {
1449 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1450 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1451 if (receiveInfo == NULL) {
1452 return 0;
1453 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001454 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001455 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001456 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001457 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001458 num++;
1459 }
1460 }
1461 receiveInfoIt++;
1462 }
1463 } else {
1464 while (receiveInfoIt != _receivedInfoMap.end()) {
1465 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1466 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001467 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001468 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001469 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001470 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001471 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001472 }
1473 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001474}
1475
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001476} // namespace webrtc