blob: 55974bf74bdef493491579a698ed4f8dec038149 [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"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000019#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
20#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
21#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +000022#include "webrtc/system_wrappers/interface/logging.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000023#include "webrtc/system_wrappers/interface/trace_event.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
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000032RTCPReceiver::RTCPReceiver(
33 int32_t id,
34 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020035 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000036 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000037 RtcpBandwidthObserver* rtcp_bandwidth_observer,
38 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000039 ModuleRtpRtcpImpl* owner)
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000040 : TMMBRHelp(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000041 _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020042 receiver_only_(receiver_only),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000043 _method(kRtcpOff),
44 _lastReceived(0),
45 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000046 _criticalSectionFeedbacks(
47 CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000048 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
49 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000050 _criticalSectionRTCPReceiver(
51 CriticalSectionWrapper::CreateCriticalSection()),
52 main_ssrc_(0),
53 _remoteSSRC(0),
54 _remoteSenderInfo(),
55 _lastReceivedSRNTPsecs(0),
56 _lastReceivedSRNTPfrac(0),
57 _lastReceivedXRNTPsecs(0),
58 _lastReceivedXRNTPfrac(0),
59 xr_rr_rtt_ms_(0),
60 _receivedInfoMap(),
61 _packetTimeOutMS(0),
62 _lastReceivedRrMs(0),
63 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000064 stats_callback_(NULL),
65 packet_type_counter_observer_(packet_type_counter_observer) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000066 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000067}
68
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000069RTCPReceiver::~RTCPReceiver() {
70 delete _criticalSectionRTCPReceiver;
71 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000072
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000073 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
74 for (; it != _receivedReportBlockMap.end(); ++it) {
75 ReportBlockInfoMap* info_map = &(it->second);
76 while (!info_map->empty()) {
77 ReportBlockInfoMap::iterator it_info = info_map->begin();
78 delete it_info->second;
79 info_map->erase(it_info);
80 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000081 }
82 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000083 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000084 _receivedInfoMap.begin();
85 delete first->second;
86 _receivedInfoMap.erase(first);
87 }
88 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000089 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000090 _receivedCnameMap.begin();
91 delete first->second;
92 _receivedCnameMap.erase(first);
93 }
niklase@google.com470e71d2011-07-07 08:21:25 +000094}
95
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000096RTCPMethod RTCPReceiver::Status() const {
97 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
98 return _method;
niklase@google.com470e71d2011-07-07 08:21:25 +000099}
100
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000101void RTCPReceiver::SetRTCPStatus(RTCPMethod method) {
102 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
103 _method = method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000104}
105
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000106int64_t RTCPReceiver::LastReceived() {
107 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
108 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000109}
110
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000111int64_t RTCPReceiver::LastReceivedReceiverReport() const {
112 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
113 int64_t last_received_rr = -1;
114 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
115 it != _receivedInfoMap.end(); ++it) {
116 if (it->second->lastTimeReceived > last_received_rr) {
117 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000118 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000119 }
120 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000121}
122
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000123void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
124 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000125
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000126 // new SSRC reset old reports
127 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
128 _lastReceivedSRNTPsecs = 0;
129 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000130
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000131 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000132}
133
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000134uint32_t RTCPReceiver::RemoteSSRC() const {
135 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
136 return _remoteSSRC;
137}
138
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000139void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
140 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000141 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000142 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000143 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000144 old_ssrc = main_ssrc_;
145 main_ssrc_ = main_ssrc;
146 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000147 }
148 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000149 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
150 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000151 }
152 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000153}
154
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000155int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000156 int64_t* RTT,
157 int64_t* avgRTT,
158 int64_t* minRTT,
159 int64_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000160 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000161
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000162 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000163 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000164
165 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000166 return -1;
167 }
168 if (RTT) {
169 *RTT = reportBlock->RTT;
170 }
171 if (avgRTT) {
172 *avgRTT = reportBlock->avgRTT;
173 }
174 if (minRTT) {
175 *minRTT = reportBlock->minRTT;
176 }
177 if (maxRTT) {
178 *maxRTT = reportBlock->maxRTT;
179 }
180 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000181}
182
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000183bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000184 assert(rtt_ms);
185 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
186 if (xr_rr_rtt_ms_ == 0) {
187 return false;
188 }
189 *rtt_ms = xr_rr_rtt_ms_;
190 xr_rr_rtt_ms_ = 0;
191 return true;
192}
193
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000194// TODO(pbos): Make this fail when we haven't received NTP.
195bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
196 uint32_t* ReceivedNTPfrac,
197 uint32_t* RTCPArrivalTimeSecs,
198 uint32_t* RTCPArrivalTimeFrac,
199 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000200{
201 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
202 if(ReceivedNTPsecs)
203 {
204 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
205 }
206 if(ReceivedNTPfrac)
207 {
208 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
209 }
210 if(RTCPArrivalTimeFrac)
211 {
212 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
213 }
214 if(RTCPArrivalTimeSecs)
215 {
216 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
217 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000218 if (rtcp_timestamp) {
219 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
220 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000221 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000222}
223
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000224bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
225 RtcpReceiveTimeInfo* info) const {
226 assert(info);
227 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
228 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
229 return false;
230 }
231
232 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
233 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
234
235 // Get the delay since last received report (RFC 3611).
236 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
237 _lastReceivedXRNTPfrac);
238
239 uint32_t ntp_sec = 0;
240 uint32_t ntp_frac = 0;
241 _clock->CurrentNtp(ntp_sec, ntp_frac);
242 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
243
244 info->delaySinceLastRR = now - receive_time;
245 return true;
246}
247
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000248int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
249 assert(senderInfo);
250 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
251 if (_lastReceivedSRNTPsecs == 0) {
252 return -1;
253 }
254 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
255 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000256}
257
258// statistics
259// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000260int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000261 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000262 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000263 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000264 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
265 for (; it != _receivedReportBlockMap.end(); ++it) {
266 const ReportBlockInfoMap* info_map = &(it->second);
267 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
268 for (; it_info != info_map->end(); ++it_info) {
269 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
270 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000271 }
272 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000273}
274
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000275int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000276RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
277 RTCPUtility::RTCPParserV2* rtcpParser)
278{
279 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
280
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000281 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000282
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000283 if (packet_type_counter_.first_packet_time_ms == -1) {
284 packet_type_counter_.first_packet_time_ms = _lastReceived;
285 }
286
niklase@google.com470e71d2011-07-07 08:21:25 +0000287 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200288 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000289 // Each "case" is responsible for iterate the parser to the
290 // next top level packet.
291 switch (pktType)
292 {
Erik Språng242e22b2015-05-11 10:17:43 +0200293 case RTCPPacketTypes::kSr:
294 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000295 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
296 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200297 case RTCPPacketTypes::kSdes:
niklase@google.com470e71d2011-07-07 08:21:25 +0000298 HandleSDES(*rtcpParser);
299 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200300 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000301 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
302 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200303 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000304 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
305 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200306 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000307 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
308 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200309 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000310 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
311 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200312 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000313 HandleBYE(*rtcpParser);
314 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200315 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000316 HandleNACK(*rtcpParser, rtcpPacketInformation);
317 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200318 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000319 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
320 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200321 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000322 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000323 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200324 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000325 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
326 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200327 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000328 HandlePLI(*rtcpParser, rtcpPacketInformation);
329 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200330 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 HandleSLI(*rtcpParser, rtcpPacketInformation);
332 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200333 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 HandleRPSI(*rtcpParser, rtcpPacketInformation);
335 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200336 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000337 HandleIJ(*rtcpParser, rtcpPacketInformation);
338 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200339 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 HandleFIR(*rtcpParser, rtcpPacketInformation);
341 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200342 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000343 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
344 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200345 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 // generic application messages
347 HandleAPP(*rtcpParser, rtcpPacketInformation);
348 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200349 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000350 // generic application messages
351 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
352 break;
353 default:
354 rtcpParser->Iterate();
355 break;
356 }
357 pktType = rtcpParser->PacketType();
358 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000359
360 if (packet_type_counter_observer_ != NULL) {
361 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
362 main_ssrc_, packet_type_counter_);
363 }
364
niklase@google.com470e71d2011-07-07 08:21:25 +0000365 return 0;
366}
367
368// no need for critsect we have _criticalSectionRTCPReceiver
369void
370RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
371 RTCPPacketInformation& rtcpPacketInformation)
372{
373 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
374 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
375
Erik Språng242e22b2015-05-11 10:17:43 +0200376 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
377 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000378
379 // SR.SenderSSRC
380 // The synchronization source identifier for the originator of this SR packet
381
382 // rtcpPacket.RR.SenderSSRC
383 // The source of the packet sender, same as of SR? or is this a CE?
384
Erik Språng242e22b2015-05-11 10:17:43 +0200385 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
386 ? rtcpPacket.RR.SenderSSRC
387 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000388
389 rtcpPacketInformation.remoteSSRC = remoteSSRC;
390
391 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
392 if (!ptrReceiveInfo)
393 {
394 rtcpParser.Iterate();
395 return;
396 }
397
Erik Språng242e22b2015-05-11 10:17:43 +0200398 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000399 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
400 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000401
niklase@google.com470e71d2011-07-07 08:21:25 +0000402 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
403 {
404 // only signal that we have received a SR when we accept one
405 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
406
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000407 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
408 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
409 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
410
niklase@google.com470e71d2011-07-07 08:21:25 +0000411 // We will only store the send report from one source, but
412 // we will store all the receive block
413
414 // Save the NTP time of this report
415 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
416 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
417 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
418 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
419 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
420
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000421 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000422 }
423 else
424 {
425 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
426 }
427 } else
428 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000429 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
430 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000431
432 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
433 }
434 UpdateReceiveInformation(*ptrReceiveInfo);
435
436 rtcpPacketType = rtcpParser.Iterate();
437
Erik Språng242e22b2015-05-11 10:17:43 +0200438 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000439 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000440 rtcpPacketType = rtcpParser.Iterate();
441 }
442}
443
444// no need for critsect we have _criticalSectionRTCPReceiver
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000445void RTCPReceiver::HandleReportBlock(
446 const RTCPUtility::RTCPPacket& rtcpPacket,
447 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000448 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000449 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000450 // This will be called once per report block in the RTCP packet.
451 // We filter out all report blocks that are not for us.
452 // Each packet has max 31 RR blocks.
453 //
454 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000455
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000456 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
457 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000458
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000459 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000460 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
461 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000462 // This block is not for us ignore it.
463 return;
464 }
465
466 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
467 // _criticalSectionRTCPReceiver.
468 _criticalSectionRTCPReceiver->Leave();
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000469 int64_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000470 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
471 _criticalSectionRTCPReceiver->Enter();
472
473 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000474 CreateOrGetReportBlockInformation(remoteSSRC,
475 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000476 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000477 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
478 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000479 return;
480 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000481
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000482 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000483 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
484 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
485 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
486 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
487 reportBlock->remoteReceiveBlock.cumulativeLost =
488 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000489 if (rb.ExtendedHighestSequenceNumber >
490 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
491 // We have successfully delivered new RTP packets to the remote side after
492 // the last RR was sent from the remote side.
493 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000494 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000495 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
496 rb.ExtendedHighestSequenceNumber;
497 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
498 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
499 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
500
501 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
502 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
503 }
504
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000505 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000506 rtcpPacket.ReportBlockItem.DelayLastSR;
507
508 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000509 uint32_t lastReceivedRRNTPsecs = 0;
510 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000511
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000512 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000513
514 // time when we received this in MS
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000515 int64_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
516 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000517
518 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000519 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000520 d /= 65536;
521 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
522
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000523 int64_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000524
525 if (sendTimeMS > 0) {
526 RTT = receiveTimeMS - d - sendTimeMS;
527 if (RTT <= 0) {
528 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000529 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000530 if (RTT > reportBlock->maxRTT) {
531 // store max RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000532 reportBlock->maxRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000533 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000534 if (reportBlock->minRTT == 0) {
535 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000536 reportBlock->minRTT = RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000537 } else if (RTT < reportBlock->minRTT) {
538 // Store min RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000539 reportBlock->minRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000540 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000541 // store last RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000542 reportBlock->RTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000543
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000544 // store average RTT
545 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000546 float ac = static_cast<float>(reportBlock->numAverageCalcs);
547 float newAverage =
548 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * RTT);
549 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000550 } else {
551 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000552 reportBlock->avgRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000553 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000554 reportBlock->numAverageCalcs++;
555 }
556
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000557 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
558 RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000559
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000560 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000561}
562
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000563RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
564 uint32_t remote_ssrc,
565 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000566 RTCPReportBlockInformation* info =
567 GetReportBlockInformation(remote_ssrc, source_ssrc);
568 if (info == NULL) {
569 info = new RTCPReportBlockInformation;
570 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000571 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000572 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000573}
574
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000575RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
576 uint32_t remote_ssrc,
577 uint32_t source_ssrc) const {
578 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000579 if (it == _receivedReportBlockMap.end()) {
580 return NULL;
581 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000582 const ReportBlockInfoMap* info_map = &(it->second);
583 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
584 if (it_info == info_map->end()) {
585 return NULL;
586 }
587 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000588}
589
590RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000591RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000592 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000593
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000594 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000595 _receivedCnameMap.find(remoteSSRC);
596
597 if (it != _receivedCnameMap.end()) {
598 return it->second;
599 }
600 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000601 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000602 _receivedCnameMap[remoteSSRC] = cnameInfo;
603 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000604}
605
606RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000607RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000608 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000609
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000610 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000611 _receivedCnameMap.find(remoteSSRC);
612
613 if (it == _receivedCnameMap.end()) {
614 return NULL;
615 }
616 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000617}
618
619RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000620RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000621 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000622
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000623 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000624 _receivedInfoMap.find(remoteSSRC);
625
626 if (it != _receivedInfoMap.end()) {
627 return it->second;
628 }
629 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
630 _receivedInfoMap[remoteSSRC] = receiveInfo;
631 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000632}
633
634RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000635RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000636 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000637
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000638 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000639 _receivedInfoMap.find(remoteSSRC);
640 if (it == _receivedInfoMap.end()) {
641 return NULL;
642 }
643 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000644}
645
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000646void RTCPReceiver::UpdateReceiveInformation(
647 RTCPReceiveInformation& receiveInformation) {
648 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000649 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000650}
651
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000652bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
653 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
654 if (_lastReceivedRrMs == 0)
655 return false;
656
657 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000658 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000659 // Reset the timer to only trigger one log.
660 _lastReceivedRrMs = 0;
661 return true;
662 }
663 return false;
664}
665
666bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
667 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
668 if (_lastIncreasedSequenceNumberMs == 0)
669 return false;
670
671 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000672 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000673 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000674 // Reset the timer to only trigger one log.
675 _lastIncreasedSequenceNumberMs = 0;
676 return true;
677 }
678 return false;
679}
680
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000681bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
682 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000683
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000684 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000685 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000686
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000687 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000688 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000689
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000690 while (receiveInfoIt != _receivedInfoMap.end()) {
691 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
692 if (receiveInfo == NULL) {
693 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000694 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000695 // time since last received rtcp packet
696 // when we dont have a lastTimeReceived and the object is marked
697 // readyForDelete it's removed from the map
698 if (receiveInfo->lastTimeReceived) {
699 /// use audio define since we don't know what interval the remote peer is
700 // using
701 if ((timeNow - receiveInfo->lastTimeReceived) >
702 5 * RTCP_INTERVAL_AUDIO_MS) {
703 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000704 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000705 // prevent that we call this over and over again
706 receiveInfo->lastTimeReceived = 0;
707 // send new TMMBN to all channels using the default codec
708 updateBoundingSet = true;
709 }
710 receiveInfoIt++;
711 } else if (receiveInfo->readyForDelete) {
712 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000713 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000714 receiveInfoItemToBeErased = receiveInfoIt;
715 receiveInfoIt++;
716 delete receiveInfoItemToBeErased->second;
717 _receivedInfoMap.erase(receiveInfoItemToBeErased);
718 } else {
719 receiveInfoIt++;
720 }
721 }
722 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000723}
724
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000725int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000726 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000727
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000728 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000729 _receivedInfoMap.find(_remoteSSRC);
730
731 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000732 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000733 }
734 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
735 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000736 return -1;
737 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000738 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000739 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000740 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000741 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000742 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000743 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000744 // owner of bounding set
745 tmmbrOwner = true;
746 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000747 boundingSetRec->SetEntry(i,
748 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
749 receiveInfo->TmmbnBoundingSet.PacketOH(i),
750 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000751 }
752 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000753 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000754}
755
756// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000757void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser) {
758 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200759 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000760 HandleSDESChunk(rtcpParser);
761 pktType = rtcpParser.Iterate();
762 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000763}
764
765// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000766void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
767 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
768 RTCPCnameInformation* cnameInfo =
769 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
770 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000771
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000772 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
773 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000774 {
775 CriticalSectionScoped lock(_criticalSectionFeedbacks);
776 if (stats_callback_ != NULL) {
777 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
778 rtcpPacket.CName.SenderSSRC);
779 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000780 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000781}
782
783// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000784void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
785 RTCPPacketInformation& rtcpPacketInformation) {
786 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200787 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000788 // Not to us.
789 rtcpParser.Iterate();
790 return;
791 }
792 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000793
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000794 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200795 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000796 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
797 pktType = rtcpParser.Iterate();
798 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000799
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000800 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
801 ++packet_type_counter_.nack_packets;
802 packet_type_counter_.nack_requests = nack_stats_.requests();
803 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
804 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000805}
806
807// no need for critsect we have _criticalSectionRTCPReceiver
808void
809RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000810 RTCPPacketInformation& rtcpPacketInformation) {
811 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
812 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000813
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000814 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
815 if (bitMask) {
816 for (int i=1; i <= 16; ++i) {
817 if (bitMask & 0x01) {
818 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
819 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
820 }
821 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000822 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000823 }
824 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000825}
826
827// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000828void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
829 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000830
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000831 // clear our lists
832 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000833 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
834 for (; it != _receivedReportBlockMap.end(); ++it) {
835 ReportBlockInfoMap* info_map = &(it->second);
836 ReportBlockInfoMap::iterator it_info = info_map->find(
837 rtcpPacket.BYE.SenderSSRC);
838 if (it_info != info_map->end()) {
839 delete it_info->second;
840 info_map->erase(it_info);
841 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000842 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000843
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000844 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000845 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000846 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000847
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000848 if (receiveInfoIt != _receivedInfoMap.end()) {
849 receiveInfoIt->second->readyForDelete = true;
850 }
851
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000852 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000853 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
854
855 if (cnameInfoIt != _receivedCnameMap.end()) {
856 delete cnameInfoIt->second;
857 _receivedCnameMap.erase(cnameInfoIt);
858 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000859 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000860 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000861}
862
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000863void RTCPReceiver::HandleXrHeader(
864 RTCPUtility::RTCPParserV2& parser,
865 RTCPPacketInformation& rtcpPacketInformation) {
866 const RTCPUtility::RTCPPacket& packet = parser.Packet();
867
868 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
869
870 parser.Iterate();
871}
872
873void RTCPReceiver::HandleXrReceiveReferenceTime(
874 RTCPUtility::RTCPParserV2& parser,
875 RTCPPacketInformation& rtcpPacketInformation) {
876 const RTCPUtility::RTCPPacket& packet = parser.Packet();
877
878 _remoteXRReceiveTimeInfo.sourceSSRC =
879 rtcpPacketInformation.xr_originator_ssrc;
880
881 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
882 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
883 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
884
885 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
886
887 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
888
889 parser.Iterate();
890}
891
892void RTCPReceiver::HandleXrDlrrReportBlock(
893 RTCPUtility::RTCPParserV2& parser,
894 RTCPPacketInformation& rtcpPacketInformation) {
895 const RTCPUtility::RTCPPacket& packet = parser.Packet();
896 // Iterate through sub-block(s), if any.
897 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
898
Erik Språng242e22b2015-05-11 10:17:43 +0200899 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000900 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
901 packet_type = parser.Iterate();
902 }
903}
904
905void RTCPReceiver::HandleXrDlrrReportBlockItem(
906 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000907 RTCPPacketInformation& rtcpPacketInformation)
908 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000909 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
910 registered_ssrcs_.end()) {
911 // Not to us.
912 return;
913 }
914
915 rtcpPacketInformation.xr_dlrr_item = true;
916
917 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
918 // _criticalSectionRTCPReceiver.
919 _criticalSectionRTCPReceiver->Leave();
920
921 int64_t send_time_ms;
922 bool found = _rtpRtcp.SendTimeOfXrRrReport(
923 packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
924
925 _criticalSectionRTCPReceiver->Enter();
926
927 if (!found) {
928 return;
929 }
930
931 // The DelayLastRR field is in units of 1/65536 sec.
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000932 uint32_t delay_rr_ms =
933 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
934 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000935
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000936 int64_t rtt = _clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000937
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000938 xr_rr_rtt_ms_ = std::max<int64_t>(rtt, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000939
940 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
941}
942
niklase@google.com470e71d2011-07-07 08:21:25 +0000943// no need for critsect we have _criticalSectionRTCPReceiver
944void
945RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
946 RTCPPacketInformation& rtcpPacketInformation)
947{
948 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
949
950 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
951
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000952 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000953 {
954 // Store VoIP metrics block if it's about me
955 // from OriginatorSSRC do we filter it?
956 // rtcpPacket.XR.OriginatorSSRC;
957
958 RTCPVoIPMetric receivedVoIPMetrics;
959 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
960 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
961 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
962 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
963 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
964 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
965 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
966 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
967 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
968 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
969 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
970 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
971 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
972 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
973 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
974 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
975 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
976 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
977 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
978 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
979
980 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
981
982 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
983 }
984 rtcpParser.Iterate();
985}
986
987// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000988void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
989 RTCPPacketInformation& rtcpPacketInformation) {
990 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000991 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000992 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000993
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000994 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000995 // Received a signal that we need to send a new key frame.
996 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
997 }
998 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000999}
1000
1001// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001002void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
1003 RTCPPacketInformation& rtcpPacketInformation) {
1004 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001005
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001006 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
1007 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
1008 if (ptrReceiveInfo == NULL) {
1009 // This remote SSRC must be saved before.
1010 rtcpParser.Iterate();
1011 return;
1012 }
1013 if (rtcpPacket.TMMBR.MediaSSRC) {
1014 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1015 // in relay mode this is a valid number
1016 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1017 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001018
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001019 // Use packet length to calc max number of TMMBR blocks
1020 // each TMMBR block is 8 bytes
1021 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001022
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001023 // sanity, we can't have more than what's in one packet
1024 if (maxNumOfTMMBRBlocks > 200) {
1025 assert(false);
1026 rtcpParser.Iterate();
1027 return;
1028 }
1029 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001030
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001031 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001032 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001033 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1034 pktType = rtcpParser.Iterate();
1035 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001036}
1037
1038// no need for critsect we have _criticalSectionRTCPReceiver
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001039void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1040 const RTCPUtility::RTCPPacket& rtcpPacket,
1041 RTCPPacketInformation& rtcpPacketInformation,
1042 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001043 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1044 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1045 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1046 _clock->TimeInMilliseconds());
1047 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1048 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001049}
1050
1051// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001052void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1053 RTCPPacketInformation& rtcpPacketInformation) {
1054 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1055 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1056 rtcpPacket.TMMBN.SenderSSRC);
1057 if (ptrReceiveInfo == NULL) {
1058 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001059 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001060 return;
1061 }
1062 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1063 // Use packet length to calc max number of TMMBN blocks
1064 // each TMMBN block is 8 bytes
1065 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1066
1067 // sanity, we cant have more than what's in one packet
1068 if (maxNumOfTMMBNBlocks > 200) {
1069 assert(false);
1070 rtcpParser.Iterate();
1071 return;
1072 }
1073
1074 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1075
1076 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001077 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001078 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1079 pktType = rtcpParser.Iterate();
1080 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001081}
1082
1083// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001084void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1085 RTCPPacketInformation& rtcpPacketInformation) {
1086 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1087 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001088}
1089
1090// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001091void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1092 const RTCPUtility::RTCPPacket& rtcpPacket) {
1093 receiveInfo.TmmbnBoundingSet.AddEntry(
1094 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1095 rtcpPacket.TMMBNItem.MeasuredOverhead,
1096 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001097}
1098
1099// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001100void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1101 RTCPPacketInformation& rtcpPacketInformation) {
1102 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1103 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001104 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001105 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1106 pktType = rtcpParser.Iterate();
1107 }
1108}
1109
1110// no need for critsect we have _criticalSectionRTCPReceiver
1111void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1112 RTCPPacketInformation& rtcpPacketInformation) {
1113 // in theory there could be multiple slices lost
1114 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1115 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001116}
1117
1118void
1119RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1120 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1121{
1122 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001123 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001124 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001125 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1126 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1127 {
1128 // to us unknown
1129 // continue
1130 rtcpParser.Iterate();
1131 return;
1132 }
1133 rtcpPacketInformation.rpsiPictureId = 0;
1134
1135 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001136 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1137 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001138 {
1139 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1140 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1141 }
1142 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1143 }
1144}
1145
1146// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001147void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1148 RTCPPacketInformation& rtcpPacketInformation) {
1149 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001150 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001151 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001152 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001153 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1154 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001155 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001156 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001157}
1158
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001159// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001160void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1161 RTCPPacketInformation& rtcpPacketInformation) {
1162 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001163
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001164 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001165 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001166 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1167 pktType = rtcpParser.Iterate();
1168 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001169}
1170
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001171void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1172 RTCPPacketInformation& rtcpPacketInformation) {
1173 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1174 rtcpPacketInformation.interArrivalJitter =
1175 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001176}
1177
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001178void RTCPReceiver::HandleREMBItem(
1179 RTCPUtility::RTCPParserV2& rtcpParser,
1180 RTCPPacketInformation& rtcpPacketInformation) {
1181 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1182 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1183 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1184 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001185}
1186
1187// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001188void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1189 RTCPPacketInformation& rtcpPacketInformation) {
1190 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1191 RTCPReceiveInformation* ptrReceiveInfo =
1192 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001193
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001194 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001195 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001196 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1197 pktType = rtcpParser.Iterate();
1198 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001199}
1200
1201// no need for critsect we have _criticalSectionRTCPReceiver
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
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001254int32_t RTCPReceiver::UpdateTMMBR() {
1255 int32_t numBoundingSet = 0;
1256 uint32_t bitrate = 0;
1257 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001258
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001259 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001260 if (size > 0) {
1261 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1262 // Get candidate set from receiver.
1263 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1264 } else {
1265 // Candidate set empty.
1266 VerifyAndAllocateCandidateSet(0); // resets candidate set
1267 }
1268 // Find bounding set
1269 TMMBRSet* boundingSet = NULL;
1270 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1271 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001272 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001273 return -1;
1274 }
1275 // Set bounding set
1276 // Inform remote clients about the new bandwidth
1277 // inform the remote client
1278 _rtpRtcp.SetTMMBN(boundingSet);
1279
1280 // might trigger a TMMBN
1281 if (numBoundingSet == 0) {
1282 // owner of max bitrate request has timed out
1283 // empty bounding set has been sent
1284 return 0;
1285 }
1286 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001287 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001288 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001289 if (_cbRtcpBandwidthObserver) {
1290 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001291 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001292 }
1293 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001294}
1295
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001296void RTCPReceiver::RegisterRtcpStatisticsCallback(
1297 RtcpStatisticsCallback* callback) {
1298 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001299 stats_callback_ = callback;
1300}
1301
1302RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1303 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1304 return stats_callback_;
1305}
1306
niklase@google.com470e71d2011-07-07 08:21:25 +00001307// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001308void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001309 RTCPPacketInformation& rtcpPacketInformation) {
1310 // Process TMMBR and REMB first to avoid multiple callbacks
1311 // to OnNetworkChanged.
1312 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001313 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1314 UpdateTMMBR();
1315 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001316 unsigned int local_ssrc;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001317 {
1318 // We don't want to hold this critsect when triggering the callbacks below.
1319 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001320 local_ssrc = main_ssrc_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001321 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001322 if (!receiver_only_ &&
1323 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001324 _rtpRtcp.OnRequestSendReport();
1325 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001326 if (!receiver_only_ &&
1327 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001328 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001329 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001330 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001331 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001332 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001333 }
1334 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001335 // We need feedback that we have received a report block(s) so that we
1336 // can generate a new packet in a conference relay scenario, one received
1337 // report can generate several RTCP packets, based on number relayed/mixed
1338 // a send report block should go out to all receivers.
1339 if (_cbRtcpIntraFrameObserver) {
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001340 DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001341 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1342 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1343 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001344 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001345 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001346 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001347 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001348 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001349 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001350 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001351 }
1352 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1353 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001354 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001355 }
1356 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1357 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001358 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001359 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001360 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001361 if (_cbRtcpBandwidthObserver) {
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001362 DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001363 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001364 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001365 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001366 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1367 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1368 }
Erik Språng242e22b2015-05-11 10:17:43 +02001369 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1370 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001371 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001372 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001373 rtcpPacketInformation.report_blocks,
1374 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001375 now);
1376 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001377 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001378 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001379
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001380 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001381 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1382 if (stats_callback_) {
1383 for (ReportBlockList::const_iterator it =
1384 rtcpPacketInformation.report_blocks.begin();
1385 it != rtcpPacketInformation.report_blocks.end();
1386 ++it) {
1387 RtcpStatistics stats;
1388 stats.cumulative_lost = it->cumulativeLost;
1389 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1390 stats.fraction_lost = it->fractionLost;
1391 stats.jitter = it->jitter;
1392
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001393 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001394 }
1395 }
1396 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001397}
1398
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001399int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001400 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001401 assert(cName);
1402
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001403 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1404 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001405 if (cnameInfo == NULL) {
1406 return -1;
1407 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001408 cName[RTCP_CNAME_SIZE - 1] = 0;
1409 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1410 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001411}
1412
1413// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001414int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1415 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001416 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001417 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001418
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001419 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001420 receiveInfoIt = _receivedInfoMap.begin();
1421 if (receiveInfoIt == _receivedInfoMap.end()) {
1422 return -1;
1423 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001424 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001425 if (candidateSet) {
1426 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1427 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1428 if (receiveInfo == NULL) {
1429 return 0;
1430 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001431 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001432 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001433 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001434 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001435 num++;
1436 }
1437 }
1438 receiveInfoIt++;
1439 }
1440 } else {
1441 while (receiveInfoIt != _receivedInfoMap.end()) {
1442 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1443 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001444 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001445 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001446 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001447 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001448 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001449 }
1450 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001451}
1452
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001453} // namespace webrtc