blob: 168557d22409802c99e0d80b3b3e2ae6f00140ec [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"
Erik Språng6b8d3552015-09-24 15:06:57 +020020#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000021#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
22#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +000023#include "webrtc/system_wrappers/interface/logging.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000024#include "webrtc/system_wrappers/interface/trace_event.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),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000046 _method(kRtcpOff),
47 _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
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000102RTCPMethod RTCPReceiver::Status() const {
103 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
104 return _method;
niklase@google.com470e71d2011-07-07 08:21:25 +0000105}
106
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +0000107void RTCPReceiver::SetRTCPStatus(RTCPMethod method) {
108 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
390// no need for critsect we have _criticalSectionRTCPReceiver
391void
392RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
393 RTCPPacketInformation& rtcpPacketInformation)
394{
395 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
396 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
397
Erik Språng242e22b2015-05-11 10:17:43 +0200398 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
399 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000400
401 // SR.SenderSSRC
402 // The synchronization source identifier for the originator of this SR packet
403
404 // rtcpPacket.RR.SenderSSRC
405 // The source of the packet sender, same as of SR? or is this a CE?
406
Erik Språng242e22b2015-05-11 10:17:43 +0200407 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
408 ? rtcpPacket.RR.SenderSSRC
409 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000410
411 rtcpPacketInformation.remoteSSRC = remoteSSRC;
412
413 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
414 if (!ptrReceiveInfo)
415 {
416 rtcpParser.Iterate();
417 return;
418 }
419
Erik Språng242e22b2015-05-11 10:17:43 +0200420 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000421 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
422 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000423
niklase@google.com470e71d2011-07-07 08:21:25 +0000424 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
425 {
426 // only signal that we have received a SR when we accept one
427 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
428
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000429 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
430 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
431 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
432
niklase@google.com470e71d2011-07-07 08:21:25 +0000433 // We will only store the send report from one source, but
434 // we will store all the receive block
435
436 // Save the NTP time of this report
437 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
438 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
439 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
440 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
441 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
442
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000443 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000444 }
445 else
446 {
447 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
448 }
449 } else
450 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000451 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
452 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000453
454 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
455 }
456 UpdateReceiveInformation(*ptrReceiveInfo);
457
458 rtcpPacketType = rtcpParser.Iterate();
459
Erik Språng242e22b2015-05-11 10:17:43 +0200460 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000461 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000462 rtcpPacketType = rtcpParser.Iterate();
463 }
464}
465
466// no need for critsect we have _criticalSectionRTCPReceiver
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000467void RTCPReceiver::HandleReportBlock(
468 const RTCPUtility::RTCPPacket& rtcpPacket,
469 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000470 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000471 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000472 // This will be called once per report block in the RTCP packet.
473 // We filter out all report blocks that are not for us.
474 // Each packet has max 31 RR blocks.
475 //
476 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000477
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000478 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
479 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000480
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000481 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000482 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
483 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000484 // This block is not for us ignore it.
485 return;
486 }
487
488 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
489 // _criticalSectionRTCPReceiver.
490 _criticalSectionRTCPReceiver->Leave();
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000491 int64_t sendTimeMS =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000492 _rtpRtcp.SendTimeOfSendReport(rtcpPacket.ReportBlockItem.LastSR);
493 _criticalSectionRTCPReceiver->Enter();
494
495 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000496 CreateOrGetReportBlockInformation(remoteSSRC,
497 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000498 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000499 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
500 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000501 return;
502 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000503
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000504 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000505 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
506 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
507 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
508 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
509 reportBlock->remoteReceiveBlock.cumulativeLost =
510 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000511 if (rb.ExtendedHighestSequenceNumber >
512 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
513 // We have successfully delivered new RTP packets to the remote side after
514 // the last RR was sent from the remote side.
515 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000516 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000517 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
518 rb.ExtendedHighestSequenceNumber;
519 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
520 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
521 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
522
523 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
524 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
525 }
526
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000527 uint32_t delaySinceLastSendReport =
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000528 rtcpPacket.ReportBlockItem.DelayLastSR;
529
530 // local NTP time when we received this
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000531 uint32_t lastReceivedRRNTPsecs = 0;
532 uint32_t lastReceivedRRNTPfrac = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000533
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000534 _clock->CurrentNtp(lastReceivedRRNTPsecs, lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000535
536 // time when we received this in MS
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000537 int64_t receiveTimeMS = Clock::NtpToMs(lastReceivedRRNTPsecs,
538 lastReceivedRRNTPfrac);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000539
540 // Estimate RTT
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000541 uint32_t d = (delaySinceLastSendReport & 0x0000ffff) * 1000;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000542 d /= 65536;
543 d += ((delaySinceLastSendReport & 0xffff0000) >> 16) * 1000;
544
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000545 int64_t RTT = 0;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000546
547 if (sendTimeMS > 0) {
548 RTT = receiveTimeMS - d - sendTimeMS;
549 if (RTT <= 0) {
550 RTT = 1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000551 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000552 if (RTT > reportBlock->maxRTT) {
553 // store max RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000554 reportBlock->maxRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000555 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000556 if (reportBlock->minRTT == 0) {
557 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000558 reportBlock->minRTT = RTT;
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000559 } else if (RTT < reportBlock->minRTT) {
560 // Store min RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000561 reportBlock->minRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000562 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000563 // store last RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000564 reportBlock->RTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000565
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000566 // store average RTT
567 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000568 float ac = static_cast<float>(reportBlock->numAverageCalcs);
569 float newAverage =
570 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * RTT);
571 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000572 } else {
573 // first RTT
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000574 reportBlock->avgRTT = RTT;
niklase@google.com470e71d2011-07-07 08:21:25 +0000575 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000576 reportBlock->numAverageCalcs++;
577 }
578
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000579 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
580 RTT);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000581
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000582 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000583}
584
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000585RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
586 uint32_t remote_ssrc,
587 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000588 RTCPReportBlockInformation* info =
589 GetReportBlockInformation(remote_ssrc, source_ssrc);
590 if (info == NULL) {
591 info = new RTCPReportBlockInformation;
592 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000593 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000594 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000595}
596
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000597RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
598 uint32_t remote_ssrc,
599 uint32_t source_ssrc) const {
600 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000601 if (it == _receivedReportBlockMap.end()) {
602 return NULL;
603 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000604 const ReportBlockInfoMap* info_map = &(it->second);
605 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
606 if (it_info == info_map->end()) {
607 return NULL;
608 }
609 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000610}
611
612RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000613RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000614 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000615
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000616 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000617 _receivedCnameMap.find(remoteSSRC);
618
619 if (it != _receivedCnameMap.end()) {
620 return it->second;
621 }
622 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000623 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000624 _receivedCnameMap[remoteSSRC] = cnameInfo;
625 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000626}
627
628RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000629RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000630 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000631
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000632 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000633 _receivedCnameMap.find(remoteSSRC);
634
635 if (it == _receivedCnameMap.end()) {
636 return NULL;
637 }
638 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000639}
640
641RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000642RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000643 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000644
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000645 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000646 _receivedInfoMap.find(remoteSSRC);
647
648 if (it != _receivedInfoMap.end()) {
649 return it->second;
650 }
651 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
652 _receivedInfoMap[remoteSSRC] = receiveInfo;
653 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000654}
655
656RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000657RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000658 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000659
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000660 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000661 _receivedInfoMap.find(remoteSSRC);
662 if (it == _receivedInfoMap.end()) {
663 return NULL;
664 }
665 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000666}
667
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000668void RTCPReceiver::UpdateReceiveInformation(
669 RTCPReceiveInformation& receiveInformation) {
670 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000671 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000672}
673
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000674bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
675 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
676 if (_lastReceivedRrMs == 0)
677 return false;
678
679 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000680 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000681 // Reset the timer to only trigger one log.
682 _lastReceivedRrMs = 0;
683 return true;
684 }
685 return false;
686}
687
688bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
689 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
690 if (_lastIncreasedSequenceNumberMs == 0)
691 return false;
692
693 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000694 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000695 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000696 // Reset the timer to only trigger one log.
697 _lastIncreasedSequenceNumberMs = 0;
698 return true;
699 }
700 return false;
701}
702
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000703bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
704 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000705
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000706 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000707 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000708
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000709 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000710 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000711
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000712 while (receiveInfoIt != _receivedInfoMap.end()) {
713 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
714 if (receiveInfo == NULL) {
715 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000716 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000717 // time since last received rtcp packet
718 // when we dont have a lastTimeReceived and the object is marked
719 // readyForDelete it's removed from the map
720 if (receiveInfo->lastTimeReceived) {
721 /// use audio define since we don't know what interval the remote peer is
722 // using
723 if ((timeNow - receiveInfo->lastTimeReceived) >
724 5 * RTCP_INTERVAL_AUDIO_MS) {
725 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000726 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000727 // prevent that we call this over and over again
728 receiveInfo->lastTimeReceived = 0;
729 // send new TMMBN to all channels using the default codec
730 updateBoundingSet = true;
731 }
732 receiveInfoIt++;
733 } else if (receiveInfo->readyForDelete) {
734 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000735 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000736 receiveInfoItemToBeErased = receiveInfoIt;
737 receiveInfoIt++;
738 delete receiveInfoItemToBeErased->second;
739 _receivedInfoMap.erase(receiveInfoItemToBeErased);
740 } else {
741 receiveInfoIt++;
742 }
743 }
744 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000745}
746
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000747int32_t RTCPReceiver::BoundingSet(bool &tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000748 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000749
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000750 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000751 _receivedInfoMap.find(_remoteSSRC);
752
753 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000754 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000755 }
756 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
757 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000758 return -1;
759 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000760 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000761 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000762 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000763 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000764 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000765 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000766 // owner of bounding set
767 tmmbrOwner = true;
768 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000769 boundingSetRec->SetEntry(i,
770 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
771 receiveInfo->TmmbnBoundingSet.PacketOH(i),
772 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000773 }
774 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000775 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000776}
777
778// no need for critsect we have _criticalSectionRTCPReceiver
Erik Språnga38233a2015-07-24 09:58:18 +0200779void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
780 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000781 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200782 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000783 HandleSDESChunk(rtcpParser);
784 pktType = rtcpParser.Iterate();
785 }
Erik Språnga38233a2015-07-24 09:58:18 +0200786 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000787}
788
789// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000790void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
791 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
792 RTCPCnameInformation* cnameInfo =
793 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
794 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000795
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000796 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
797 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000798 {
799 CriticalSectionScoped lock(_criticalSectionFeedbacks);
800 if (stats_callback_ != NULL) {
801 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
802 rtcpPacket.CName.SenderSSRC);
803 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000804 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000805}
806
807// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000808void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
809 RTCPPacketInformation& rtcpPacketInformation) {
810 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200811 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000812 // Not to us.
813 rtcpParser.Iterate();
814 return;
815 }
816 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000817
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000818 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200819 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000820 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
821 pktType = rtcpParser.Iterate();
822 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000823
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000824 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
825 ++packet_type_counter_.nack_packets;
826 packet_type_counter_.nack_requests = nack_stats_.requests();
827 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
828 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000829}
830
831// no need for critsect we have _criticalSectionRTCPReceiver
832void
833RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000834 RTCPPacketInformation& rtcpPacketInformation) {
835 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
836 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000837
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000838 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
839 if (bitMask) {
840 for (int i=1; i <= 16; ++i) {
841 if (bitMask & 0x01) {
842 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
843 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
844 }
845 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000846 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000847 }
848 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000849}
850
851// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000852void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
853 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000854
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000855 // clear our lists
856 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000857 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
858 for (; it != _receivedReportBlockMap.end(); ++it) {
859 ReportBlockInfoMap* info_map = &(it->second);
860 ReportBlockInfoMap::iterator it_info = info_map->find(
861 rtcpPacket.BYE.SenderSSRC);
862 if (it_info != info_map->end()) {
863 delete it_info->second;
864 info_map->erase(it_info);
865 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000866 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000867
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000868 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000869 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000870 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000871
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000872 if (receiveInfoIt != _receivedInfoMap.end()) {
873 receiveInfoIt->second->readyForDelete = true;
874 }
875
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000876 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000877 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
878
879 if (cnameInfoIt != _receivedCnameMap.end()) {
880 delete cnameInfoIt->second;
881 _receivedCnameMap.erase(cnameInfoIt);
882 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000883 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000884 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000885}
886
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000887void RTCPReceiver::HandleXrHeader(
888 RTCPUtility::RTCPParserV2& parser,
889 RTCPPacketInformation& rtcpPacketInformation) {
890 const RTCPUtility::RTCPPacket& packet = parser.Packet();
891
892 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
893
894 parser.Iterate();
895}
896
897void RTCPReceiver::HandleXrReceiveReferenceTime(
898 RTCPUtility::RTCPParserV2& parser,
899 RTCPPacketInformation& rtcpPacketInformation) {
900 const RTCPUtility::RTCPPacket& packet = parser.Packet();
901
902 _remoteXRReceiveTimeInfo.sourceSSRC =
903 rtcpPacketInformation.xr_originator_ssrc;
904
905 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
906 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
907 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
908
909 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
910
911 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
912
913 parser.Iterate();
914}
915
916void RTCPReceiver::HandleXrDlrrReportBlock(
917 RTCPUtility::RTCPParserV2& parser,
918 RTCPPacketInformation& rtcpPacketInformation) {
919 const RTCPUtility::RTCPPacket& packet = parser.Packet();
920 // Iterate through sub-block(s), if any.
921 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
922
Erik Språng242e22b2015-05-11 10:17:43 +0200923 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000924 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
925 packet_type = parser.Iterate();
926 }
927}
928
929void RTCPReceiver::HandleXrDlrrReportBlockItem(
930 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000931 RTCPPacketInformation& rtcpPacketInformation)
932 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000933 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
934 registered_ssrcs_.end()) {
935 // Not to us.
936 return;
937 }
938
939 rtcpPacketInformation.xr_dlrr_item = true;
940
941 // To avoid problem with acquiring _criticalSectionRTCPSender while holding
942 // _criticalSectionRTCPReceiver.
943 _criticalSectionRTCPReceiver->Leave();
944
945 int64_t send_time_ms;
946 bool found = _rtpRtcp.SendTimeOfXrRrReport(
947 packet.XRDLRRReportBlockItem.LastRR, &send_time_ms);
948
949 _criticalSectionRTCPReceiver->Enter();
950
951 if (!found) {
952 return;
953 }
954
955 // The DelayLastRR field is in units of 1/65536 sec.
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000956 uint32_t delay_rr_ms =
957 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0x0000ffff) * 1000) >> 16) +
958 (((packet.XRDLRRReportBlockItem.DelayLastRR & 0xffff0000) >> 16) * 1000);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000959
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000960 int64_t rtt = _clock->CurrentNtpInMilliseconds() - delay_rr_ms - send_time_ms;
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000961
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000962 xr_rr_rtt_ms_ = std::max<int64_t>(rtt, 1);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000963
964 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
965}
966
niklase@google.com470e71d2011-07-07 08:21:25 +0000967// no need for critsect we have _criticalSectionRTCPReceiver
968void
969RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
970 RTCPPacketInformation& rtcpPacketInformation)
971{
972 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
973
974 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
975
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000976 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000977 {
978 // Store VoIP metrics block if it's about me
979 // from OriginatorSSRC do we filter it?
980 // rtcpPacket.XR.OriginatorSSRC;
981
982 RTCPVoIPMetric receivedVoIPMetrics;
983 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
984 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
985 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
986 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
987 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
988 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
989 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
990 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
991 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
992 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
993 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
994 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
995 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
996 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
997 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
998 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
999 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
1000 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
1001 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
1002 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
1003
1004 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
1005
1006 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
1007 }
1008 rtcpParser.Iterate();
1009}
1010
1011// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001012void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
1013 RTCPPacketInformation& rtcpPacketInformation) {
1014 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001015 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +00001016 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +00001017
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001018 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001019 // Received a signal that we need to send a new key frame.
1020 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
1021 }
1022 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001023}
1024
1025// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001026void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
1027 RTCPPacketInformation& rtcpPacketInformation) {
1028 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001029
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001030 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
1031 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
1032 if (ptrReceiveInfo == NULL) {
1033 // This remote SSRC must be saved before.
1034 rtcpParser.Iterate();
1035 return;
1036 }
1037 if (rtcpPacket.TMMBR.MediaSSRC) {
1038 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1039 // in relay mode this is a valid number
1040 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1041 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001042
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001043 // Use packet length to calc max number of TMMBR blocks
1044 // each TMMBR block is 8 bytes
1045 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001046
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001047 // sanity, we can't have more than what's in one packet
1048 if (maxNumOfTMMBRBlocks > 200) {
1049 assert(false);
1050 rtcpParser.Iterate();
1051 return;
1052 }
1053 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001054
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001055 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001056 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001057 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1058 pktType = rtcpParser.Iterate();
1059 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001060}
1061
1062// no need for critsect we have _criticalSectionRTCPReceiver
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001063void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1064 const RTCPUtility::RTCPPacket& rtcpPacket,
1065 RTCPPacketInformation& rtcpPacketInformation,
1066 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001067 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1068 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1069 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1070 _clock->TimeInMilliseconds());
1071 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1072 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001073}
1074
1075// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001076void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1077 RTCPPacketInformation& rtcpPacketInformation) {
1078 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1079 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1080 rtcpPacket.TMMBN.SenderSSRC);
1081 if (ptrReceiveInfo == NULL) {
1082 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001083 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001084 return;
1085 }
1086 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1087 // Use packet length to calc max number of TMMBN blocks
1088 // each TMMBN block is 8 bytes
1089 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1090
1091 // sanity, we cant have more than what's in one packet
1092 if (maxNumOfTMMBNBlocks > 200) {
1093 assert(false);
1094 rtcpParser.Iterate();
1095 return;
1096 }
1097
1098 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1099
1100 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001101 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001102 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1103 pktType = rtcpParser.Iterate();
1104 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001105}
1106
1107// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001108void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1109 RTCPPacketInformation& rtcpPacketInformation) {
1110 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1111 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001112}
1113
1114// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001115void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1116 const RTCPUtility::RTCPPacket& rtcpPacket) {
1117 receiveInfo.TmmbnBoundingSet.AddEntry(
1118 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1119 rtcpPacket.TMMBNItem.MeasuredOverhead,
1120 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001121}
1122
1123// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001124void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1125 RTCPPacketInformation& rtcpPacketInformation) {
1126 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1127 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001128 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001129 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1130 pktType = rtcpParser.Iterate();
1131 }
1132}
1133
1134// no need for critsect we have _criticalSectionRTCPReceiver
1135void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1136 RTCPPacketInformation& rtcpPacketInformation) {
1137 // in theory there could be multiple slices lost
1138 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1139 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001140}
1141
1142void
1143RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1144 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1145{
1146 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001147 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001148 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001149 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1150 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1151 {
1152 // to us unknown
1153 // continue
1154 rtcpParser.Iterate();
1155 return;
1156 }
1157 rtcpPacketInformation.rpsiPictureId = 0;
1158
1159 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001160 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1161 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001162 {
1163 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1164 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1165 }
1166 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1167 }
1168}
1169
1170// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001171void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1172 RTCPPacketInformation& rtcpPacketInformation) {
1173 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001174 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001175 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001176 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001177 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1178 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001179 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001180 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001181}
1182
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001183// no need for critsect we have _criticalSectionRTCPReceiver
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001184void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1185 RTCPPacketInformation& rtcpPacketInformation) {
1186 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001187
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001188 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001189 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001190 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1191 pktType = rtcpParser.Iterate();
1192 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001193}
1194
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001195void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1196 RTCPPacketInformation& rtcpPacketInformation) {
1197 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1198 rtcpPacketInformation.interArrivalJitter =
1199 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001200}
1201
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001202void RTCPReceiver::HandleREMBItem(
1203 RTCPUtility::RTCPParserV2& rtcpParser,
1204 RTCPPacketInformation& rtcpPacketInformation) {
1205 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1206 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1207 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1208 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001209}
1210
1211// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001212void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1213 RTCPPacketInformation& rtcpPacketInformation) {
1214 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1215 RTCPReceiveInformation* ptrReceiveInfo =
1216 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001217
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001218 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001219 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001220 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1221 pktType = rtcpParser.Iterate();
1222 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001223}
1224
1225// no need for critsect we have _criticalSectionRTCPReceiver
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001226void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1227 const RTCPUtility::RTCPPacket& rtcpPacket,
1228 RTCPPacketInformation& rtcpPacketInformation) {
1229 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001230 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001231 return;
1232 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001233
1234 ++packet_type_counter_.fir_packets;
1235
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001236 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1237 // we don't know who this originate from
1238 if (receiveInfo) {
1239 // check if we have reported this FIRSequenceNumber before
1240 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1241 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001242 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001243 // sanity; don't go crazy with the callbacks
1244 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1245 receiveInfo->lastFIRRequest = now;
1246 receiveInfo->lastFIRSequenceNumber =
1247 rtcpPacket.FIRItem.CommandSequenceNumber;
1248 // received signal that we need to send a new key frame
1249 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1250 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001251 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001252 } else {
1253 // received signal that we need to send a new key frame
1254 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1255 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001256}
1257
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001258void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1259 RTCPPacketInformation& rtcpPacketInformation) {
1260 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001261
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001262 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1263 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1264 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001265
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001266 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001267}
1268
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001269void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1270 RTCPPacketInformation& rtcpPacketInformation) {
1271 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001272
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001273 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001274
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001275 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001276}
1277
Erik Språng6b8d3552015-09-24 15:06:57 +02001278void RTCPReceiver::HandleTransportFeedback(
1279 RTCPUtility::RTCPParserV2* rtcp_parser,
1280 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1281 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1282 RTC_DCHECK(packet != nullptr);
1283 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1284 rtcp_packet_information->transport_feedback_.reset(
1285 static_cast<rtcp::TransportFeedback*>(packet));
1286
1287 rtcp_parser->Iterate();
1288}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001289int32_t RTCPReceiver::UpdateTMMBR() {
1290 int32_t numBoundingSet = 0;
1291 uint32_t bitrate = 0;
1292 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001293
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001294 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001295 if (size > 0) {
1296 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1297 // Get candidate set from receiver.
1298 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1299 } else {
1300 // Candidate set empty.
1301 VerifyAndAllocateCandidateSet(0); // resets candidate set
1302 }
1303 // Find bounding set
1304 TMMBRSet* boundingSet = NULL;
1305 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1306 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001307 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001308 return -1;
1309 }
1310 // Set bounding set
1311 // Inform remote clients about the new bandwidth
1312 // inform the remote client
1313 _rtpRtcp.SetTMMBN(boundingSet);
1314
1315 // might trigger a TMMBN
1316 if (numBoundingSet == 0) {
1317 // owner of max bitrate request has timed out
1318 // empty bounding set has been sent
1319 return 0;
1320 }
1321 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001322 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001323 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001324 if (_cbRtcpBandwidthObserver) {
1325 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001326 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001327 }
1328 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001329}
1330
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001331void RTCPReceiver::RegisterRtcpStatisticsCallback(
1332 RtcpStatisticsCallback* callback) {
1333 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001334 stats_callback_ = callback;
1335}
1336
1337RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1338 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1339 return stats_callback_;
1340}
1341
niklase@google.com470e71d2011-07-07 08:21:25 +00001342// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001343void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001344 RTCPPacketInformation& rtcpPacketInformation) {
1345 // Process TMMBR and REMB first to avoid multiple callbacks
1346 // to OnNetworkChanged.
1347 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001348 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1349 UpdateTMMBR();
1350 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001351 unsigned int local_ssrc;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001352 {
1353 // We don't want to hold this critsect when triggering the callbacks below.
1354 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001355 local_ssrc = main_ssrc_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001356 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001357 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001358 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001359 _rtpRtcp.OnRequestSendReport();
1360 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001361 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001362 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001363 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001364 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001365 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001366 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001367 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001368 }
1369 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001370 // We need feedback that we have received a report block(s) so that we
1371 // can generate a new packet in a conference relay scenario, one received
1372 // report can generate several RTCP packets, based on number relayed/mixed
1373 // a send report block should go out to all receivers.
1374 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001375 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001376 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1377 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1378 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001379 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001380 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001381 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001382 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001383 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001384 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001385 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001386 }
1387 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1388 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001389 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001390 }
1391 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1392 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001393 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001394 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001395 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001396 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001397 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001398 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001399 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001400 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001401 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1402 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1403 }
Erik Språng242e22b2015-05-11 10:17:43 +02001404 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1405 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001406 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001407 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001408 rtcpPacketInformation.report_blocks,
1409 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001410 now);
1411 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001412 }
Erik Språng6b8d3552015-09-24 15:06:57 +02001413 if (_cbTransportFeedbackObserver &&
1414 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1415 uint32_t media_source_ssrc =
1416 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
1417 if (media_source_ssrc == main_ssrc_ ||
1418 registered_ssrcs_.find(media_source_ssrc) !=
1419 registered_ssrcs_.end()) {
1420 _cbTransportFeedbackObserver->OnTransportFeedback(
1421 *rtcpPacketInformation.transport_feedback_.get());
1422 }
1423 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001424 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001425
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001426 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001427 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1428 if (stats_callback_) {
1429 for (ReportBlockList::const_iterator it =
1430 rtcpPacketInformation.report_blocks.begin();
1431 it != rtcpPacketInformation.report_blocks.end();
1432 ++it) {
1433 RtcpStatistics stats;
1434 stats.cumulative_lost = it->cumulativeLost;
1435 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1436 stats.fraction_lost = it->fractionLost;
1437 stats.jitter = it->jitter;
1438
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001439 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001440 }
1441 }
1442 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001443}
1444
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001445int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001446 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001447 assert(cName);
1448
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001449 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1450 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001451 if (cnameInfo == NULL) {
1452 return -1;
1453 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001454 cName[RTCP_CNAME_SIZE - 1] = 0;
1455 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1456 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001457}
1458
1459// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001460int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1461 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001462 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001463 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001464
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001465 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001466 receiveInfoIt = _receivedInfoMap.begin();
1467 if (receiveInfoIt == _receivedInfoMap.end()) {
1468 return -1;
1469 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001470 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001471 if (candidateSet) {
1472 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1473 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1474 if (receiveInfo == NULL) {
1475 return 0;
1476 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001477 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001478 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001479 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001480 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001481 num++;
1482 }
1483 }
1484 receiveInfoIt++;
1485 }
1486 } else {
1487 while (receiveInfoIt != _receivedInfoMap.end()) {
1488 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1489 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001490 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001491 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001492 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001493 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001494 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001495 }
1496 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001497}
1498
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001499} // namespace webrtc