blob: 23a7a781fec25dc072bdd6ac0d9796efb0dd3a1c [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000011#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
Peter Boströmfe7a80c2015-04-23 17:53:17 +020013#include <assert.h>
14#include <string.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000015
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +000016#include <algorithm>
17
Peter Boströmfe7a80c2015-04-23 17:53:17 +020018#include "webrtc/base/checks.h"
Peter Boströmebc0b4e2015-10-28 16:39:33 +010019#include "webrtc/base/logging.h"
tommie4f96502015-10-20 23:00:48 -070020#include "webrtc/base/trace_event.h"
Erik Språng6b8d3552015-09-24 15:06:57 +020021#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
tommie4f96502015-10-20 23:00:48 -070022#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000023#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
24#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000025
niklase@google.com470e71d2011-07-07 08:21:25 +000026namespace webrtc {
27using namespace RTCPUtility;
28using namespace RTCPHelp;
29
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000030// The number of RTCP time intervals needed to trigger a timeout.
31const int kRrTimeoutIntervals = 3;
32
Erik Språng6b8d3552015-09-24 15:06:57 +020033const int64_t kMaxWarningLogIntervalMs = 10000;
34
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000035RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000036 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020037 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000038 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000039 RtcpBandwidthObserver* rtcp_bandwidth_observer,
40 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020041 TransportFeedbackObserver* transport_feedback_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000042 ModuleRtpRtcpImpl* owner)
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000043 : TMMBRHelp(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000044 _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020045 receiver_only_(receiver_only),
pbosda903ea2015-10-02 02:36:56 -070046 _method(RtcpMode::kOff),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000047 _lastReceived(0),
48 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000049 _criticalSectionFeedbacks(
50 CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000051 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
52 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020053 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000054 _criticalSectionRTCPReceiver(
55 CriticalSectionWrapper::CreateCriticalSection()),
56 main_ssrc_(0),
57 _remoteSSRC(0),
58 _remoteSenderInfo(),
59 _lastReceivedSRNTPsecs(0),
60 _lastReceivedSRNTPfrac(0),
61 _lastReceivedXRNTPsecs(0),
62 _lastReceivedXRNTPfrac(0),
63 xr_rr_rtt_ms_(0),
64 _receivedInfoMap(),
65 _packetTimeOutMS(0),
66 _lastReceivedRrMs(0),
67 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000068 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020069 packet_type_counter_observer_(packet_type_counter_observer),
70 num_skipped_packets_(0),
71 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000072 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000073}
74
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000075RTCPReceiver::~RTCPReceiver() {
76 delete _criticalSectionRTCPReceiver;
77 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000078
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000079 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
80 for (; it != _receivedReportBlockMap.end(); ++it) {
81 ReportBlockInfoMap* info_map = &(it->second);
82 while (!info_map->empty()) {
83 ReportBlockInfoMap::iterator it_info = info_map->begin();
84 delete it_info->second;
85 info_map->erase(it_info);
86 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000087 }
88 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000089 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000090 _receivedInfoMap.begin();
91 delete first->second;
92 _receivedInfoMap.erase(first);
93 }
94 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000095 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000096 _receivedCnameMap.begin();
97 delete first->second;
98 _receivedCnameMap.erase(first);
99 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000100}
101
pbosda903ea2015-10-02 02:36:56 -0700102RtcpMode RTCPReceiver::Status() const {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000103 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
104 return _method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000105}
106
pbosda903ea2015-10-02 02:36:56 -0700107void RTCPReceiver::SetRTCPStatus(RtcpMode method) {
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000108 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
109 _method = method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000110}
111
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000112int64_t RTCPReceiver::LastReceived() {
113 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
114 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000115}
116
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000117int64_t RTCPReceiver::LastReceivedReceiverReport() const {
118 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
119 int64_t last_received_rr = -1;
120 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
121 it != _receivedInfoMap.end(); ++it) {
122 if (it->second->lastTimeReceived > last_received_rr) {
123 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000124 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000125 }
126 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000127}
128
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000129void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
130 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000131
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000132 // new SSRC reset old reports
133 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
134 _lastReceivedSRNTPsecs = 0;
135 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000136
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000137 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000138}
139
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000140uint32_t RTCPReceiver::RemoteSSRC() const {
141 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
142 return _remoteSSRC;
143}
144
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000145void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
146 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000147 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000148 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000149 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000150 old_ssrc = main_ssrc_;
151 main_ssrc_ = main_ssrc;
152 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000153 }
154 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000155 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
156 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000157 }
158 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000159}
160
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000161int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000162 int64_t* RTT,
163 int64_t* avgRTT,
164 int64_t* minRTT,
165 int64_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000166 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000167
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000168 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000169 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000170
171 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000172 return -1;
173 }
174 if (RTT) {
175 *RTT = reportBlock->RTT;
176 }
177 if (avgRTT) {
178 *avgRTT = reportBlock->avgRTT;
179 }
180 if (minRTT) {
181 *minRTT = reportBlock->minRTT;
182 }
183 if (maxRTT) {
184 *maxRTT = reportBlock->maxRTT;
185 }
186 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000187}
188
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000189bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000190 assert(rtt_ms);
191 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
192 if (xr_rr_rtt_ms_ == 0) {
193 return false;
194 }
195 *rtt_ms = xr_rr_rtt_ms_;
196 xr_rr_rtt_ms_ = 0;
197 return true;
198}
199
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000200// TODO(pbos): Make this fail when we haven't received NTP.
201bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
202 uint32_t* ReceivedNTPfrac,
203 uint32_t* RTCPArrivalTimeSecs,
204 uint32_t* RTCPArrivalTimeFrac,
205 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000206{
207 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
208 if(ReceivedNTPsecs)
209 {
210 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
211 }
212 if(ReceivedNTPfrac)
213 {
214 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
215 }
216 if(RTCPArrivalTimeFrac)
217 {
218 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
219 }
220 if(RTCPArrivalTimeSecs)
221 {
222 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
223 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000224 if (rtcp_timestamp) {
225 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
226 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000227 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000228}
229
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000230bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
231 RtcpReceiveTimeInfo* info) const {
232 assert(info);
233 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
234 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
235 return false;
236 }
237
238 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
239 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
240
241 // Get the delay since last received report (RFC 3611).
242 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
243 _lastReceivedXRNTPfrac);
244
245 uint32_t ntp_sec = 0;
246 uint32_t ntp_frac = 0;
247 _clock->CurrentNtp(ntp_sec, ntp_frac);
248 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
249
250 info->delaySinceLastRR = now - receive_time;
251 return true;
252}
253
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000254int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
255 assert(senderInfo);
256 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
257 if (_lastReceivedSRNTPsecs == 0) {
258 return -1;
259 }
260 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
261 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000262}
263
264// statistics
265// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000266int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000267 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000268 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000269 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000270 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
271 for (; it != _receivedReportBlockMap.end(); ++it) {
272 const ReportBlockInfoMap* info_map = &(it->second);
273 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
274 for (; it_info != info_map->end(); ++it_info) {
275 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
276 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000277 }
278 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000279}
280
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000281int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000282RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
283 RTCPUtility::RTCPParserV2* rtcpParser)
284{
285 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
286
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000287 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000288
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000289 if (packet_type_counter_.first_packet_time_ms == -1) {
290 packet_type_counter_.first_packet_time_ms = _lastReceived;
291 }
292
niklase@google.com470e71d2011-07-07 08:21:25 +0000293 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200294 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000295 // Each "case" is responsible for iterate the parser to the
296 // next top level packet.
297 switch (pktType)
298 {
Erik Språng242e22b2015-05-11 10:17:43 +0200299 case RTCPPacketTypes::kSr:
300 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000301 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
302 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200303 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200304 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000305 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200306 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000307 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
308 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200309 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000310 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
311 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200312 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000313 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
314 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200315 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000316 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
317 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200318 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000319 HandleBYE(*rtcpParser);
320 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200321 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000322 HandleNACK(*rtcpParser, rtcpPacketInformation);
323 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200324 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000325 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
326 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200327 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000328 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000329 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200330 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
332 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200333 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000334 HandlePLI(*rtcpParser, rtcpPacketInformation);
335 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200336 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000337 HandleSLI(*rtcpParser, rtcpPacketInformation);
338 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200339 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000340 HandleRPSI(*rtcpParser, rtcpPacketInformation);
341 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200342 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000343 HandleIJ(*rtcpParser, rtcpPacketInformation);
344 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200345 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000346 HandleFIR(*rtcpParser, rtcpPacketInformation);
347 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200348 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000349 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
350 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200351 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000352 // generic application messages
353 HandleAPP(*rtcpParser, rtcpPacketInformation);
354 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200355 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000356 // generic application messages
357 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
358 break;
Erik Språng6b8d3552015-09-24 15:06:57 +0200359 case RTCPPacketTypes::kTransportFeedback:
360 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
361 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000362 default:
363 rtcpParser->Iterate();
364 break;
365 }
366 pktType = rtcpParser->PacketType();
367 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000368
369 if (packet_type_counter_observer_ != NULL) {
370 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
371 main_ssrc_, packet_type_counter_);
372 }
373
Erik Språng6b8d3552015-09-24 15:06:57 +0200374 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
375
376 int64_t now = _clock->TimeInMilliseconds();
377 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
378 num_skipped_packets_ > 0) {
379 last_skipped_packets_warning_ = now;
380 LOG(LS_WARNING)
381 << num_skipped_packets_
382 << " RTCP blocks were skipped due to being malformed or of "
383 "unrecognized/unsupported type, during the past "
384 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
385 }
386
niklase@google.com470e71d2011-07-07 08:21:25 +0000387 return 0;
388}
389
niklase@google.com470e71d2011-07-07 08:21:25 +0000390void
391RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
392 RTCPPacketInformation& rtcpPacketInformation)
393{
394 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
395 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
396
Erik Språng242e22b2015-05-11 10:17:43 +0200397 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
398 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000399
400 // SR.SenderSSRC
401 // The synchronization source identifier for the originator of this SR packet
402
403 // rtcpPacket.RR.SenderSSRC
404 // The source of the packet sender, same as of SR? or is this a CE?
405
Erik Språng242e22b2015-05-11 10:17:43 +0200406 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
407 ? rtcpPacket.RR.SenderSSRC
408 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000409
410 rtcpPacketInformation.remoteSSRC = remoteSSRC;
411
412 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
413 if (!ptrReceiveInfo)
414 {
415 rtcpParser.Iterate();
416 return;
417 }
418
Erik Språng242e22b2015-05-11 10:17:43 +0200419 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000420 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
421 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000422
niklase@google.com470e71d2011-07-07 08:21:25 +0000423 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
424 {
425 // only signal that we have received a SR when we accept one
426 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
427
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000428 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
429 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
430 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
431
niklase@google.com470e71d2011-07-07 08:21:25 +0000432 // We will only store the send report from one source, but
433 // we will store all the receive block
434
435 // Save the NTP time of this report
436 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
437 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
438 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
439 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
440 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
441
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000442 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000443 }
444 else
445 {
446 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
447 }
448 } else
449 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000450 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
451 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000452
453 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
454 }
455 UpdateReceiveInformation(*ptrReceiveInfo);
456
457 rtcpPacketType = rtcpParser.Iterate();
458
Erik Språng242e22b2015-05-11 10:17:43 +0200459 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000460 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000461 rtcpPacketType = rtcpParser.Iterate();
462 }
463}
464
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000465void RTCPReceiver::HandleReportBlock(
466 const RTCPUtility::RTCPPacket& rtcpPacket,
467 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000468 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000469 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000470 // This will be called once per report block in the RTCP packet.
471 // We filter out all report blocks that are not for us.
472 // Each packet has max 31 RR blocks.
473 //
474 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000475
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000476 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
477 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000478
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000479 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000480 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
481 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000482 // This block is not for us ignore it.
483 return;
484 }
485
486 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
487 // _criticalSectionRTCPReceiver.
488 _criticalSectionRTCPReceiver->Leave();
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000489 int64_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000490 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
491 _criticalSectionRTCPReceiver->Enter();
492
493 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000494 CreateOrGetReportBlockInformation(remoteSSRC,
495 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000496 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000497 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
498 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000499 return;
500 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000501
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000502 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000503 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
504 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
505 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
506 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
507 reportBlock->remoteReceiveBlock.cumulativeLost =
508 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000509 if (rb.ExtendedHighestSequenceNumber >
510 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
511 // We have successfully delivered new RTP packets to the remote side after
512 // the last RR was sent from the remote side.
513 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000514 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000515 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
516 rb.ExtendedHighestSequenceNumber;
517 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
518 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
519 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
520
521 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
522 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
523 }
524
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000525 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000526 rtcpPacket.ReportBlockItem.DelayLastSR;
527
528 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000529 uint32_t lastReceivedRRNTPsecs = 0;
530 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000531
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000532 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000533
534 // time when we received this in MS
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000535 int64_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
536 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000537
538 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000539 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000540 d /= 65536;
541 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
542
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000543 int64_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000544
545 if (sendTimeMS > 0) {
546 RTT = receiveTimeMS - d - sendTimeMS;
547 if (RTT <= 0) {
548 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000549 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000550 if (RTT > reportBlock->maxRTT) {
551 // store max RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000552 reportBlock->maxRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000553 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000554 if (reportBlock->minRTT == 0) {
555 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000556 reportBlock->minRTT = RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000557 } else if (RTT < reportBlock->minRTT) {
558 // Store min RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000559 reportBlock->minRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000560 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000561 // store last RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000562 reportBlock->RTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000563
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000564 // store average RTT
565 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000566 float ac = static_cast<float>(reportBlock->numAverageCalcs);
567 float newAverage =
568 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * RTT);
569 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000570 } else {
571 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000572 reportBlock->avgRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000573 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000574 reportBlock->numAverageCalcs++;
575 }
576
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000577 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
578 RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000579
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000580 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000581}
582
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000583RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
584 uint32_t remote_ssrc,
585 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000586 RTCPReportBlockInformation* info =
587 GetReportBlockInformation(remote_ssrc, source_ssrc);
588 if (info == NULL) {
589 info = new RTCPReportBlockInformation;
590 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000591 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000592 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000593}
594
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000595RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
596 uint32_t remote_ssrc,
597 uint32_t source_ssrc) const {
598 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000599 if (it == _receivedReportBlockMap.end()) {
600 return NULL;
601 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000602 const ReportBlockInfoMap* info_map = &(it->second);
603 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
604 if (it_info == info_map->end()) {
605 return NULL;
606 }
607 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000608}
609
610RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000611RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000612 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000613
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000614 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000615 _receivedCnameMap.find(remoteSSRC);
616
617 if (it != _receivedCnameMap.end()) {
618 return it->second;
619 }
620 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000621 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000622 _receivedCnameMap[remoteSSRC] = cnameInfo;
623 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000624}
625
626RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000627RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000628 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000629
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000630 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000631 _receivedCnameMap.find(remoteSSRC);
632
633 if (it == _receivedCnameMap.end()) {
634 return NULL;
635 }
636 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000637}
638
639RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000640RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000641 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000642
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000643 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000644 _receivedInfoMap.find(remoteSSRC);
645
646 if (it != _receivedInfoMap.end()) {
647 return it->second;
648 }
649 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
650 _receivedInfoMap[remoteSSRC] = receiveInfo;
651 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000652}
653
654RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000655RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000656 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000657
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000658 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000659 _receivedInfoMap.find(remoteSSRC);
660 if (it == _receivedInfoMap.end()) {
661 return NULL;
662 }
663 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000664}
665
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000666void RTCPReceiver::UpdateReceiveInformation(
667 RTCPReceiveInformation& receiveInformation) {
668 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000669 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000670}
671
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000672bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
673 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
674 if (_lastReceivedRrMs == 0)
675 return false;
676
677 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000678 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000679 // Reset the timer to only trigger one log.
680 _lastReceivedRrMs = 0;
681 return true;
682 }
683 return false;
684}
685
686bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
687 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
688 if (_lastIncreasedSequenceNumberMs == 0)
689 return false;
690
691 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000692 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000693 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000694 // Reset the timer to only trigger one log.
695 _lastIncreasedSequenceNumberMs = 0;
696 return true;
697 }
698 return false;
699}
700
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000701bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
702 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000703
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000704 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000705 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000706
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000707 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000708 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000709
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000710 while (receiveInfoIt != _receivedInfoMap.end()) {
711 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
712 if (receiveInfo == NULL) {
713 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000714 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000715 // time since last received rtcp packet
716 // when we dont have a lastTimeReceived and the object is marked
717 // readyForDelete it's removed from the map
718 if (receiveInfo->lastTimeReceived) {
719 /// use audio define since we don't know what interval the remote peer is
720 // using
721 if ((timeNow - receiveInfo->lastTimeReceived) >
722 5 * RTCP_INTERVAL_AUDIO_MS) {
723 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000724 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000725 // prevent that we call this over and over again
726 receiveInfo->lastTimeReceived = 0;
727 // send new TMMBN to all channels using the default codec
728 updateBoundingSet = true;
729 }
730 receiveInfoIt++;
731 } else if (receiveInfo->readyForDelete) {
732 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000733 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000734 receiveInfoItemToBeErased = receiveInfoIt;
735 receiveInfoIt++;
736 delete receiveInfoItemToBeErased->second;
737 _receivedInfoMap.erase(receiveInfoItemToBeErased);
738 } else {
739 receiveInfoIt++;
740 }
741 }
742 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000743}
744
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000745int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000746 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000747
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000748 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000749 _receivedInfoMap.find(_remoteSSRC);
750
751 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000752 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000753 }
754 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
755 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000756 return -1;
757 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000758 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000759 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000760 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000761 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000762 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000763 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000764 // owner of bounding set
765 tmmbrOwner = true;
766 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000767 boundingSetRec->SetEntry(i,
768 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
769 receiveInfo->TmmbnBoundingSet.PacketOH(i),
770 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000771 }
772 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000773 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000774}
775
Erik Språnga38233a2015-07-24 09:58:18 +0200776void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
777 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000778 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200779 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000780 HandleSDESChunk(rtcpParser);
781 pktType = rtcpParser.Iterate();
782 }
Erik Språnga38233a2015-07-24 09:58:18 +0200783 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000784}
785
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000786void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
787 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
788 RTCPCnameInformation* cnameInfo =
789 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
790 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000791
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000792 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
793 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000794 {
795 CriticalSectionScoped lock(_criticalSectionFeedbacks);
796 if (stats_callback_ != NULL) {
797 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
798 rtcpPacket.CName.SenderSSRC);
799 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000800 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000801}
802
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000803void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
804 RTCPPacketInformation& rtcpPacketInformation) {
805 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200806 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000807 // Not to us.
808 rtcpParser.Iterate();
809 return;
810 }
811 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000812
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000813 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200814 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000815 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
816 pktType = rtcpParser.Iterate();
817 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000818
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000819 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
820 ++packet_type_counter_.nack_packets;
821 packet_type_counter_.nack_requests = nack_stats_.requests();
822 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
823 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000824}
825
niklase@google.com470e71d2011-07-07 08:21:25 +0000826void
827RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000828 RTCPPacketInformation& rtcpPacketInformation) {
829 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
830 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000831
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000832 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
833 if (bitMask) {
834 for (int i=1; i <= 16; ++i) {
835 if (bitMask & 0x01) {
836 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
837 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
838 }
839 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000840 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000841 }
842 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000843}
844
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000845void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
846 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000847
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000848 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000849 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
850 for (; it != _receivedReportBlockMap.end(); ++it) {
851 ReportBlockInfoMap* info_map = &(it->second);
852 ReportBlockInfoMap::iterator it_info = info_map->find(
853 rtcpPacket.BYE.SenderSSRC);
854 if (it_info != info_map->end()) {
855 delete it_info->second;
856 info_map->erase(it_info);
857 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000858 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000859
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000860 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000861 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000862 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000863
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000864 if (receiveInfoIt != _receivedInfoMap.end()) {
865 receiveInfoIt->second->readyForDelete = true;
866 }
867
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000868 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000869 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
870
871 if (cnameInfoIt != _receivedCnameMap.end()) {
872 delete cnameInfoIt->second;
873 _receivedCnameMap.erase(cnameInfoIt);
874 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000875 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000876 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000877}
878
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000879void RTCPReceiver::HandleXrHeader(
880 RTCPUtility::RTCPParserV2& parser,
881 RTCPPacketInformation& rtcpPacketInformation) {
882 const RTCPUtility::RTCPPacket& packet = parser.Packet();
883
884 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
885
886 parser.Iterate();
887}
888
889void RTCPReceiver::HandleXrReceiveReferenceTime(
890 RTCPUtility::RTCPParserV2& parser,
891 RTCPPacketInformation& rtcpPacketInformation) {
892 const RTCPUtility::RTCPPacket& packet = parser.Packet();
893
894 _remoteXRReceiveTimeInfo.sourceSSRC =
895 rtcpPacketInformation.xr_originator_ssrc;
896
897 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
898 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
899 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
900
901 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
902
903 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
904
905 parser.Iterate();
906}
907
908void RTCPReceiver::HandleXrDlrrReportBlock(
909 RTCPUtility::RTCPParserV2& parser,
910 RTCPPacketInformation& rtcpPacketInformation) {
911 const RTCPUtility::RTCPPacket& packet = parser.Packet();
912 // Iterate through sub-block(s), if any.
913 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
914
Erik Språng242e22b2015-05-11 10:17:43 +0200915 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000916 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
917 packet_type = parser.Iterate();
918 }
919}
920
921void RTCPReceiver::HandleXrDlrrReportBlockItem(
922 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000923 RTCPPacketInformation& rtcpPacketInformation)
924 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000925 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
926 registered_ssrcs_.end()) {
927 // Not to us.
928 return;
929 }
930
931 rtcpPacketInformation.xr_dlrr_item = true;
932
933 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
934 // _criticalSectionRTCPReceiver.
935 _criticalSectionRTCPReceiver->Leave();
936
937 int64_t send_time_ms;
938 bool found = _rtpRtcp.SendTimeOfXrRrReport(
939 packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
940
941 _criticalSectionRTCPReceiver->Enter();
942
943 if (!found) {
944 return;
945 }
946
947 // The DelayLastRR field is in units of 1/65536 sec.
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000948 uint32_t delay_rr_ms =
949 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
950 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000951
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000952 int64_t rtt = _clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000953
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000954 xr_rr_rtt_ms_ = std::max<int64_t>(rtt, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000955
956 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
957}
958
niklase@google.com470e71d2011-07-07 08:21:25 +0000959void
960RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
961 RTCPPacketInformation& rtcpPacketInformation)
962{
963 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
964
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000965 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000966 {
967 // Store VoIP metrics block if it's about me
968 // from OriginatorSSRC do we filter it?
969 // rtcpPacket.XR.OriginatorSSRC;
970
971 RTCPVoIPMetric receivedVoIPMetrics;
972 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
973 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
974 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
975 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
976 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
977 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
978 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
979 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
980 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
981 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
982 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
983 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
984 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
985 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
986 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
987 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
988 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
989 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
990 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
991 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
992
993 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
994
995 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
996 }
997 rtcpParser.Iterate();
998}
999
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001000void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
1001 RTCPPacketInformation& rtcpPacketInformation) {
1002 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001003 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +00001004 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +00001005
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001006 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001007 // Received a signal that we need to send a new key frame.
1008 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
1009 }
1010 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001011}
1012
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001013void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
1014 RTCPPacketInformation& rtcpPacketInformation) {
1015 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001016
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001017 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
1018 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
1019 if (ptrReceiveInfo == NULL) {
1020 // This remote SSRC must be saved before.
1021 rtcpParser.Iterate();
1022 return;
1023 }
1024 if (rtcpPacket.TMMBR.MediaSSRC) {
1025 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1026 // in relay mode this is a valid number
1027 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1028 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001029
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001030 // Use packet length to calc max number of TMMBR blocks
1031 // each TMMBR block is 8 bytes
1032 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001033
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001034 // sanity, we can't have more than what's in one packet
1035 if (maxNumOfTMMBRBlocks > 200) {
1036 assert(false);
1037 rtcpParser.Iterate();
1038 return;
1039 }
1040 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001041
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001042 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001043 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001044 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1045 pktType = rtcpParser.Iterate();
1046 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001047}
1048
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001049void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1050 const RTCPUtility::RTCPPacket& rtcpPacket,
1051 RTCPPacketInformation& rtcpPacketInformation,
1052 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001053 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1054 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1055 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1056 _clock->TimeInMilliseconds());
1057 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1058 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001059}
1060
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001061void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1062 RTCPPacketInformation& rtcpPacketInformation) {
1063 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1064 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1065 rtcpPacket.TMMBN.SenderSSRC);
1066 if (ptrReceiveInfo == NULL) {
1067 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001068 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001069 return;
1070 }
1071 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1072 // Use packet length to calc max number of TMMBN blocks
1073 // each TMMBN block is 8 bytes
1074 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1075
1076 // sanity, we cant have more than what's in one packet
1077 if (maxNumOfTMMBNBlocks > 200) {
1078 assert(false);
1079 rtcpParser.Iterate();
1080 return;
1081 }
1082
1083 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1084
1085 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001086 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001087 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1088 pktType = rtcpParser.Iterate();
1089 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001090}
1091
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001092void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1093 RTCPPacketInformation& rtcpPacketInformation) {
1094 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1095 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001096}
1097
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001098void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1099 const RTCPUtility::RTCPPacket& rtcpPacket) {
1100 receiveInfo.TmmbnBoundingSet.AddEntry(
1101 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1102 rtcpPacket.TMMBNItem.MeasuredOverhead,
1103 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001104}
1105
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001106void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1107 RTCPPacketInformation& rtcpPacketInformation) {
1108 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1109 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001110 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001111 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1112 pktType = rtcpParser.Iterate();
1113 }
1114}
1115
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001116void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1117 RTCPPacketInformation& rtcpPacketInformation) {
1118 // in theory there could be multiple slices lost
1119 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1120 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001121}
1122
1123void
1124RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1125 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1126{
1127 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001128 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001129 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001130 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1131 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1132 {
1133 // to us unknown
1134 // continue
1135 rtcpParser.Iterate();
1136 return;
1137 }
1138 rtcpPacketInformation.rpsiPictureId = 0;
1139
1140 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001141 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1142 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001143 {
1144 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1145 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1146 }
1147 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1148 }
1149}
1150
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001151void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1152 RTCPPacketInformation& rtcpPacketInformation) {
1153 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001154 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001155 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001156 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001157 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1158 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001159 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001160 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001161}
1162
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001163void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1164 RTCPPacketInformation& rtcpPacketInformation) {
1165 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001166
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001167 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001168 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001169 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1170 pktType = rtcpParser.Iterate();
1171 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001172}
1173
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001174void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1175 RTCPPacketInformation& rtcpPacketInformation) {
1176 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1177 rtcpPacketInformation.interArrivalJitter =
1178 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001179}
1180
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001181void RTCPReceiver::HandleREMBItem(
1182 RTCPUtility::RTCPParserV2& rtcpParser,
1183 RTCPPacketInformation& rtcpPacketInformation) {
1184 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1185 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1186 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1187 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001188}
1189
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001190void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1191 RTCPPacketInformation& rtcpPacketInformation) {
1192 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1193 RTCPReceiveInformation* ptrReceiveInfo =
1194 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001195
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001196 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001197 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001198 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1199 pktType = rtcpParser.Iterate();
1200 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001201}
1202
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
Erik Språng6b8d3552015-09-24 15:06:57 +02001255void RTCPReceiver::HandleTransportFeedback(
1256 RTCPUtility::RTCPParserV2* rtcp_parser,
1257 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1258 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1259 RTC_DCHECK(packet != nullptr);
1260 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1261 rtcp_packet_information->transport_feedback_.reset(
1262 static_cast<rtcp::TransportFeedback*>(packet));
1263
1264 rtcp_parser->Iterate();
1265}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001266int32_t RTCPReceiver::UpdateTMMBR() {
1267 int32_t numBoundingSet = 0;
1268 uint32_t bitrate = 0;
1269 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001270
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001271 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001272 if (size > 0) {
1273 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1274 // Get candidate set from receiver.
1275 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1276 } else {
1277 // Candidate set empty.
1278 VerifyAndAllocateCandidateSet(0); // resets candidate set
1279 }
1280 // Find bounding set
1281 TMMBRSet* boundingSet = NULL;
1282 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1283 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001284 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001285 return -1;
1286 }
1287 // Set bounding set
1288 // Inform remote clients about the new bandwidth
1289 // inform the remote client
1290 _rtpRtcp.SetTMMBN(boundingSet);
1291
1292 // might trigger a TMMBN
1293 if (numBoundingSet == 0) {
1294 // owner of max bitrate request has timed out
1295 // empty bounding set has been sent
1296 return 0;
1297 }
1298 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001299 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001300 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001301 if (_cbRtcpBandwidthObserver) {
1302 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001303 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001304 }
1305 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001306}
1307
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001308void RTCPReceiver::RegisterRtcpStatisticsCallback(
1309 RtcpStatisticsCallback* callback) {
1310 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001311 stats_callback_ = callback;
1312}
1313
1314RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1315 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1316 return stats_callback_;
1317}
1318
niklase@google.com470e71d2011-07-07 08:21:25 +00001319// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001320void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001321 RTCPPacketInformation& rtcpPacketInformation) {
1322 // Process TMMBR and REMB first to avoid multiple callbacks
1323 // to OnNetworkChanged.
1324 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001325 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1326 UpdateTMMBR();
1327 }
sprang7dc39f32015-10-13 09:17:48 -07001328 uint32_t local_ssrc;
1329 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001330 {
1331 // We don't want to hold this critsect when triggering the callbacks below.
1332 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001333 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001334 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001335 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001336 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001337 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001338 _rtpRtcp.OnRequestSendReport();
1339 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001340 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001341 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001342 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001343 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001344 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001345 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001346 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001347 }
1348 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001349 // We need feedback that we have received a report block(s) so that we
1350 // can generate a new packet in a conference relay scenario, one received
1351 // report can generate several RTCP packets, based on number relayed/mixed
1352 // a send report block should go out to all receivers.
1353 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001354 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001355 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1356 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1357 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001358 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001359 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001360 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001361 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001362 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001363 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001364 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001365 }
1366 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1367 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001368 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001369 }
1370 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1371 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001372 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001373 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001374 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001375 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001376 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001377 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001378 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001379 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001380 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1381 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1382 }
Erik Språng242e22b2015-05-11 10:17:43 +02001383 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1384 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001385 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001386 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001387 rtcpPacketInformation.report_blocks,
1388 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001389 now);
1390 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001391 }
Erik Språng6b8d3552015-09-24 15:06:57 +02001392 if (_cbTransportFeedbackObserver &&
1393 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1394 uint32_t media_source_ssrc =
1395 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001396 if (media_source_ssrc == local_ssrc ||
1397 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001398 _cbTransportFeedbackObserver->OnTransportFeedback(
1399 *rtcpPacketInformation.transport_feedback_.get());
1400 }
1401 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001402 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001403
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001404 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001405 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1406 if (stats_callback_) {
1407 for (ReportBlockList::const_iterator it =
1408 rtcpPacketInformation.report_blocks.begin();
1409 it != rtcpPacketInformation.report_blocks.end();
1410 ++it) {
1411 RtcpStatistics stats;
1412 stats.cumulative_lost = it->cumulativeLost;
1413 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1414 stats.fraction_lost = it->fractionLost;
1415 stats.jitter = it->jitter;
1416
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001417 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001418 }
1419 }
1420 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001421}
1422
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001423int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001424 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001425 assert(cName);
1426
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001427 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1428 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001429 if (cnameInfo == NULL) {
1430 return -1;
1431 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001432 cName[RTCP_CNAME_SIZE - 1] = 0;
1433 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1434 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001435}
1436
1437// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001438int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1439 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001440 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001441 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001442
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001443 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001444 receiveInfoIt = _receivedInfoMap.begin();
1445 if (receiveInfoIt == _receivedInfoMap.end()) {
1446 return -1;
1447 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001448 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001449 if (candidateSet) {
1450 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1451 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1452 if (receiveInfo == NULL) {
1453 return 0;
1454 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001455 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001456 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001457 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001458 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001459 num++;
1460 }
1461 }
1462 receiveInfoIt++;
1463 }
1464 } else {
1465 while (receiveInfoIt != _receivedInfoMap.end()) {
1466 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1467 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001468 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001469 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001470 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001471 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001472 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001473 }
1474 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001475}
1476
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001477} // namespace webrtc