blob: 4392f52e6a4daf53f85deba4bffdee12f04a8df3 [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(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000033 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020034 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000035 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000036 RtcpBandwidthObserver* rtcp_bandwidth_observer,
37 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000038 ModuleRtpRtcpImpl* owner)
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000039 : TMMBRHelp(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000040 _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020041 receiver_only_(receiver_only),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000042 _method(kRtcpOff),
43 _lastReceived(0),
44 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000045 _criticalSectionFeedbacks(
46 CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000047 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
48 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000049 _criticalSectionRTCPReceiver(
50 CriticalSectionWrapper::CreateCriticalSection()),
51 main_ssrc_(0),
52 _remoteSSRC(0),
53 _remoteSenderInfo(),
54 _lastReceivedSRNTPsecs(0),
55 _lastReceivedSRNTPfrac(0),
56 _lastReceivedXRNTPsecs(0),
57 _lastReceivedXRNTPfrac(0),
58 xr_rr_rtt_ms_(0),
59 _receivedInfoMap(),
60 _packetTimeOutMS(0),
61 _lastReceivedRrMs(0),
62 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000063 stats_callback_(NULL),
Erik Språngc9bbeb02015-09-23 13:51:47 +020064 packet_type_counter_observer_(packet_type_counter_observer) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000065 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000066}
67
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000068RTCPReceiver::~RTCPReceiver() {
69 delete _criticalSectionRTCPReceiver;
70 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000071
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000072 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
73 for (; it != _receivedReportBlockMap.end(); ++it) {
74 ReportBlockInfoMap* info_map = &(it->second);
75 while (!info_map->empty()) {
76 ReportBlockInfoMap::iterator it_info = info_map->begin();
77 delete it_info->second;
78 info_map->erase(it_info);
79 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000080 }
81 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000082 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000083 _receivedInfoMap.begin();
84 delete first->second;
85 _receivedInfoMap.erase(first);
86 }
87 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000088 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000089 _receivedCnameMap.begin();
90 delete first->second;
91 _receivedCnameMap.erase(first);
92 }
niklase@google.com470e71d2011-07-07 08:21:25 +000093}
94
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000095RTCPMethod RTCPReceiver::Status() const {
96 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
97 return _method;
niklase@google.com470e71d2011-07-07 08:21:25 +000098}
99
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000100void RTCPReceiver::SetRTCPStatus(RTCPMethod method) {
101 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
102 _method = method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000103}
104
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000105int64_t RTCPReceiver::LastReceived() {
106 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
107 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000108}
109
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000110int64_t RTCPReceiver::LastReceivedReceiverReport() const {
111 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
112 int64_t last_received_rr = -1;
113 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
114 it != _receivedInfoMap.end(); ++it) {
115 if (it->second->lastTimeReceived > last_received_rr) {
116 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000117 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000118 }
119 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000120}
121
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000122void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
123 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000124
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000125 // new SSRC reset old reports
126 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
127 _lastReceivedSRNTPsecs = 0;
128 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000129
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000130 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000131}
132
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000133uint32_t RTCPReceiver::RemoteSSRC() const {
134 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
135 return _remoteSSRC;
136}
137
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000138void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
139 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000140 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000141 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000142 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000143 old_ssrc = main_ssrc_;
144 main_ssrc_ = main_ssrc;
145 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000146 }
147 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000148 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
149 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000150 }
151 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000152}
153
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000154int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000155 int64_t* RTT,
156 int64_t* avgRTT,
157 int64_t* minRTT,
158 int64_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000159 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000160
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000161 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000162 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000163
164 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000165 return -1;
166 }
167 if (RTT) {
168 *RTT = reportBlock->RTT;
169 }
170 if (avgRTT) {
171 *avgRTT = reportBlock->avgRTT;
172 }
173 if (minRTT) {
174 *minRTT = reportBlock->minRTT;
175 }
176 if (maxRTT) {
177 *maxRTT = reportBlock->maxRTT;
178 }
179 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000180}
181
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000182bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000183 assert(rtt_ms);
184 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
185 if (xr_rr_rtt_ms_ == 0) {
186 return false;
187 }
188 *rtt_ms = xr_rr_rtt_ms_;
189 xr_rr_rtt_ms_ = 0;
190 return true;
191}
192
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000193// TODO(pbos): Make this fail when we haven't received NTP.
194bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
195 uint32_t* ReceivedNTPfrac,
196 uint32_t* RTCPArrivalTimeSecs,
197 uint32_t* RTCPArrivalTimeFrac,
198 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000199{
200 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
201 if(ReceivedNTPsecs)
202 {
203 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
204 }
205 if(ReceivedNTPfrac)
206 {
207 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
208 }
209 if(RTCPArrivalTimeFrac)
210 {
211 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
212 }
213 if(RTCPArrivalTimeSecs)
214 {
215 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
216 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000217 if (rtcp_timestamp) {
218 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
219 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000220 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000221}
222
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000223bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
224 RtcpReceiveTimeInfo* info) const {
225 assert(info);
226 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
227 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
228 return false;
229 }
230
231 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
232 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
233
234 // Get the delay since last received report (RFC 3611).
235 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
236 _lastReceivedXRNTPfrac);
237
238 uint32_t ntp_sec = 0;
239 uint32_t ntp_frac = 0;
240 _clock->CurrentNtp(ntp_sec, ntp_frac);
241 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
242
243 info->delaySinceLastRR = now - receive_time;
244 return true;
245}
246
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000247int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
248 assert(senderInfo);
249 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
250 if (_lastReceivedSRNTPsecs == 0) {
251 return -1;
252 }
253 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
254 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000255}
256
257// statistics
258// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000259int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000260 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000261 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000262 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000263 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
264 for (; it != _receivedReportBlockMap.end(); ++it) {
265 const ReportBlockInfoMap* info_map = &(it->second);
266 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
267 for (; it_info != info_map->end(); ++it_info) {
268 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
269 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000270 }
271 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000272}
273
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000274int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000275RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
276 RTCPUtility::RTCPParserV2* rtcpParser)
277{
278 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
279
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000280 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000281
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000282 if (packet_type_counter_.first_packet_time_ms == -1) {
283 packet_type_counter_.first_packet_time_ms = _lastReceived;
284 }
285
niklase@google.com470e71d2011-07-07 08:21:25 +0000286 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200287 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000288 // Each "case" is responsible for iterate the parser to the
289 // next top level packet.
290 switch (pktType)
291 {
Erik Språng242e22b2015-05-11 10:17:43 +0200292 case RTCPPacketTypes::kSr:
293 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000294 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
295 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200296 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200297 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000298 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200299 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000300 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
301 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200302 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000303 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
304 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200305 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000306 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
307 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200308 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000309 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
310 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200311 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000312 HandleBYE(*rtcpParser);
313 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200314 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000315 HandleNACK(*rtcpParser, rtcpPacketInformation);
316 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200317 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000318 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
319 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200320 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000321 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000322 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200323 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000324 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
325 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200326 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000327 HandlePLI(*rtcpParser, rtcpPacketInformation);
328 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200329 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000330 HandleSLI(*rtcpParser, rtcpPacketInformation);
331 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200332 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000333 HandleRPSI(*rtcpParser, rtcpPacketInformation);
334 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200335 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000336 HandleIJ(*rtcpParser, rtcpPacketInformation);
337 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200338 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000339 HandleFIR(*rtcpParser, rtcpPacketInformation);
340 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200341 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000342 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
343 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200344 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000345 // generic application messages
346 HandleAPP(*rtcpParser, rtcpPacketInformation);
347 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200348 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000349 // generic application messages
350 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
351 break;
352 default:
353 rtcpParser->Iterate();
354 break;
355 }
356 pktType = rtcpParser->PacketType();
357 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000358
359 if (packet_type_counter_observer_ != NULL) {
360 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
361 main_ssrc_, packet_type_counter_);
362 }
363
niklase@google.com470e71d2011-07-07 08:21:25 +0000364 return 0;
365}
366
367// no need for critsect we have _criticalSectionRTCPReceiver
368void
369RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
370 RTCPPacketInformation& rtcpPacketInformation)
371{
372 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
373 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
374
Erik Språng242e22b2015-05-11 10:17:43 +0200375 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
376 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000377
378 // SR.SenderSSRC
379 // The synchronization source identifier for the originator of this SR packet
380
381 // rtcpPacket.RR.SenderSSRC
382 // The source of the packet sender, same as of SR? or is this a CE?
383
Erik Språng242e22b2015-05-11 10:17:43 +0200384 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
385 ? rtcpPacket.RR.SenderSSRC
386 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000387
388 rtcpPacketInformation.remoteSSRC = remoteSSRC;
389
390 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
391 if (!ptrReceiveInfo)
392 {
393 rtcpParser.Iterate();
394 return;
395 }
396
Erik Språng242e22b2015-05-11 10:17:43 +0200397 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000398 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
399 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000400
niklase@google.com470e71d2011-07-07 08:21:25 +0000401 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
402 {
403 // only signal that we have received a SR when we accept one
404 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
405
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000406 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
407 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
408 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
409
niklase@google.com470e71d2011-07-07 08:21:25 +0000410 // We will only store the send report from one source, but
411 // we will store all the receive block
412
413 // Save the NTP time of this report
414 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
415 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
416 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
417 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
418 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
419
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000420 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000421 }
422 else
423 {
424 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
425 }
426 } else
427 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000428 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
429 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000430
431 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
432 }
433 UpdateReceiveInformation(*ptrReceiveInfo);
434
435 rtcpPacketType = rtcpParser.Iterate();
436
Erik Språng242e22b2015-05-11 10:17:43 +0200437 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000438 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000439 rtcpPacketType = rtcpParser.Iterate();
440 }
441}
442
443// no need for critsect we have _criticalSectionRTCPReceiver
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000444void RTCPReceiver::HandleReportBlock(
445 const RTCPUtility::RTCPPacket& rtcpPacket,
446 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000447 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000448 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000449 // This will be called once per report block in the RTCP packet.
450 // We filter out all report blocks that are not for us.
451 // Each packet has max 31 RR blocks.
452 //
453 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000454
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000455 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
456 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000457
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000458 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000459 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
460 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000461 // This block is not for us ignore it.
462 return;
463 }
464
465 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
466 // _criticalSectionRTCPReceiver.
467 _criticalSectionRTCPReceiver->Leave();
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000468 int64_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000469 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
470 _criticalSectionRTCPReceiver->Enter();
471
472 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000473 CreateOrGetReportBlockInformation(remoteSSRC,
474 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000475 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000476 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
477 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000478 return;
479 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000480
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000481 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000482 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
483 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
484 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
485 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
486 reportBlock->remoteReceiveBlock.cumulativeLost =
487 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000488 if (rb.ExtendedHighestSequenceNumber >
489 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
490 // We have successfully delivered new RTP packets to the remote side after
491 // the last RR was sent from the remote side.
492 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000493 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000494 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
495 rb.ExtendedHighestSequenceNumber;
496 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
497 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
498 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
499
500 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
501 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
502 }
503
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000504 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000505 rtcpPacket.ReportBlockItem.DelayLastSR;
506
507 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000508 uint32_t lastReceivedRRNTPsecs = 0;
509 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000510
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000511 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000512
513 // time when we received this in MS
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000514 int64_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
515 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000516
517 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000518 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000519 d /= 65536;
520 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
521
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000522 int64_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000523
524 if (sendTimeMS > 0) {
525 RTT = receiveTimeMS - d - sendTimeMS;
526 if (RTT <= 0) {
527 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000528 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000529 if (RTT > reportBlock->maxRTT) {
530 // store max RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000531 reportBlock->maxRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000532 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000533 if (reportBlock->minRTT == 0) {
534 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000535 reportBlock->minRTT = RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000536 } else if (RTT < reportBlock->minRTT) {
537 // Store min RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000538 reportBlock->minRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000539 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000540 // store last RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000541 reportBlock->RTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000542
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000543 // store average RTT
544 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000545 float ac = static_cast<float>(reportBlock->numAverageCalcs);
546 float newAverage =
547 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * RTT);
548 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000549 } else {
550 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000551 reportBlock->avgRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000552 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000553 reportBlock->numAverageCalcs++;
554 }
555
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000556 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
557 RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000558
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000559 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000560}
561
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000562RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
563 uint32_t remote_ssrc,
564 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000565 RTCPReportBlockInformation* info =
566 GetReportBlockInformation(remote_ssrc, source_ssrc);
567 if (info == NULL) {
568 info = new RTCPReportBlockInformation;
569 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000570 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000571 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000572}
573
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000574RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
575 uint32_t remote_ssrc,
576 uint32_t source_ssrc) const {
577 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000578 if (it == _receivedReportBlockMap.end()) {
579 return NULL;
580 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000581 const ReportBlockInfoMap* info_map = &(it->second);
582 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
583 if (it_info == info_map->end()) {
584 return NULL;
585 }
586 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000587}
588
589RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000590RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000591 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000592
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000593 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000594 _receivedCnameMap.find(remoteSSRC);
595
596 if (it != _receivedCnameMap.end()) {
597 return it->second;
598 }
599 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000600 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000601 _receivedCnameMap[remoteSSRC] = cnameInfo;
602 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000603}
604
605RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000606RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000607 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000608
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000609 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000610 _receivedCnameMap.find(remoteSSRC);
611
612 if (it == _receivedCnameMap.end()) {
613 return NULL;
614 }
615 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000616}
617
618RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000619RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000620 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000621
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000622 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000623 _receivedInfoMap.find(remoteSSRC);
624
625 if (it != _receivedInfoMap.end()) {
626 return it->second;
627 }
628 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
629 _receivedInfoMap[remoteSSRC] = receiveInfo;
630 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000631}
632
633RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000634RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000635 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000636
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000637 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000638 _receivedInfoMap.find(remoteSSRC);
639 if (it == _receivedInfoMap.end()) {
640 return NULL;
641 }
642 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000643}
644
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000645void RTCPReceiver::UpdateReceiveInformation(
646 RTCPReceiveInformation& receiveInformation) {
647 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000648 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000649}
650
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000651bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
652 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
653 if (_lastReceivedRrMs == 0)
654 return false;
655
656 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000657 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000658 // Reset the timer to only trigger one log.
659 _lastReceivedRrMs = 0;
660 return true;
661 }
662 return false;
663}
664
665bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
666 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
667 if (_lastIncreasedSequenceNumberMs == 0)
668 return false;
669
670 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000671 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000672 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000673 // Reset the timer to only trigger one log.
674 _lastIncreasedSequenceNumberMs = 0;
675 return true;
676 }
677 return false;
678}
679
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000680bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
681 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000682
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000683 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000684 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000685
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000686 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000687 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000688
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000689 while (receiveInfoIt != _receivedInfoMap.end()) {
690 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
691 if (receiveInfo == NULL) {
692 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000693 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000694 // time since last received rtcp packet
695 // when we dont have a lastTimeReceived and the object is marked
696 // readyForDelete it's removed from the map
697 if (receiveInfo->lastTimeReceived) {
698 /// use audio define since we don't know what interval the remote peer is
699 // using
700 if ((timeNow - receiveInfo->lastTimeReceived) >
701 5 * RTCP_INTERVAL_AUDIO_MS) {
702 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000703 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000704 // prevent that we call this over and over again
705 receiveInfo->lastTimeReceived = 0;
706 // send new TMMBN to all channels using the default codec
707 updateBoundingSet = true;
708 }
709 receiveInfoIt++;
710 } else if (receiveInfo->readyForDelete) {
711 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000712 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000713 receiveInfoItemToBeErased = receiveInfoIt;
714 receiveInfoIt++;
715 delete receiveInfoItemToBeErased->second;
716 _receivedInfoMap.erase(receiveInfoItemToBeErased);
717 } else {
718 receiveInfoIt++;
719 }
720 }
721 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000722}
723
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000724int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000725 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000726
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000727 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000728 _receivedInfoMap.find(_remoteSSRC);
729
730 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000731 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000732 }
733 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
734 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000735 return -1;
736 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000737 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000738 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000739 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000740 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000741 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000742 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000743 // owner of bounding set
744 tmmbrOwner = true;
745 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000746 boundingSetRec->SetEntry(i,
747 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
748 receiveInfo->TmmbnBoundingSet.PacketOH(i),
749 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000750 }
751 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000752 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000753}
754
755// no need for critsect we have _criticalSectionRTCPReceiver
Erik Språnga38233a2015-07-24 09:58:18 +0200756void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
757 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000758 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 }
Erik Språnga38233a2015-07-24 09:58:18 +0200763 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000764}
765
766// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000767void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
768 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
769 RTCPCnameInformation* cnameInfo =
770 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
771 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000772
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000773 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
774 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000775 {
776 CriticalSectionScoped lock(_criticalSectionFeedbacks);
777 if (stats_callback_ != NULL) {
778 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
779 rtcpPacket.CName.SenderSSRC);
780 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000781 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000782}
783
784// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000785void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
786 RTCPPacketInformation& rtcpPacketInformation) {
787 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200788 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000789 // Not to us.
790 rtcpParser.Iterate();
791 return;
792 }
793 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000794
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000795 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200796 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000797 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
798 pktType = rtcpParser.Iterate();
799 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000800
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000801 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
802 ++packet_type_counter_.nack_packets;
803 packet_type_counter_.nack_requests = nack_stats_.requests();
804 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
805 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000806}
807
808// no need for critsect we have _criticalSectionRTCPReceiver
809void
810RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000811 RTCPPacketInformation& rtcpPacketInformation) {
812 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
813 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000814
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000815 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
816 if (bitMask) {
817 for (int i=1; i <= 16; ++i) {
818 if (bitMask & 0x01) {
819 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
820 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
821 }
822 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000823 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000824 }
825 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000826}
827
828// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000829void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
830 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000831
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000832 // clear our lists
833 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000834 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
835 for (; it != _receivedReportBlockMap.end(); ++it) {
836 ReportBlockInfoMap* info_map = &(it->second);
837 ReportBlockInfoMap::iterator it_info = info_map->find(
838 rtcpPacket.BYE.SenderSSRC);
839 if (it_info != info_map->end()) {
840 delete it_info->second;
841 info_map->erase(it_info);
842 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000843 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000844
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000845 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000846 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000847 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000848
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000849 if (receiveInfoIt != _receivedInfoMap.end()) {
850 receiveInfoIt->second->readyForDelete = true;
851 }
852
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000853 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000854 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
855
856 if (cnameInfoIt != _receivedCnameMap.end()) {
857 delete cnameInfoIt->second;
858 _receivedCnameMap.erase(cnameInfoIt);
859 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000860 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000861 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000862}
863
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000864void RTCPReceiver::HandleXrHeader(
865 RTCPUtility::RTCPParserV2& parser,
866 RTCPPacketInformation& rtcpPacketInformation) {
867 const RTCPUtility::RTCPPacket& packet = parser.Packet();
868
869 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
870
871 parser.Iterate();
872}
873
874void RTCPReceiver::HandleXrReceiveReferenceTime(
875 RTCPUtility::RTCPParserV2& parser,
876 RTCPPacketInformation& rtcpPacketInformation) {
877 const RTCPUtility::RTCPPacket& packet = parser.Packet();
878
879 _remoteXRReceiveTimeInfo.sourceSSRC =
880 rtcpPacketInformation.xr_originator_ssrc;
881
882 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
883 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
884 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
885
886 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
887
888 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
889
890 parser.Iterate();
891}
892
893void RTCPReceiver::HandleXrDlrrReportBlock(
894 RTCPUtility::RTCPParserV2& parser,
895 RTCPPacketInformation& rtcpPacketInformation) {
896 const RTCPUtility::RTCPPacket& packet = parser.Packet();
897 // Iterate through sub-block(s), if any.
898 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
899
Erik Språng242e22b2015-05-11 10:17:43 +0200900 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000901 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
902 packet_type = parser.Iterate();
903 }
904}
905
906void RTCPReceiver::HandleXrDlrrReportBlockItem(
907 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000908 RTCPPacketInformation& rtcpPacketInformation)
909 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000910 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
911 registered_ssrcs_.end()) {
912 // Not to us.
913 return;
914 }
915
916 rtcpPacketInformation.xr_dlrr_item = true;
917
918 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
919 // _criticalSectionRTCPReceiver.
920 _criticalSectionRTCPReceiver->Leave();
921
922 int64_t send_time_ms;
923 bool found = _rtpRtcp.SendTimeOfXrRrReport(
924 packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
925
926 _criticalSectionRTCPReceiver->Enter();
927
928 if (!found) {
929 return;
930 }
931
932 // The DelayLastRR field is in units of 1/65536 sec.
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000933 uint32_t delay_rr_ms =
934 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
935 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000936
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000937 int64_t rtt = _clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000938
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000939 xr_rr_rtt_ms_ = std::max<int64_t>(rtt, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000940
941 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
942}
943
niklase@google.com470e71d2011-07-07 08:21:25 +0000944// no need for critsect we have _criticalSectionRTCPReceiver
945void
946RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
947 RTCPPacketInformation& rtcpPacketInformation)
948{
949 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
950
951 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
952
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000953 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000954 {
955 // Store VoIP metrics block if it's about me
956 // from OriginatorSSRC do we filter it?
957 // rtcpPacket.XR.OriginatorSSRC;
958
959 RTCPVoIPMetric receivedVoIPMetrics;
960 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
961 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
962 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
963 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
964 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
965 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
966 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
967 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
968 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
969 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
970 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
971 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
972 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
973 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
974 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
975 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
976 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
977 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
978 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
979 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
980
981 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
982
983 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
984 }
985 rtcpParser.Iterate();
986}
987
988// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000989void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
990 RTCPPacketInformation& rtcpPacketInformation) {
991 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000992 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000993 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000994
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000995 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000996 // Received a signal that we need to send a new key frame.
997 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
998 }
999 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001000}
1001
1002// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001003void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
1004 RTCPPacketInformation& rtcpPacketInformation) {
1005 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001006
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001007 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
1008 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
1009 if (ptrReceiveInfo == NULL) {
1010 // This remote SSRC must be saved before.
1011 rtcpParser.Iterate();
1012 return;
1013 }
1014 if (rtcpPacket.TMMBR.MediaSSRC) {
1015 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1016 // in relay mode this is a valid number
1017 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1018 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001019
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001020 // Use packet length to calc max number of TMMBR blocks
1021 // each TMMBR block is 8 bytes
1022 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001023
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001024 // sanity, we can't have more than what's in one packet
1025 if (maxNumOfTMMBRBlocks > 200) {
1026 assert(false);
1027 rtcpParser.Iterate();
1028 return;
1029 }
1030 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001031
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001032 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001033 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001034 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1035 pktType = rtcpParser.Iterate();
1036 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001037}
1038
1039// no need for critsect we have _criticalSectionRTCPReceiver
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001040void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1041 const RTCPUtility::RTCPPacket& rtcpPacket,
1042 RTCPPacketInformation& rtcpPacketInformation,
1043 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001044 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1045 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1046 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1047 _clock->TimeInMilliseconds());
1048 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1049 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001050}
1051
1052// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001053void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1054 RTCPPacketInformation& rtcpPacketInformation) {
1055 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1056 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1057 rtcpPacket.TMMBN.SenderSSRC);
1058 if (ptrReceiveInfo == NULL) {
1059 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001060 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001061 return;
1062 }
1063 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1064 // Use packet length to calc max number of TMMBN blocks
1065 // each TMMBN block is 8 bytes
1066 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1067
1068 // sanity, we cant have more than what's in one packet
1069 if (maxNumOfTMMBNBlocks > 200) {
1070 assert(false);
1071 rtcpParser.Iterate();
1072 return;
1073 }
1074
1075 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1076
1077 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001078 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001079 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1080 pktType = rtcpParser.Iterate();
1081 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001082}
1083
1084// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001085void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1086 RTCPPacketInformation& rtcpPacketInformation) {
1087 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1088 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001089}
1090
1091// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001092void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1093 const RTCPUtility::RTCPPacket& rtcpPacket) {
1094 receiveInfo.TmmbnBoundingSet.AddEntry(
1095 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1096 rtcpPacket.TMMBNItem.MeasuredOverhead,
1097 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001098}
1099
1100// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001101void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1102 RTCPPacketInformation& rtcpPacketInformation) {
1103 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1104 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001105 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001106 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1107 pktType = rtcpParser.Iterate();
1108 }
1109}
1110
1111// no need for critsect we have _criticalSectionRTCPReceiver
1112void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1113 RTCPPacketInformation& rtcpPacketInformation) {
1114 // in theory there could be multiple slices lost
1115 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1116 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001117}
1118
1119void
1120RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1121 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1122{
1123 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001124 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001125 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001126 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1127 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1128 {
1129 // to us unknown
1130 // continue
1131 rtcpParser.Iterate();
1132 return;
1133 }
1134 rtcpPacketInformation.rpsiPictureId = 0;
1135
1136 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001137 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1138 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001139 {
1140 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1141 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1142 }
1143 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1144 }
1145}
1146
1147// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001148void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1149 RTCPPacketInformation& rtcpPacketInformation) {
1150 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001151 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001152 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001153 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001154 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1155 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001156 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001157 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001158}
1159
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001160// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001161void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1162 RTCPPacketInformation& rtcpPacketInformation) {
1163 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001164
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001165 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001166 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001167 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1168 pktType = rtcpParser.Iterate();
1169 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001170}
1171
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001172void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1173 RTCPPacketInformation& rtcpPacketInformation) {
1174 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1175 rtcpPacketInformation.interArrivalJitter =
1176 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001177}
1178
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001179void RTCPReceiver::HandleREMBItem(
1180 RTCPUtility::RTCPParserV2& rtcpParser,
1181 RTCPPacketInformation& rtcpPacketInformation) {
1182 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1183 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1184 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1185 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001186}
1187
1188// no need for critsect we have _criticalSectionRTCPReceiver
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
1202// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001203void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1204 const RTCPUtility::RTCPPacket& rtcpPacket,
1205 RTCPPacketInformation& rtcpPacketInformation) {
1206 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001207 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001208 return;
1209 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001210
1211 ++packet_type_counter_.fir_packets;
1212
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001213 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1214 // we don't know who this originate from
1215 if (receiveInfo) {
1216 // check if we have reported this FIRSequenceNumber before
1217 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1218 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001219 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001220 // sanity; don't go crazy with the callbacks
1221 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1222 receiveInfo->lastFIRRequest = now;
1223 receiveInfo->lastFIRSequenceNumber =
1224 rtcpPacket.FIRItem.CommandSequenceNumber;
1225 // received signal that we need to send a new key frame
1226 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1227 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001228 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001229 } else {
1230 // received signal that we need to send a new key frame
1231 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1232 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001233}
1234
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001235void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1236 RTCPPacketInformation& rtcpPacketInformation) {
1237 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001238
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001239 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1240 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1241 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001242
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001243 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001244}
1245
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001246void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1247 RTCPPacketInformation& rtcpPacketInformation) {
1248 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001249
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001250 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001251
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001252 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001253}
1254
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001255int32_t RTCPReceiver::UpdateTMMBR() {
1256 int32_t numBoundingSet = 0;
1257 uint32_t bitrate = 0;
1258 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001259
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001260 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001261 if (size > 0) {
1262 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1263 // Get candidate set from receiver.
1264 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1265 } else {
1266 // Candidate set empty.
1267 VerifyAndAllocateCandidateSet(0); // resets candidate set
1268 }
1269 // Find bounding set
1270 TMMBRSet* boundingSet = NULL;
1271 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1272 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001273 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001274 return -1;
1275 }
1276 // Set bounding set
1277 // Inform remote clients about the new bandwidth
1278 // inform the remote client
1279 _rtpRtcp.SetTMMBN(boundingSet);
1280
1281 // might trigger a TMMBN
1282 if (numBoundingSet == 0) {
1283 // owner of max bitrate request has timed out
1284 // empty bounding set has been sent
1285 return 0;
1286 }
1287 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001288 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001289 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001290 if (_cbRtcpBandwidthObserver) {
1291 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001292 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001293 }
1294 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001295}
1296
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001297void RTCPReceiver::RegisterRtcpStatisticsCallback(
1298 RtcpStatisticsCallback* callback) {
1299 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001300 stats_callback_ = callback;
1301}
1302
1303RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1304 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1305 return stats_callback_;
1306}
1307
niklase@google.com470e71d2011-07-07 08:21:25 +00001308// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001309void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001310 RTCPPacketInformation& rtcpPacketInformation) {
1311 // Process TMMBR and REMB first to avoid multiple callbacks
1312 // to OnNetworkChanged.
1313 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001314 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1315 UpdateTMMBR();
1316 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001317 unsigned int local_ssrc;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001318 {
1319 // We don't want to hold this critsect when triggering the callbacks below.
1320 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001321 local_ssrc = main_ssrc_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001322 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001323 if (!receiver_only_ &&
Erik Språngc9bbeb02015-09-23 13:51:47 +02001324 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001325 _rtpRtcp.OnRequestSendReport();
1326 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001327 if (!receiver_only_ &&
Erik Språngc9bbeb02015-09-23 13:51:47 +02001328 rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001329 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001330 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001331 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001332 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001333 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001334 }
1335 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001336 // We need feedback that we have received a report block(s) so that we
1337 // can generate a new packet in a conference relay scenario, one received
1338 // report can generate several RTCP packets, based on number relayed/mixed
1339 // a send report block should go out to all receivers.
1340 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001341 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001342 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1343 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1344 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001345 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001346 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001347 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001348 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001349 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001350 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001351 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001352 }
1353 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1354 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001355 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001356 }
1357 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1358 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001359 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001360 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001361 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001362 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001363 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001364 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001365 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001366 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001367 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1368 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1369 }
Erik Språng242e22b2015-05-11 10:17:43 +02001370 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1371 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001372 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001373 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001374 rtcpPacketInformation.report_blocks,
1375 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001376 now);
1377 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001378 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001379 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001380
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001381 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001382 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1383 if (stats_callback_) {
1384 for (ReportBlockList::const_iterator it =
1385 rtcpPacketInformation.report_blocks.begin();
1386 it != rtcpPacketInformation.report_blocks.end();
1387 ++it) {
1388 RtcpStatistics stats;
1389 stats.cumulative_lost = it->cumulativeLost;
1390 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1391 stats.fraction_lost = it->fractionLost;
1392 stats.jitter = it->jitter;
1393
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001394 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001395 }
1396 }
1397 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001398}
1399
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001400int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001401 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001402 assert(cName);
1403
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001404 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1405 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001406 if (cnameInfo == NULL) {
1407 return -1;
1408 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001409 cName[RTCP_CNAME_SIZE - 1] = 0;
1410 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1411 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001412}
1413
1414// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001415int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1416 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001417 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001418 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001419
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001420 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001421 receiveInfoIt = _receivedInfoMap.begin();
1422 if (receiveInfoIt == _receivedInfoMap.end()) {
1423 return -1;
1424 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001425 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001426 if (candidateSet) {
1427 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1428 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1429 if (receiveInfo == NULL) {
1430 return 0;
1431 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001432 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001433 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001434 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001435 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001436 num++;
1437 }
1438 }
1439 receiveInfoIt++;
1440 }
1441 } else {
1442 while (receiveInfoIt != _receivedInfoMap.end()) {
1443 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1444 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001445 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001446 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001447 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001448 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001449 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001450 }
1451 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001452}
1453
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001454} // namespace webrtc