blob: 1bfa7cdebc3106b09514fb205ed87d13e00b05a2 [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
Peter Boströmfe7a80c2015-04-23 17:53:17 +020016#include "webrtc/base/checks.h"
Peter Boströmebc0b4e2015-10-28 16:39:33 +010017#include "webrtc/base/logging.h"
tommie4f96502015-10-20 23:00:48 -070018#include "webrtc/base/trace_event.h"
Erik Språng6b8d3552015-09-24 15:06:57 +020019#include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
tommie4f96502015-10-20 23:00:48 -070020#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.orga048d7c2013-05-29 14:27:38 +000021#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
Danil Chapovalova094fd12016-02-22 18:59:36 +010022#include "webrtc/modules/rtp_rtcp/source/time_util.h"
23#include "webrtc/system_wrappers/include/ntp_time.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000024
niklase@google.com470e71d2011-07-07 08:21:25 +000025namespace webrtc {
danilchap6a6f0892015-12-10 12:39:08 -080026using RTCPHelp::RTCPPacketInformation;
27using RTCPHelp::RTCPReceiveInformation;
28using RTCPHelp::RTCPReportBlockInformation;
29using RTCPUtility::kBtVoipMetric;
30using RTCPUtility::RTCPCnameInformation;
31using RTCPUtility::RTCPPacketReportBlockItem;
32using RTCPUtility::RTCPPacketTypes;
niklase@google.com470e71d2011-07-07 08:21:25 +000033
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +000034// The number of RTCP time intervals needed to trigger a timeout.
35const int kRrTimeoutIntervals = 3;
36
Erik Språng6b8d3552015-09-24 15:06:57 +020037const int64_t kMaxWarningLogIntervalMs = 10000;
38
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000039RTCPReceiver::RTCPReceiver(
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000040 Clock* clock,
Peter Boströmfe7a80c2015-04-23 17:53:17 +020041 bool receiver_only,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000042 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000043 RtcpBandwidthObserver* rtcp_bandwidth_observer,
44 RtcpIntraFrameObserver* rtcp_intra_frame_observer,
Erik Språng6b8d3552015-09-24 15:06:57 +020045 TransportFeedbackObserver* transport_feedback_observer,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000046 ModuleRtpRtcpImpl* owner)
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000047 : TMMBRHelp(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000048 _clock(clock),
Peter Boströmfe7a80c2015-04-23 17:53:17 +020049 receiver_only_(receiver_only),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000050 _lastReceived(0),
51 _rtpRtcp(*owner),
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +000052 _criticalSectionFeedbacks(
53 CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org96abda02015-02-25 13:50:10 +000054 _cbRtcpBandwidthObserver(rtcp_bandwidth_observer),
55 _cbRtcpIntraFrameObserver(rtcp_intra_frame_observer),
Erik Språng6b8d3552015-09-24 15:06:57 +020056 _cbTransportFeedbackObserver(transport_feedback_observer),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000057 _criticalSectionRTCPReceiver(
58 CriticalSectionWrapper::CreateCriticalSection()),
59 main_ssrc_(0),
60 _remoteSSRC(0),
61 _remoteSenderInfo(),
62 _lastReceivedSRNTPsecs(0),
63 _lastReceivedSRNTPfrac(0),
64 _lastReceivedXRNTPsecs(0),
65 _lastReceivedXRNTPfrac(0),
Danil Chapovalovc1e55c72016-03-09 15:14:35 +010066 xr_rrtr_status_(false),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000067 xr_rr_rtt_ms_(0),
68 _receivedInfoMap(),
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +000069 _lastReceivedRrMs(0),
70 _lastIncreasedSequenceNumberMs(0),
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +000071 stats_callback_(NULL),
Erik Språng6b8d3552015-09-24 15:06:57 +020072 packet_type_counter_observer_(packet_type_counter_observer),
73 num_skipped_packets_(0),
74 last_skipped_packets_warning_(clock->TimeInMilliseconds()) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +000075 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
niklase@google.com470e71d2011-07-07 08:21:25 +000076}
77
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000078RTCPReceiver::~RTCPReceiver() {
79 delete _criticalSectionRTCPReceiver;
80 delete _criticalSectionFeedbacks;
niklase@google.com470e71d2011-07-07 08:21:25 +000081
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +000082 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
83 for (; it != _receivedReportBlockMap.end(); ++it) {
84 ReportBlockInfoMap* info_map = &(it->second);
85 while (!info_map->empty()) {
86 ReportBlockInfoMap::iterator it_info = info_map->begin();
87 delete it_info->second;
88 info_map->erase(it_info);
89 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000090 }
91 while (!_receivedInfoMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000092 std::map<uint32_t, RTCPReceiveInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000093 _receivedInfoMap.begin();
94 delete first->second;
95 _receivedInfoMap.erase(first);
96 }
97 while (!_receivedCnameMap.empty()) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +000098 std::map<uint32_t, RTCPCnameInformation*>::iterator first =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +000099 _receivedCnameMap.begin();
100 delete first->second;
101 _receivedCnameMap.erase(first);
102 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000103}
104
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000105int64_t RTCPReceiver::LastReceived() {
106 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
107 return _lastReceived;
niklase@google.com470e71d2011-07-07 08:21:25 +0000108}
109
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000110int64_t RTCPReceiver::LastReceivedReceiverReport() const {
111 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
112 int64_t last_received_rr = -1;
113 for (ReceivedInfoMap::const_iterator it = _receivedInfoMap.begin();
114 it != _receivedInfoMap.end(); ++it) {
115 if (it->second->lastTimeReceived > last_received_rr) {
116 last_received_rr = it->second->lastTimeReceived;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000117 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000118 }
119 return last_received_rr;
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000120}
121
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000122void RTCPReceiver::SetRemoteSSRC(uint32_t ssrc) {
123 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000124
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000125 // new SSRC reset old reports
126 memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
127 _lastReceivedSRNTPsecs = 0;
128 _lastReceivedSRNTPfrac = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000129
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000130 _remoteSSRC = ssrc;
niklase@google.com470e71d2011-07-07 08:21:25 +0000131}
132
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000133uint32_t RTCPReceiver::RemoteSSRC() const {
134 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
135 return _remoteSSRC;
136}
137
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000138void RTCPReceiver::SetSsrcs(uint32_t main_ssrc,
139 const std::set<uint32_t>& registered_ssrcs) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000140 uint32_t old_ssrc = 0;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000141 {
niklase@google.com470e71d2011-07-07 08:21:25 +0000142 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000143 old_ssrc = main_ssrc_;
144 main_ssrc_ = main_ssrc;
145 registered_ssrcs_ = registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000146 }
147 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000148 if (_cbRtcpIntraFrameObserver && old_ssrc != main_ssrc) {
149 _cbRtcpIntraFrameObserver->OnLocalSsrcChanged(old_ssrc, main_ssrc);
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +0000150 }
151 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000152}
153
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000154int32_t RTCPReceiver::RTT(uint32_t remoteSSRC,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000155 int64_t* RTT,
156 int64_t* avgRTT,
157 int64_t* minRTT,
158 int64_t* maxRTT) const {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000159 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000160
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000161 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000162 GetReportBlockInformation(remoteSSRC, main_ssrc_);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000163
164 if (reportBlock == NULL) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000165 return -1;
166 }
167 if (RTT) {
168 *RTT = reportBlock->RTT;
169 }
170 if (avgRTT) {
171 *avgRTT = reportBlock->avgRTT;
172 }
173 if (minRTT) {
174 *minRTT = reportBlock->minRTT;
175 }
176 if (maxRTT) {
177 *maxRTT = reportBlock->maxRTT;
178 }
179 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000180}
181
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100182void RTCPReceiver::SetRtcpXrRrtrStatus(bool enable) {
183 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
184 xr_rrtr_status_ = enable;
185}
186
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000187bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000188 assert(rtt_ms);
189 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
190 if (xr_rr_rtt_ms_ == 0) {
191 return false;
192 }
193 *rtt_ms = xr_rr_rtt_ms_;
194 xr_rr_rtt_ms_ = 0;
195 return true;
196}
197
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000198// TODO(pbos): Make this fail when we haven't received NTP.
199bool RTCPReceiver::NTP(uint32_t* ReceivedNTPsecs,
200 uint32_t* ReceivedNTPfrac,
201 uint32_t* RTCPArrivalTimeSecs,
202 uint32_t* RTCPArrivalTimeFrac,
203 uint32_t* rtcp_timestamp) const
niklase@google.com470e71d2011-07-07 08:21:25 +0000204{
205 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
206 if(ReceivedNTPsecs)
207 {
208 *ReceivedNTPsecs = _remoteSenderInfo.NTPseconds; // NTP from incoming SendReport
209 }
210 if(ReceivedNTPfrac)
211 {
212 *ReceivedNTPfrac = _remoteSenderInfo.NTPfraction;
213 }
214 if(RTCPArrivalTimeFrac)
215 {
216 *RTCPArrivalTimeFrac = _lastReceivedSRNTPfrac; // local NTP time when we received a RTCP packet with a send block
217 }
218 if(RTCPArrivalTimeSecs)
219 {
220 *RTCPArrivalTimeSecs = _lastReceivedSRNTPsecs;
221 }
stefan@webrtc.org7c3523c2012-09-11 07:00:42 +0000222 if (rtcp_timestamp) {
223 *rtcp_timestamp = _remoteSenderInfo.RTPtimeStamp;
224 }
pbos@webrtc.org2f4b14e2014-07-15 15:25:39 +0000225 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000226}
227
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000228bool RTCPReceiver::LastReceivedXrReferenceTimeInfo(
229 RtcpReceiveTimeInfo* info) const {
230 assert(info);
231 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
232 if (_lastReceivedXRNTPsecs == 0 && _lastReceivedXRNTPfrac == 0) {
233 return false;
234 }
235
236 info->sourceSSRC = _remoteXRReceiveTimeInfo.sourceSSRC;
237 info->lastRR = _remoteXRReceiveTimeInfo.lastRR;
238
239 // Get the delay since last received report (RFC 3611).
240 uint32_t receive_time = RTCPUtility::MidNtp(_lastReceivedXRNTPsecs,
241 _lastReceivedXRNTPfrac);
242
243 uint32_t ntp_sec = 0;
244 uint32_t ntp_frac = 0;
245 _clock->CurrentNtp(ntp_sec, ntp_frac);
246 uint32_t now = RTCPUtility::MidNtp(ntp_sec, ntp_frac);
247
248 info->delaySinceLastRR = now - receive_time;
249 return true;
250}
251
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000252int32_t RTCPReceiver::SenderInfoReceived(RTCPSenderInfo* senderInfo) const {
253 assert(senderInfo);
254 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
255 if (_lastReceivedSRNTPsecs == 0) {
256 return -1;
257 }
258 memcpy(senderInfo, &(_remoteSenderInfo), sizeof(RTCPSenderInfo));
259 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000260}
261
262// statistics
263// we can get multiple receive reports when we receive the report from a CE
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000264int32_t RTCPReceiver::StatisticsReceived(
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000265 std::vector<RTCPReportBlock>* receiveBlocks) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000266 assert(receiveBlocks);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000267 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000268 ReportBlockMap::const_iterator it = _receivedReportBlockMap.begin();
269 for (; it != _receivedReportBlockMap.end(); ++it) {
270 const ReportBlockInfoMap* info_map = &(it->second);
271 ReportBlockInfoMap::const_iterator it_info = info_map->begin();
272 for (; it_info != info_map->end(); ++it_info) {
273 receiveBlocks->push_back(it_info->second->remoteReceiveBlock);
274 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000275 }
276 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000277}
278
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000279int32_t
niklase@google.com470e71d2011-07-07 08:21:25 +0000280RTCPReceiver::IncomingRTCPPacket(RTCPPacketInformation& rtcpPacketInformation,
281 RTCPUtility::RTCPParserV2* rtcpParser)
282{
283 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
284
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000285 _lastReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000286
asapersson@webrtc.orgd08d3892014-12-16 12:03:11 +0000287 if (packet_type_counter_.first_packet_time_ms == -1) {
288 packet_type_counter_.first_packet_time_ms = _lastReceived;
289 }
290
niklase@google.com470e71d2011-07-07 08:21:25 +0000291 RTCPUtility::RTCPPacketTypes pktType = rtcpParser->Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200292 while (pktType != RTCPPacketTypes::kInvalid) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000293 // Each "case" is responsible for iterate the parser to the
294 // next top level packet.
295 switch (pktType)
296 {
Erik Språng242e22b2015-05-11 10:17:43 +0200297 case RTCPPacketTypes::kSr:
298 case RTCPPacketTypes::kRr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000299 HandleSenderReceiverReport(*rtcpParser, rtcpPacketInformation);
300 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200301 case RTCPPacketTypes::kSdes:
Erik Språnga38233a2015-07-24 09:58:18 +0200302 HandleSDES(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000303 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200304 case RTCPPacketTypes::kXrHeader:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000305 HandleXrHeader(*rtcpParser, rtcpPacketInformation);
306 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200307 case RTCPPacketTypes::kXrReceiverReferenceTime:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000308 HandleXrReceiveReferenceTime(*rtcpParser, rtcpPacketInformation);
309 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200310 case RTCPPacketTypes::kXrDlrrReportBlock:
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000311 HandleXrDlrrReportBlock(*rtcpParser, rtcpPacketInformation);
312 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200313 case RTCPPacketTypes::kXrVoipMetric:
niklase@google.com470e71d2011-07-07 08:21:25 +0000314 HandleXRVOIPMetric(*rtcpParser, rtcpPacketInformation);
315 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200316 case RTCPPacketTypes::kBye:
niklase@google.com470e71d2011-07-07 08:21:25 +0000317 HandleBYE(*rtcpParser);
318 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200319 case RTCPPacketTypes::kRtpfbNack:
niklase@google.com470e71d2011-07-07 08:21:25 +0000320 HandleNACK(*rtcpParser, rtcpPacketInformation);
321 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200322 case RTCPPacketTypes::kRtpfbTmmbr:
niklase@google.com470e71d2011-07-07 08:21:25 +0000323 HandleTMMBR(*rtcpParser, rtcpPacketInformation);
324 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200325 case RTCPPacketTypes::kRtpfbTmmbn:
hta@webrtc.org9d54cd12012-04-30 08:24:55 +0000326 HandleTMMBN(*rtcpParser, rtcpPacketInformation);
niklase@google.com470e71d2011-07-07 08:21:25 +0000327 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200328 case RTCPPacketTypes::kRtpfbSrReq:
niklase@google.com470e71d2011-07-07 08:21:25 +0000329 HandleSR_REQ(*rtcpParser, rtcpPacketInformation);
330 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200331 case RTCPPacketTypes::kPsfbPli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000332 HandlePLI(*rtcpParser, rtcpPacketInformation);
333 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200334 case RTCPPacketTypes::kPsfbSli:
niklase@google.com470e71d2011-07-07 08:21:25 +0000335 HandleSLI(*rtcpParser, rtcpPacketInformation);
336 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200337 case RTCPPacketTypes::kPsfbRpsi:
niklase@google.com470e71d2011-07-07 08:21:25 +0000338 HandleRPSI(*rtcpParser, rtcpPacketInformation);
339 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200340 case RTCPPacketTypes::kExtendedIj:
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +0000341 HandleIJ(*rtcpParser, rtcpPacketInformation);
342 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200343 case RTCPPacketTypes::kPsfbFir:
niklase@google.com470e71d2011-07-07 08:21:25 +0000344 HandleFIR(*rtcpParser, rtcpPacketInformation);
345 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200346 case RTCPPacketTypes::kPsfbApp:
pwestin@webrtc.org741da942011-09-20 13:52:04 +0000347 HandlePsfbApp(*rtcpParser, rtcpPacketInformation);
348 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200349 case RTCPPacketTypes::kApp:
niklase@google.com470e71d2011-07-07 08:21:25 +0000350 // generic application messages
351 HandleAPP(*rtcpParser, rtcpPacketInformation);
352 break;
Erik Språng242e22b2015-05-11 10:17:43 +0200353 case RTCPPacketTypes::kAppItem:
niklase@google.com470e71d2011-07-07 08:21:25 +0000354 // generic application messages
355 HandleAPPItem(*rtcpParser, rtcpPacketInformation);
356 break;
Erik Språng6b8d3552015-09-24 15:06:57 +0200357 case RTCPPacketTypes::kTransportFeedback:
358 HandleTransportFeedback(rtcpParser, &rtcpPacketInformation);
359 break;
niklase@google.com470e71d2011-07-07 08:21:25 +0000360 default:
361 rtcpParser->Iterate();
362 break;
363 }
364 pktType = rtcpParser->PacketType();
365 }
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000366
367 if (packet_type_counter_observer_ != NULL) {
368 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
369 main_ssrc_, packet_type_counter_);
370 }
371
Erik Språng6b8d3552015-09-24 15:06:57 +0200372 num_skipped_packets_ += rtcpParser->NumSkippedBlocks();
373
374 int64_t now = _clock->TimeInMilliseconds();
375 if (now - last_skipped_packets_warning_ >= kMaxWarningLogIntervalMs &&
376 num_skipped_packets_ > 0) {
377 last_skipped_packets_warning_ = now;
378 LOG(LS_WARNING)
379 << num_skipped_packets_
380 << " RTCP blocks were skipped due to being malformed or of "
381 "unrecognized/unsupported type, during the past "
382 << (kMaxWarningLogIntervalMs / 1000) << " second period.";
383 }
384
niklase@google.com470e71d2011-07-07 08:21:25 +0000385 return 0;
386}
387
niklase@google.com470e71d2011-07-07 08:21:25 +0000388void
389RTCPReceiver::HandleSenderReceiverReport(RTCPUtility::RTCPParserV2& rtcpParser,
390 RTCPPacketInformation& rtcpPacketInformation)
391{
392 RTCPUtility::RTCPPacketTypes rtcpPacketType = rtcpParser.PacketType();
393 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
394
Erik Språng242e22b2015-05-11 10:17:43 +0200395 assert((rtcpPacketType == RTCPPacketTypes::kRr) ||
396 (rtcpPacketType == RTCPPacketTypes::kSr));
niklase@google.com470e71d2011-07-07 08:21:25 +0000397
398 // SR.SenderSSRC
399 // The synchronization source identifier for the originator of this SR packet
400
401 // rtcpPacket.RR.SenderSSRC
402 // The source of the packet sender, same as of SR? or is this a CE?
403
Erik Språng242e22b2015-05-11 10:17:43 +0200404 const uint32_t remoteSSRC = (rtcpPacketType == RTCPPacketTypes::kRr)
405 ? rtcpPacket.RR.SenderSSRC
406 : rtcpPacket.SR.SenderSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +0000407
408 rtcpPacketInformation.remoteSSRC = remoteSSRC;
409
410 RTCPReceiveInformation* ptrReceiveInfo = CreateReceiveInformation(remoteSSRC);
411 if (!ptrReceiveInfo)
412 {
413 rtcpParser.Iterate();
414 return;
415 }
416
Erik Språng242e22b2015-05-11 10:17:43 +0200417 if (rtcpPacketType == RTCPPacketTypes::kSr) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000418 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "SR",
419 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
elham@webrtc.orgb7eda432013-07-15 21:08:27 +0000420
niklase@google.com470e71d2011-07-07 08:21:25 +0000421 if (_remoteSSRC == remoteSSRC) // have I received RTP packets from this party
422 {
423 // only signal that we have received a SR when we accept one
424 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSr;
425
stefan@webrtc.org976a7e62012-09-21 13:20:21 +0000426 rtcpPacketInformation.ntp_secs = rtcpPacket.SR.NTPMostSignificant;
427 rtcpPacketInformation.ntp_frac = rtcpPacket.SR.NTPLeastSignificant;
428 rtcpPacketInformation.rtp_timestamp = rtcpPacket.SR.RTPTimestamp;
429
niklase@google.com470e71d2011-07-07 08:21:25 +0000430 // We will only store the send report from one source, but
431 // we will store all the receive block
432
433 // Save the NTP time of this report
434 _remoteSenderInfo.NTPseconds = rtcpPacket.SR.NTPMostSignificant;
435 _remoteSenderInfo.NTPfraction = rtcpPacket.SR.NTPLeastSignificant;
436 _remoteSenderInfo.RTPtimeStamp = rtcpPacket.SR.RTPTimestamp;
437 _remoteSenderInfo.sendPacketCount = rtcpPacket.SR.SenderPacketCount;
438 _remoteSenderInfo.sendOctetCount = rtcpPacket.SR.SenderOctetCount;
439
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000440 _clock->CurrentNtp(_lastReceivedSRNTPsecs, _lastReceivedSRNTPfrac);
niklase@google.com470e71d2011-07-07 08:21:25 +0000441 }
442 else
443 {
444 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
445 }
446 } else
447 {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000448 TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR",
449 "remote_ssrc", remoteSSRC, "ssrc", main_ssrc_);
niklase@google.com470e71d2011-07-07 08:21:25 +0000450
451 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRr;
452 }
453 UpdateReceiveInformation(*ptrReceiveInfo);
454
455 rtcpPacketType = rtcpParser.Iterate();
456
Erik Språng242e22b2015-05-11 10:17:43 +0200457 while (rtcpPacketType == RTCPPacketTypes::kReportBlockItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000458 HandleReportBlock(rtcpPacket, rtcpPacketInformation, remoteSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000459 rtcpPacketType = rtcpParser.Iterate();
460 }
461}
462
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000463void RTCPReceiver::HandleReportBlock(
464 const RTCPUtility::RTCPPacket& rtcpPacket,
465 RTCPPacketInformation& rtcpPacketInformation,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000466 uint32_t remoteSSRC)
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000467 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000468 // This will be called once per report block in the RTCP packet.
469 // We filter out all report blocks that are not for us.
470 // Each packet has max 31 RR blocks.
471 //
472 // We can calc RTT if we send a send report and get a report block back.
niklase@google.com470e71d2011-07-07 08:21:25 +0000473
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000474 // |rtcpPacket.ReportBlockItem.SSRC| is the SSRC identifier of the source to
475 // which the information in this reception report block pertains.
niklase@google.com470e71d2011-07-07 08:21:25 +0000476
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000477 // Filter out all report blocks that are not for us.
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000478 if (registered_ssrcs_.find(rtcpPacket.ReportBlockItem.SSRC) ==
479 registered_ssrcs_.end()) {
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000480 // This block is not for us ignore it.
481 return;
482 }
483
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000484 RTCPReportBlockInformation* reportBlock =
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000485 CreateOrGetReportBlockInformation(remoteSSRC,
486 rtcpPacket.ReportBlockItem.SSRC);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000487 if (reportBlock == NULL) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +0000488 LOG(LS_WARNING) << "Failed to CreateReportBlockInformation("
489 << remoteSSRC << ")";
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000490 return;
491 }
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000492
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000493 _lastReceivedRrMs = _clock->TimeInMilliseconds();
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000494 const RTCPPacketReportBlockItem& rb = rtcpPacket.ReportBlockItem;
495 reportBlock->remoteReceiveBlock.remoteSSRC = remoteSSRC;
496 reportBlock->remoteReceiveBlock.sourceSSRC = rb.SSRC;
497 reportBlock->remoteReceiveBlock.fractionLost = rb.FractionLost;
498 reportBlock->remoteReceiveBlock.cumulativeLost =
499 rb.CumulativeNumOfPacketsLost;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000500 if (rb.ExtendedHighestSequenceNumber >
501 reportBlock->remoteReceiveBlock.extendedHighSeqNum) {
502 // We have successfully delivered new RTP packets to the remote side after
503 // the last RR was sent from the remote side.
504 _lastIncreasedSequenceNumberMs = _lastReceivedRrMs;
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000505 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000506 reportBlock->remoteReceiveBlock.extendedHighSeqNum =
507 rb.ExtendedHighestSequenceNumber;
508 reportBlock->remoteReceiveBlock.jitter = rb.Jitter;
509 reportBlock->remoteReceiveBlock.delaySinceLastSR = rb.DelayLastSR;
510 reportBlock->remoteReceiveBlock.lastSR = rb.LastSR;
511
512 if (rtcpPacket.ReportBlockItem.Jitter > reportBlock->remoteMaxJitter) {
513 reportBlock->remoteMaxJitter = rtcpPacket.ReportBlockItem.Jitter;
514 }
515
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100516 int64_t rtt = 0;
Danil Chapovalova094fd12016-02-22 18:59:36 +0100517 uint32_t send_time = rtcpPacket.ReportBlockItem.LastSR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100518 // RFC3550, section 6.4.1, LSR field discription states:
519 // If no SR has been received yet, the field is set to zero.
520 // Receiver rtp_rtcp module is not expected to calculate rtt using
521 // Sender Reports even if it accidentally can.
522 if (!receiver_only_ && send_time != 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100523 uint32_t delay = rtcpPacket.ReportBlockItem.DelayLastSR;
524 // Local NTP time.
525 uint32_t receive_time = CompactNtp(NtpTime(*_clock));
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000526
Danil Chapovalova094fd12016-02-22 18:59:36 +0100527 // RTT in 1/(2^16) seconds.
528 uint32_t rtt_ntp = receive_time - delay - send_time;
529 // Convert to 1/1000 seconds (milliseconds).
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100530 rtt = CompactNtpRttToMs(rtt_ntp);
Danil Chapovalova094fd12016-02-22 18:59:36 +0100531 if (rtt > reportBlock->maxRTT) {
532 // Store max RTT.
533 reportBlock->maxRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000534 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000535 if (reportBlock->minRTT == 0) {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100536 // First RTT.
537 reportBlock->minRTT = rtt;
538 } else if (rtt < reportBlock->minRTT) {
539 // Store min RTT.
540 reportBlock->minRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000541 }
Danil Chapovalova094fd12016-02-22 18:59:36 +0100542 // Store last RTT.
543 reportBlock->RTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000544
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000545 // store average RTT
546 if (reportBlock->numAverageCalcs != 0) {
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000547 float ac = static_cast<float>(reportBlock->numAverageCalcs);
548 float newAverage =
Danil Chapovalova094fd12016-02-22 18:59:36 +0100549 ((ac / (ac + 1)) * reportBlock->avgRTT) + ((1 / (ac + 1)) * rtt);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000550 reportBlock->avgRTT = static_cast<int64_t>(newAverage + 0.5f);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000551 } else {
Danil Chapovalova094fd12016-02-22 18:59:36 +0100552 // First RTT.
553 reportBlock->avgRTT = rtt;
niklase@google.com470e71d2011-07-07 08:21:25 +0000554 }
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000555 reportBlock->numAverageCalcs++;
556 }
557
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000558 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RR_RTT", rb.SSRC,
Danil Chapovalova094fd12016-02-22 18:59:36 +0100559 rtt);
perkj@webrtc.orgce5990c2012-01-11 13:00:08 +0000560
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000561 rtcpPacketInformation.AddReportInfo(*reportBlock);
niklase@google.com470e71d2011-07-07 08:21:25 +0000562}
563
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000564RTCPReportBlockInformation* RTCPReceiver::CreateOrGetReportBlockInformation(
565 uint32_t remote_ssrc,
566 uint32_t source_ssrc) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000567 RTCPReportBlockInformation* info =
568 GetReportBlockInformation(remote_ssrc, source_ssrc);
569 if (info == NULL) {
570 info = new RTCPReportBlockInformation;
571 _receivedReportBlockMap[source_ssrc][remote_ssrc] = info;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000572 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000573 return info;
niklase@google.com470e71d2011-07-07 08:21:25 +0000574}
575
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000576RTCPReportBlockInformation* RTCPReceiver::GetReportBlockInformation(
577 uint32_t remote_ssrc,
578 uint32_t source_ssrc) const {
579 ReportBlockMap::const_iterator it = _receivedReportBlockMap.find(source_ssrc);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000580 if (it == _receivedReportBlockMap.end()) {
581 return NULL;
582 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000583 const ReportBlockInfoMap* info_map = &(it->second);
584 ReportBlockInfoMap::const_iterator it_info = info_map->find(remote_ssrc);
585 if (it_info == info_map->end()) {
586 return NULL;
587 }
588 return it_info->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000589}
590
591RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000592RTCPReceiver::CreateCnameInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000593 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000594
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000595 std::map<uint32_t, RTCPCnameInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000596 _receivedCnameMap.find(remoteSSRC);
597
598 if (it != _receivedCnameMap.end()) {
599 return it->second;
600 }
601 RTCPCnameInformation* cnameInfo = new RTCPCnameInformation;
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000602 memset(cnameInfo->name, 0, RTCP_CNAME_SIZE);
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000603 _receivedCnameMap[remoteSSRC] = cnameInfo;
604 return cnameInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000605}
606
607RTCPCnameInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000608RTCPReceiver::GetCnameInformation(uint32_t remoteSSRC) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000609 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000610
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000611 std::map<uint32_t, RTCPCnameInformation*>::const_iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000612 _receivedCnameMap.find(remoteSSRC);
613
614 if (it == _receivedCnameMap.end()) {
615 return NULL;
616 }
617 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000618}
619
620RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000621RTCPReceiver::CreateReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000622 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000623
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000624 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000625 _receivedInfoMap.find(remoteSSRC);
626
627 if (it != _receivedInfoMap.end()) {
628 return it->second;
629 }
630 RTCPReceiveInformation* receiveInfo = new RTCPReceiveInformation;
631 _receivedInfoMap[remoteSSRC] = receiveInfo;
632 return receiveInfo;
niklase@google.com470e71d2011-07-07 08:21:25 +0000633}
634
635RTCPReceiveInformation*
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000636RTCPReceiver::GetReceiveInformation(uint32_t remoteSSRC) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000637 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000638
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000639 std::map<uint32_t, RTCPReceiveInformation*>::iterator it =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000640 _receivedInfoMap.find(remoteSSRC);
641 if (it == _receivedInfoMap.end()) {
642 return NULL;
643 }
644 return it->second;
niklase@google.com470e71d2011-07-07 08:21:25 +0000645}
646
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000647void RTCPReceiver::UpdateReceiveInformation(
648 RTCPReceiveInformation& receiveInformation) {
649 // Update that this remote is alive
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000650 receiveInformation.lastTimeReceived = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000651}
652
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000653bool RTCPReceiver::RtcpRrTimeout(int64_t rtcp_interval_ms) {
654 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
655 if (_lastReceivedRrMs == 0)
656 return false;
657
658 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000659 if (_clock->TimeInMilliseconds() > _lastReceivedRrMs + time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000660 // Reset the timer to only trigger one log.
661 _lastReceivedRrMs = 0;
662 return true;
663 }
664 return false;
665}
666
667bool RTCPReceiver::RtcpRrSequenceNumberTimeout(int64_t rtcp_interval_ms) {
668 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
669 if (_lastIncreasedSequenceNumberMs == 0)
670 return false;
671
672 int64_t time_out_ms = kRrTimeoutIntervals * rtcp_interval_ms;
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +0000673 if (_clock->TimeInMilliseconds() > _lastIncreasedSequenceNumberMs +
stefan@webrtc.org20ed36d2013-01-17 14:01:20 +0000674 time_out_ms) {
mflodman@webrtc.org2f225ca2013-01-09 13:54:43 +0000675 // Reset the timer to only trigger one log.
676 _lastIncreasedSequenceNumberMs = 0;
677 return true;
678 }
679 return false;
680}
681
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000682bool RTCPReceiver::UpdateRTCPReceiveInformationTimers() {
683 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000684
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000685 bool updateBoundingSet = false;
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000686 int64_t timeNow = _clock->TimeInMilliseconds();
niklase@google.com470e71d2011-07-07 08:21:25 +0000687
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000688 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000689 _receivedInfoMap.begin();
niklase@google.com470e71d2011-07-07 08:21:25 +0000690
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000691 while (receiveInfoIt != _receivedInfoMap.end()) {
692 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
693 if (receiveInfo == NULL) {
694 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000695 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000696 // time since last received rtcp packet
697 // when we dont have a lastTimeReceived and the object is marked
698 // readyForDelete it's removed from the map
699 if (receiveInfo->lastTimeReceived) {
700 /// use audio define since we don't know what interval the remote peer is
701 // using
702 if ((timeNow - receiveInfo->lastTimeReceived) >
703 5 * RTCP_INTERVAL_AUDIO_MS) {
704 // no rtcp packet for the last five regular intervals, reset limitations
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000705 receiveInfo->TmmbrSet.clearSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000706 // prevent that we call this over and over again
707 receiveInfo->lastTimeReceived = 0;
708 // send new TMMBN to all channels using the default codec
709 updateBoundingSet = true;
710 }
711 receiveInfoIt++;
712 } else if (receiveInfo->readyForDelete) {
713 // store our current receiveInfoItem
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000714 std::map<uint32_t, RTCPReceiveInformation*>::iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000715 receiveInfoItemToBeErased = receiveInfoIt;
716 receiveInfoIt++;
717 delete receiveInfoItemToBeErased->second;
718 _receivedInfoMap.erase(receiveInfoItemToBeErased);
719 } else {
720 receiveInfoIt++;
721 }
722 }
723 return updateBoundingSet;
niklase@google.com470e71d2011-07-07 08:21:25 +0000724}
725
danilchap6db6cdc2015-12-15 02:54:47 -0800726int32_t RTCPReceiver::BoundingSet(bool* tmmbrOwner, TMMBRSet* boundingSetRec) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000727 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +0000728
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000729 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000730 _receivedInfoMap.find(_remoteSSRC);
731
732 if (receiveInfoIt == _receivedInfoMap.end()) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000733 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000734 }
735 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
736 if (receiveInfo == NULL) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000737 return -1;
738 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000739 if (receiveInfo->TmmbnBoundingSet.lengthOfSet() > 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000740 boundingSetRec->VerifyAndAllocateSet(
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000741 receiveInfo->TmmbnBoundingSet.lengthOfSet() + 1);
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000742 for(uint32_t i=0; i< receiveInfo->TmmbnBoundingSet.lengthOfSet();
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000743 i++) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000744 if(receiveInfo->TmmbnBoundingSet.Ssrc(i) == main_ssrc_) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000745 // owner of bounding set
danilchap6db6cdc2015-12-15 02:54:47 -0800746 *tmmbrOwner = true;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000747 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000748 boundingSetRec->SetEntry(i,
749 receiveInfo->TmmbnBoundingSet.Tmmbr(i),
750 receiveInfo->TmmbnBoundingSet.PacketOH(i),
751 receiveInfo->TmmbnBoundingSet.Ssrc(i));
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000752 }
753 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +0000754 return receiveInfo->TmmbnBoundingSet.lengthOfSet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000755}
756
Erik Språnga38233a2015-07-24 09:58:18 +0200757void RTCPReceiver::HandleSDES(RTCPUtility::RTCPParserV2& rtcpParser,
758 RTCPPacketInformation& rtcpPacketInformation) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000759 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200760 while (pktType == RTCPPacketTypes::kSdesChunk) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000761 HandleSDESChunk(rtcpParser);
762 pktType = rtcpParser.Iterate();
763 }
Erik Språnga38233a2015-07-24 09:58:18 +0200764 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSdes;
niklase@google.com470e71d2011-07-07 08:21:25 +0000765}
766
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000767void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
768 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
769 RTCPCnameInformation* cnameInfo =
770 CreateCnameInformation(rtcpPacket.CName.SenderSSRC);
771 assert(cnameInfo);
niklase@google.com470e71d2011-07-07 08:21:25 +0000772
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +0000773 cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
774 strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000775 {
776 CriticalSectionScoped lock(_criticalSectionFeedbacks);
777 if (stats_callback_ != NULL) {
778 stats_callback_->CNameChanged(rtcpPacket.CName.CName,
779 rtcpPacket.CName.SenderSSRC);
780 }
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000781 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000782}
783
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000784void RTCPReceiver::HandleNACK(RTCPUtility::RTCPParserV2& rtcpParser,
785 RTCPPacketInformation& rtcpPacketInformation) {
786 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
Peter Boströmfe7a80c2015-04-23 17:53:17 +0200787 if (receiver_only_ || main_ssrc_ != rtcpPacket.NACK.MediaSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000788 // Not to us.
789 rtcpParser.Iterate();
790 return;
791 }
792 rtcpPacketInformation.ResetNACKPacketIdArray();
niklase@google.com470e71d2011-07-07 08:21:25 +0000793
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000794 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +0200795 while (pktType == RTCPPacketTypes::kRtpfbNackItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000796 HandleNACKItem(rtcpPacket, rtcpPacketInformation);
797 pktType = rtcpParser.Iterate();
798 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000799
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000800 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack) {
801 ++packet_type_counter_.nack_packets;
802 packet_type_counter_.nack_requests = nack_stats_.requests();
803 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
804 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000805}
806
niklase@google.com470e71d2011-07-07 08:21:25 +0000807void
808RTCPReceiver::HandleNACKItem(const RTCPUtility::RTCPPacket& rtcpPacket,
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000809 RTCPPacketInformation& rtcpPacketInformation) {
810 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID);
811 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID);
niklase@google.com470e71d2011-07-07 08:21:25 +0000812
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000813 uint16_t bitMask = rtcpPacket.NACKItem.BitMask;
814 if (bitMask) {
815 for (int i=1; i <= 16; ++i) {
816 if (bitMask & 0x01) {
817 rtcpPacketInformation.AddNACKPacket(rtcpPacket.NACKItem.PacketID + i);
818 nack_stats_.ReportRequest(rtcpPacket.NACKItem.PacketID + i);
819 }
820 bitMask = bitMask >>1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000821 }
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000822 }
823 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpNack;
niklase@google.com470e71d2011-07-07 08:21:25 +0000824}
825
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000826void RTCPReceiver::HandleBYE(RTCPUtility::RTCPParserV2& rtcpParser) {
827 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000828
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000829 // clear our lists
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000830 ReportBlockMap::iterator it = _receivedReportBlockMap.begin();
831 for (; it != _receivedReportBlockMap.end(); ++it) {
832 ReportBlockInfoMap* info_map = &(it->second);
833 ReportBlockInfoMap::iterator it_info = info_map->find(
834 rtcpPacket.BYE.SenderSSRC);
835 if (it_info != info_map->end()) {
836 delete it_info->second;
837 info_map->erase(it_info);
838 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000839 }
asapersson@webrtc.orgcb791412014-12-18 14:30:32 +0000840
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000841 // we can't delete it due to TMMBR
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000842 std::map<uint32_t, RTCPReceiveInformation*>::iterator receiveInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000843 _receivedInfoMap.find(rtcpPacket.BYE.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +0000844
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000845 if (receiveInfoIt != _receivedInfoMap.end()) {
846 receiveInfoIt->second->readyForDelete = true;
847 }
848
pbos@webrtc.org2f446732013-04-08 11:08:41 +0000849 std::map<uint32_t, RTCPCnameInformation*>::iterator cnameInfoIt =
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000850 _receivedCnameMap.find(rtcpPacket.BYE.SenderSSRC);
851
852 if (cnameInfoIt != _receivedCnameMap.end()) {
853 delete cnameInfoIt->second;
854 _receivedCnameMap.erase(cnameInfoIt);
855 }
asapersson@webrtc.org7d6bd222013-10-31 12:14:34 +0000856 xr_rr_rtt_ms_ = 0;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +0000857 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000858}
859
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000860void RTCPReceiver::HandleXrHeader(
861 RTCPUtility::RTCPParserV2& parser,
862 RTCPPacketInformation& rtcpPacketInformation) {
863 const RTCPUtility::RTCPPacket& packet = parser.Packet();
864
865 rtcpPacketInformation.xr_originator_ssrc = packet.XR.OriginatorSSRC;
866
867 parser.Iterate();
868}
869
870void RTCPReceiver::HandleXrReceiveReferenceTime(
871 RTCPUtility::RTCPParserV2& parser,
872 RTCPPacketInformation& rtcpPacketInformation) {
873 const RTCPUtility::RTCPPacket& packet = parser.Packet();
874
875 _remoteXRReceiveTimeInfo.sourceSSRC =
876 rtcpPacketInformation.xr_originator_ssrc;
877
878 _remoteXRReceiveTimeInfo.lastRR = RTCPUtility::MidNtp(
879 packet.XRReceiverReferenceTimeItem.NTPMostSignificant,
880 packet.XRReceiverReferenceTimeItem.NTPLeastSignificant);
881
882 _clock->CurrentNtp(_lastReceivedXRNTPsecs, _lastReceivedXRNTPfrac);
883
884 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrReceiverReferenceTime;
885
886 parser.Iterate();
887}
888
889void RTCPReceiver::HandleXrDlrrReportBlock(
890 RTCPUtility::RTCPParserV2& parser,
891 RTCPPacketInformation& rtcpPacketInformation) {
892 const RTCPUtility::RTCPPacket& packet = parser.Packet();
893 // Iterate through sub-block(s), if any.
894 RTCPUtility::RTCPPacketTypes packet_type = parser.Iterate();
895
Erik Språng242e22b2015-05-11 10:17:43 +0200896 while (packet_type == RTCPPacketTypes::kXrDlrrReportBlockItem) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000897 HandleXrDlrrReportBlockItem(packet, rtcpPacketInformation);
898 packet_type = parser.Iterate();
899 }
900}
901
902void RTCPReceiver::HandleXrDlrrReportBlockItem(
903 const RTCPUtility::RTCPPacket& packet,
andresp@webrtc.org7fb75ec2013-12-20 20:20:50 +0000904 RTCPPacketInformation& rtcpPacketInformation)
905 EXCLUSIVE_LOCKS_REQUIRED(_criticalSectionRTCPReceiver) {
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000906 if (registered_ssrcs_.find(packet.XRDLRRReportBlockItem.SSRC) ==
907 registered_ssrcs_.end()) {
908 // Not to us.
909 return;
910 }
911
912 rtcpPacketInformation.xr_dlrr_item = true;
913
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100914 // Caller should explicitly enable rtt calculation using extended reports.
915 if (!xr_rrtr_status_)
916 return;
917
Danil Chapovalova094fd12016-02-22 18:59:36 +0100918 // The send_time and delay_rr fields are in units of 1/2^16 sec.
919 uint32_t send_time = packet.XRDLRRReportBlockItem.LastRR;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100920 // RFC3611, section 4.5, LRR field discription states:
Danil Chapovalova094fd12016-02-22 18:59:36 +0100921 // If no such block has been received, the field is set to zero.
922 if (send_time == 0)
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000923 return;
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000924
Danil Chapovalova094fd12016-02-22 18:59:36 +0100925 uint32_t delay_rr = packet.XRDLRRReportBlockItem.DelayLastRR;
926 uint32_t now = CompactNtp(NtpTime(*_clock));
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000927
Danil Chapovalova094fd12016-02-22 18:59:36 +0100928 uint32_t rtt_ntp = now - delay_rr - send_time;
Danil Chapovalovc1e55c72016-03-09 15:14:35 +0100929 xr_rr_rtt_ms_ = CompactNtpRttToMs(rtt_ntp);
asapersson@webrtc.org8469f7b2013-10-02 13:15:34 +0000930
931 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrDlrrReportBlock;
932}
933
niklase@google.com470e71d2011-07-07 08:21:25 +0000934void
935RTCPReceiver::HandleXRVOIPMetric(RTCPUtility::RTCPParserV2& rtcpParser,
936 RTCPPacketInformation& rtcpPacketInformation)
937{
938 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
939
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000940 if(rtcpPacket.XRVOIPMetricItem.SSRC == main_ssrc_)
niklase@google.com470e71d2011-07-07 08:21:25 +0000941 {
942 // Store VoIP metrics block if it's about me
943 // from OriginatorSSRC do we filter it?
944 // rtcpPacket.XR.OriginatorSSRC;
945
946 RTCPVoIPMetric receivedVoIPMetrics;
947 receivedVoIPMetrics.burstDensity = rtcpPacket.XRVOIPMetricItem.burstDensity;
948 receivedVoIPMetrics.burstDuration = rtcpPacket.XRVOIPMetricItem.burstDuration;
949 receivedVoIPMetrics.discardRate = rtcpPacket.XRVOIPMetricItem.discardRate;
950 receivedVoIPMetrics.endSystemDelay = rtcpPacket.XRVOIPMetricItem.endSystemDelay;
951 receivedVoIPMetrics.extRfactor = rtcpPacket.XRVOIPMetricItem.extRfactor;
952 receivedVoIPMetrics.gapDensity = rtcpPacket.XRVOIPMetricItem.gapDensity;
953 receivedVoIPMetrics.gapDuration = rtcpPacket.XRVOIPMetricItem.gapDuration;
954 receivedVoIPMetrics.Gmin = rtcpPacket.XRVOIPMetricItem.Gmin;
955 receivedVoIPMetrics.JBabsMax = rtcpPacket.XRVOIPMetricItem.JBabsMax;
956 receivedVoIPMetrics.JBmax = rtcpPacket.XRVOIPMetricItem.JBmax;
957 receivedVoIPMetrics.JBnominal = rtcpPacket.XRVOIPMetricItem.JBnominal;
958 receivedVoIPMetrics.lossRate = rtcpPacket.XRVOIPMetricItem.lossRate;
959 receivedVoIPMetrics.MOSCQ = rtcpPacket.XRVOIPMetricItem.MOSCQ;
960 receivedVoIPMetrics.MOSLQ = rtcpPacket.XRVOIPMetricItem.MOSLQ;
961 receivedVoIPMetrics.noiseLevel = rtcpPacket.XRVOIPMetricItem.noiseLevel;
962 receivedVoIPMetrics.RERL = rtcpPacket.XRVOIPMetricItem.RERL;
963 receivedVoIPMetrics.Rfactor = rtcpPacket.XRVOIPMetricItem.Rfactor;
964 receivedVoIPMetrics.roundTripDelay = rtcpPacket.XRVOIPMetricItem.roundTripDelay;
965 receivedVoIPMetrics.RXconfig = rtcpPacket.XRVOIPMetricItem.RXconfig;
966 receivedVoIPMetrics.signalLevel = rtcpPacket.XRVOIPMetricItem.signalLevel;
967
968 rtcpPacketInformation.AddVoIPMetric(&receivedVoIPMetrics);
969
970 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpXrVoipMetric; // received signal
971 }
972 rtcpParser.Iterate();
973}
974
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000975void RTCPReceiver::HandlePLI(RTCPUtility::RTCPParserV2& rtcpParser,
976 RTCPPacketInformation& rtcpPacketInformation) {
977 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
stefan@webrtc.org28a331e2013-09-17 07:49:56 +0000978 if (main_ssrc_ == rtcpPacket.PLI.MediaSSRC) {
sprang@webrtc.org0200f702015-02-16 12:06:00 +0000979 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "PLI");
justinlin@chromium.org7bfb3a32013-05-13 22:59:00 +0000980
asapersson@webrtc.org8098e072014-02-19 11:59:02 +0000981 ++packet_type_counter_.pli_packets;
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +0000982 // Received a signal that we need to send a new key frame.
983 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpPli;
984 }
985 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +0000986}
987
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000988void RTCPReceiver::HandleTMMBR(RTCPUtility::RTCPParserV2& rtcpParser,
989 RTCPPacketInformation& rtcpPacketInformation) {
990 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +0000991
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +0000992 uint32_t senderSSRC = rtcpPacket.TMMBR.SenderSSRC;
993 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(senderSSRC);
994 if (ptrReceiveInfo == NULL) {
995 // This remote SSRC must be saved before.
996 rtcpParser.Iterate();
997 return;
998 }
999 if (rtcpPacket.TMMBR.MediaSSRC) {
1000 // rtcpPacket.TMMBR.MediaSSRC SHOULD be 0 if same as SenderSSRC
1001 // in relay mode this is a valid number
1002 senderSSRC = rtcpPacket.TMMBR.MediaSSRC;
1003 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001004
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001005 // Use packet length to calc max number of TMMBR blocks
1006 // each TMMBR block is 8 bytes
1007 ptrdiff_t maxNumOfTMMBRBlocks = rtcpParser.LengthLeft() / 8;
niklase@google.com470e71d2011-07-07 08:21:25 +00001008
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001009 // sanity, we can't have more than what's in one packet
1010 if (maxNumOfTMMBRBlocks > 200) {
1011 assert(false);
1012 rtcpParser.Iterate();
1013 return;
1014 }
1015 ptrReceiveInfo->VerifyAndAllocateTMMBRSet((uint32_t)maxNumOfTMMBRBlocks);
niklase@google.com470e71d2011-07-07 08:21:25 +00001016
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001017 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001018 while (pktType == RTCPPacketTypes::kRtpfbTmmbrItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001019 HandleTMMBRItem(*ptrReceiveInfo, rtcpPacket, rtcpPacketInformation, senderSSRC);
1020 pktType = rtcpParser.Iterate();
1021 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001022}
1023
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001024void RTCPReceiver::HandleTMMBRItem(RTCPReceiveInformation& receiveInfo,
1025 const RTCPUtility::RTCPPacket& rtcpPacket,
1026 RTCPPacketInformation& rtcpPacketInformation,
1027 uint32_t senderSSRC) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001028 if (main_ssrc_ == rtcpPacket.TMMBRItem.SSRC &&
1029 rtcpPacket.TMMBRItem.MaxTotalMediaBitRate > 0) {
1030 receiveInfo.InsertTMMBRItem(senderSSRC, rtcpPacket.TMMBRItem,
1031 _clock->TimeInMilliseconds());
1032 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbr;
1033 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001034}
1035
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001036void RTCPReceiver::HandleTMMBN(RTCPUtility::RTCPParserV2& rtcpParser,
1037 RTCPPacketInformation& rtcpPacketInformation) {
1038 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1039 RTCPReceiveInformation* ptrReceiveInfo = GetReceiveInformation(
1040 rtcpPacket.TMMBN.SenderSSRC);
1041 if (ptrReceiveInfo == NULL) {
1042 // This remote SSRC must be saved before.
niklase@google.com470e71d2011-07-07 08:21:25 +00001043 rtcpParser.Iterate();
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001044 return;
1045 }
1046 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTmmbn;
1047 // Use packet length to calc max number of TMMBN blocks
1048 // each TMMBN block is 8 bytes
1049 ptrdiff_t maxNumOfTMMBNBlocks = rtcpParser.LengthLeft() / 8;
1050
1051 // sanity, we cant have more than what's in one packet
1052 if (maxNumOfTMMBNBlocks > 200) {
1053 assert(false);
1054 rtcpParser.Iterate();
1055 return;
1056 }
1057
1058 ptrReceiveInfo->VerifyAndAllocateBoundingSet((uint32_t)maxNumOfTMMBNBlocks);
1059
1060 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001061 while (pktType == RTCPPacketTypes::kRtpfbTmmbnItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001062 HandleTMMBNItem(*ptrReceiveInfo, rtcpPacket);
1063 pktType = rtcpParser.Iterate();
1064 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001065}
1066
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001067void RTCPReceiver::HandleSR_REQ(RTCPUtility::RTCPParserV2& rtcpParser,
1068 RTCPPacketInformation& rtcpPacketInformation) {
1069 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSrReq;
1070 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001071}
1072
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001073void RTCPReceiver::HandleTMMBNItem(RTCPReceiveInformation& receiveInfo,
1074 const RTCPUtility::RTCPPacket& rtcpPacket) {
1075 receiveInfo.TmmbnBoundingSet.AddEntry(
1076 rtcpPacket.TMMBNItem.MaxTotalMediaBitRate,
1077 rtcpPacket.TMMBNItem.MeasuredOverhead,
1078 rtcpPacket.TMMBNItem.SSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001079}
1080
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001081void RTCPReceiver::HandleSLI(RTCPUtility::RTCPParserV2& rtcpParser,
1082 RTCPPacketInformation& rtcpPacketInformation) {
1083 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1084 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001085 while (pktType == RTCPPacketTypes::kPsfbSliItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001086 HandleSLIItem(rtcpPacket, rtcpPacketInformation);
1087 pktType = rtcpParser.Iterate();
1088 }
1089}
1090
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001091void RTCPReceiver::HandleSLIItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1092 RTCPPacketInformation& rtcpPacketInformation) {
1093 // in theory there could be multiple slices lost
1094 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpSli; // received signal that we need to refresh a slice
1095 rtcpPacketInformation.sliPictureId = rtcpPacket.SLIItem.PictureId;
niklase@google.com470e71d2011-07-07 08:21:25 +00001096}
1097
1098void
1099RTCPReceiver::HandleRPSI(RTCPUtility::RTCPParserV2& rtcpParser,
1100 RTCPHelp::RTCPPacketInformation& rtcpPacketInformation)
1101{
1102 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001103 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001104 if (pktType == RTCPPacketTypes::kPsfbRpsi) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001105 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRpsi; // received signal that we have a confirmed reference picture
1106 if(rtcpPacket.RPSI.NumberOfValidBits%8 != 0)
1107 {
1108 // to us unknown
1109 // continue
1110 rtcpParser.Iterate();
1111 return;
1112 }
1113 rtcpPacketInformation.rpsiPictureId = 0;
1114
1115 // convert NativeBitString to rpsiPictureId
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001116 uint8_t numberOfBytes = rtcpPacket.RPSI.NumberOfValidBits /8;
1117 for(uint8_t n = 0; n < (numberOfBytes-1); n++)
niklase@google.com470e71d2011-07-07 08:21:25 +00001118 {
1119 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[n] & 0x7f);
1120 rtcpPacketInformation.rpsiPictureId <<= 7; // prepare next
1121 }
1122 rtcpPacketInformation.rpsiPictureId += (rtcpPacket.RPSI.NativeBitString[numberOfBytes-1] & 0x7f);
1123 }
1124}
1125
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001126void RTCPReceiver::HandlePsfbApp(RTCPUtility::RTCPParserV2& rtcpParser,
1127 RTCPPacketInformation& rtcpPacketInformation) {
1128 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001129 if (pktType == RTCPPacketTypes::kPsfbRemb) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001130 pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001131 if (pktType == RTCPPacketTypes::kPsfbRembItem) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001132 HandleREMBItem(rtcpParser, rtcpPacketInformation);
1133 rtcpParser.Iterate();
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001134 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001135 }
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001136}
1137
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001138void RTCPReceiver::HandleIJ(RTCPUtility::RTCPParserV2& rtcpParser,
1139 RTCPPacketInformation& rtcpPacketInformation) {
1140 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001141
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001142 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001143 while (pktType == RTCPPacketTypes::kExtendedIjItem) {
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001144 HandleIJItem(rtcpPacket, rtcpPacketInformation);
1145 pktType = rtcpParser.Iterate();
1146 }
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001147}
1148
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001149void RTCPReceiver::HandleIJItem(const RTCPUtility::RTCPPacket& rtcpPacket,
1150 RTCPPacketInformation& rtcpPacketInformation) {
1151 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpTransmissionTimeOffset;
1152 rtcpPacketInformation.interArrivalJitter =
1153 rtcpPacket.ExtendedJitterReportItem.Jitter;
asapersson@webrtc.org5249cc82011-12-16 14:31:37 +00001154}
1155
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001156void RTCPReceiver::HandleREMBItem(
1157 RTCPUtility::RTCPParserV2& rtcpParser,
1158 RTCPPacketInformation& rtcpPacketInformation) {
1159 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1160 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpRemb;
1161 rtcpPacketInformation.receiverEstimatedMaxBitrate =
1162 rtcpPacket.REMBItem.BitRate;
pwestin@webrtc.org741da942011-09-20 13:52:04 +00001163}
1164
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001165void RTCPReceiver::HandleFIR(RTCPUtility::RTCPParserV2& rtcpParser,
1166 RTCPPacketInformation& rtcpPacketInformation) {
1167 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
1168 RTCPReceiveInformation* ptrReceiveInfo =
1169 GetReceiveInformation(rtcpPacket.FIR.SenderSSRC);
niklase@google.com470e71d2011-07-07 08:21:25 +00001170
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001171 RTCPUtility::RTCPPacketTypes pktType = rtcpParser.Iterate();
Erik Språng242e22b2015-05-11 10:17:43 +02001172 while (pktType == RTCPPacketTypes::kPsfbFirItem) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001173 HandleFIRItem(ptrReceiveInfo, rtcpPacket, rtcpPacketInformation);
1174 pktType = rtcpParser.Iterate();
1175 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001176}
1177
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001178void RTCPReceiver::HandleFIRItem(RTCPReceiveInformation* receiveInfo,
1179 const RTCPUtility::RTCPPacket& rtcpPacket,
1180 RTCPPacketInformation& rtcpPacketInformation) {
1181 // Is it our sender that is requested to generate a new keyframe
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001182 if (main_ssrc_ != rtcpPacket.FIRItem.SSRC) {
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001183 return;
1184 }
asapersson@webrtc.org8098e072014-02-19 11:59:02 +00001185
1186 ++packet_type_counter_.fir_packets;
1187
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001188 // rtcpPacket.FIR.MediaSSRC SHOULD be 0 but we ignore to check it
1189 // we don't know who this originate from
1190 if (receiveInfo) {
1191 // check if we have reported this FIRSequenceNumber before
1192 if (rtcpPacket.FIRItem.CommandSequenceNumber !=
1193 receiveInfo->lastFIRSequenceNumber) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001194 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001195 // sanity; don't go crazy with the callbacks
1196 if ((now - receiveInfo->lastFIRRequest) > RTCP_MIN_FRAME_LENGTH_MS) {
1197 receiveInfo->lastFIRRequest = now;
1198 receiveInfo->lastFIRSequenceNumber =
1199 rtcpPacket.FIRItem.CommandSequenceNumber;
1200 // received signal that we need to send a new key frame
1201 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1202 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001203 }
pwestin@webrtc.orgb2179c22012-05-21 12:00:49 +00001204 } else {
1205 // received signal that we need to send a new key frame
1206 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpFir;
1207 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001208}
1209
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001210void RTCPReceiver::HandleAPP(RTCPUtility::RTCPParserV2& rtcpParser,
1211 RTCPPacketInformation& rtcpPacketInformation) {
1212 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001213
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001214 rtcpPacketInformation.rtcpPacketTypeFlags |= kRtcpApp;
1215 rtcpPacketInformation.applicationSubType = rtcpPacket.APP.SubType;
1216 rtcpPacketInformation.applicationName = rtcpPacket.APP.Name;
niklase@google.com470e71d2011-07-07 08:21:25 +00001217
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001218 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001219}
1220
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001221void RTCPReceiver::HandleAPPItem(RTCPUtility::RTCPParserV2& rtcpParser,
1222 RTCPPacketInformation& rtcpPacketInformation) {
1223 const RTCPUtility::RTCPPacket& rtcpPacket = rtcpParser.Packet();
niklase@google.com470e71d2011-07-07 08:21:25 +00001224
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001225 rtcpPacketInformation.AddApplicationData(rtcpPacket.APP.Data, rtcpPacket.APP.Size);
niklase@google.com470e71d2011-07-07 08:21:25 +00001226
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001227 rtcpParser.Iterate();
niklase@google.com470e71d2011-07-07 08:21:25 +00001228}
1229
Erik Språng6b8d3552015-09-24 15:06:57 +02001230void RTCPReceiver::HandleTransportFeedback(
1231 RTCPUtility::RTCPParserV2* rtcp_parser,
1232 RTCPHelp::RTCPPacketInformation* rtcp_packet_information) {
1233 rtcp::RtcpPacket* packet = rtcp_parser->ReleaseRtcpPacket();
1234 RTC_DCHECK(packet != nullptr);
1235 rtcp_packet_information->rtcpPacketTypeFlags |= kRtcpTransportFeedback;
1236 rtcp_packet_information->transport_feedback_.reset(
1237 static_cast<rtcp::TransportFeedback*>(packet));
1238
1239 rtcp_parser->Iterate();
1240}
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001241int32_t RTCPReceiver::UpdateTMMBR() {
1242 int32_t numBoundingSet = 0;
1243 uint32_t bitrate = 0;
1244 uint32_t accNumCandidates = 0;
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001245
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001246 int32_t size = TMMBRReceived(0, 0, NULL);
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001247 if (size > 0) {
1248 TMMBRSet* candidateSet = VerifyAndAllocateCandidateSet(size);
1249 // Get candidate set from receiver.
1250 accNumCandidates = TMMBRReceived(size, accNumCandidates, candidateSet);
1251 } else {
1252 // Candidate set empty.
1253 VerifyAndAllocateCandidateSet(0); // resets candidate set
1254 }
1255 // Find bounding set
1256 TMMBRSet* boundingSet = NULL;
1257 numBoundingSet = FindTMMBRBoundingSet(boundingSet);
1258 if (numBoundingSet == -1) {
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001259 LOG(LS_WARNING) << "Failed to find TMMBR bounding set.";
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001260 return -1;
1261 }
1262 // Set bounding set
1263 // Inform remote clients about the new bandwidth
1264 // inform the remote client
1265 _rtpRtcp.SetTMMBN(boundingSet);
1266
1267 // might trigger a TMMBN
1268 if (numBoundingSet == 0) {
1269 // owner of max bitrate request has timed out
1270 // empty bounding set has been sent
1271 return 0;
1272 }
1273 // Get net bitrate from bounding set depending on sent packet rate
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001274 if (CalcMinBitRate(&bitrate)) {
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001275 // we have a new bandwidth estimate on this channel
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001276 if (_cbRtcpBandwidthObserver) {
1277 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(bitrate * 1000);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001278 }
pwestin@webrtc.orgcac78782012-04-05 08:30:10 +00001279 }
1280 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001281}
1282
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001283void RTCPReceiver::RegisterRtcpStatisticsCallback(
1284 RtcpStatisticsCallback* callback) {
1285 CriticalSectionScoped cs(_criticalSectionFeedbacks);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001286 stats_callback_ = callback;
1287}
1288
1289RtcpStatisticsCallback* RTCPReceiver::GetRtcpStatisticsCallback() {
1290 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1291 return stats_callback_;
1292}
1293
niklase@google.com470e71d2011-07-07 08:21:25 +00001294// Holding no Critical section
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001295void RTCPReceiver::TriggerCallbacksFromRTCPPacket(
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001296 RTCPPacketInformation& rtcpPacketInformation) {
1297 // Process TMMBR and REMB first to avoid multiple callbacks
1298 // to OnNetworkChanged.
1299 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTmmbr) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001300 // Might trigger a OnReceivedBandwidthEstimateUpdate.
1301 UpdateTMMBR();
1302 }
sprang7dc39f32015-10-13 09:17:48 -07001303 uint32_t local_ssrc;
1304 std::set<uint32_t> registered_ssrcs;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001305 {
1306 // We don't want to hold this critsect when triggering the callbacks below.
1307 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001308 local_ssrc = main_ssrc_;
sprang7dc39f32015-10-13 09:17:48 -07001309 registered_ssrcs = registered_ssrcs_;
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001310 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001311 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001312 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSrReq)) {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001313 _rtpRtcp.OnRequestSendReport();
1314 }
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001315 if (!receiver_only_ &&
Erik Språng6b8d3552015-09-24 15:06:57 +02001316 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpNack)) {
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001317 if (rtcpPacketInformation.nackSequenceNumbers.size() > 0) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001318 LOG(LS_VERBOSE) << "Incoming NACK length: "
andresp@webrtc.orgdc80bae2014-04-08 11:06:12 +00001319 << rtcpPacketInformation.nackSequenceNumbers.size();
stefan@webrtc.orgbecf9c82013-02-01 15:09:57 +00001320 _rtpRtcp.OnReceivedNACK(rtcpPacketInformation.nackSequenceNumbers);
pwestin@webrtc.org3aa25de2012-01-05 08:40:56 +00001321 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001322 }
1323 {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001324 // We need feedback that we have received a report block(s) so that we
1325 // can generate a new packet in a conference relay scenario, one received
1326 // report can generate several RTCP packets, based on number relayed/mixed
1327 // a send report block should go out to all receivers.
1328 if (_cbRtcpIntraFrameObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001329 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001330 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) ||
1331 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpFir)) {
1332 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpPli) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001333 LOG(LS_VERBOSE) << "Incoming PLI from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001334 << rtcpPacketInformation.remoteSSRC;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001335 } else {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001336 LOG(LS_VERBOSE) << "Incoming FIR from SSRC "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001337 << rtcpPacketInformation.remoteSSRC;
niklase@google.com470e71d2011-07-07 08:21:25 +00001338 }
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001339 _cbRtcpIntraFrameObserver->OnReceivedIntraFrameRequest(local_ssrc);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001340 }
1341 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSli) {
1342 _cbRtcpIntraFrameObserver->OnReceivedSLI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001343 local_ssrc, rtcpPacketInformation.sliPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001344 }
1345 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRpsi) {
1346 _cbRtcpIntraFrameObserver->OnReceivedRPSI(
mflodman@webrtc.orgaca26292012-10-05 16:17:41 +00001347 local_ssrc, rtcpPacketInformation.rpsiPictureId);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001348 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001349 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001350 if (_cbRtcpBandwidthObserver) {
henrikg91d6ede2015-09-17 00:24:34 -07001351 RTC_DCHECK(!receiver_only_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001352 if (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRemb) {
andresp@webrtc.org4436b442014-06-04 09:05:30 +00001353 LOG(LS_VERBOSE) << "Incoming REMB: "
asapersson@webrtc.orgdf7b65b2015-01-21 13:07:04 +00001354 << rtcpPacketInformation.receiverEstimatedMaxBitrate;
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001355 _cbRtcpBandwidthObserver->OnReceivedEstimatedBitrate(
1356 rtcpPacketInformation.receiverEstimatedMaxBitrate);
1357 }
Erik Språng242e22b2015-05-11 10:17:43 +02001358 if ((rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpSr) ||
1359 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpRr)) {
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001360 int64_t now = _clock->TimeInMilliseconds();
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001361 _cbRtcpBandwidthObserver->OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +00001362 rtcpPacketInformation.report_blocks,
1363 rtcpPacketInformation.rtt,
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001364 now);
1365 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001366 }
Erik Språng6b8d3552015-09-24 15:06:57 +02001367 if (_cbTransportFeedbackObserver &&
1368 (rtcpPacketInformation.rtcpPacketTypeFlags & kRtcpTransportFeedback)) {
1369 uint32_t media_source_ssrc =
1370 rtcpPacketInformation.transport_feedback_->GetMediaSourceSsrc();
sprang7dc39f32015-10-13 09:17:48 -07001371 if (media_source_ssrc == local_ssrc ||
1372 registered_ssrcs.find(media_source_ssrc) != registered_ssrcs.end()) {
Erik Språng6b8d3552015-09-24 15:06:57 +02001373 _cbTransportFeedbackObserver->OnTransportFeedback(
1374 *rtcpPacketInformation.transport_feedback_.get());
1375 }
1376 }
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001377 }
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001378
Peter Boströmfe7a80c2015-04-23 17:53:17 +02001379 if (!receiver_only_) {
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001380 CriticalSectionScoped cs(_criticalSectionFeedbacks);
1381 if (stats_callback_) {
1382 for (ReportBlockList::const_iterator it =
1383 rtcpPacketInformation.report_blocks.begin();
1384 it != rtcpPacketInformation.report_blocks.end();
1385 ++it) {
1386 RtcpStatistics stats;
1387 stats.cumulative_lost = it->cumulativeLost;
1388 stats.extended_max_sequence_number = it->extendedHighSeqNum;
1389 stats.fraction_lost = it->fractionLost;
1390 stats.jitter = it->jitter;
1391
stefan@webrtc.org58e2d262014-08-14 15:10:49 +00001392 stats_callback_->StatisticsUpdated(stats, it->sourceSSRC);
sprang@webrtc.orga6ad6e52013-12-05 09:48:44 +00001393 }
1394 }
1395 }
niklase@google.com470e71d2011-07-07 08:21:25 +00001396}
1397
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001398int32_t RTCPReceiver::CNAME(uint32_t remoteSSRC,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001399 char cName[RTCP_CNAME_SIZE]) const {
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001400 assert(cName);
1401
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001402 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
1403 RTCPCnameInformation* cnameInfo = GetCnameInformation(remoteSSRC);
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +00001404 if (cnameInfo == NULL) {
1405 return -1;
1406 }
pwestin@webrtc.orgf6bb77a2012-01-24 17:16:59 +00001407 cName[RTCP_CNAME_SIZE - 1] = 0;
1408 strncpy(cName, cnameInfo->name, RTCP_CNAME_SIZE - 1);
1409 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +00001410}
1411
1412// no callbacks allowed inside this function
pbos@webrtc.orgd16e8392014-12-19 13:49:55 +00001413int32_t RTCPReceiver::TMMBRReceived(uint32_t size,
1414 uint32_t accNumCandidates,
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001415 TMMBRSet* candidateSet) const {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001416 CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
niklase@google.com470e71d2011-07-07 08:21:25 +00001417
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001418 std::map<uint32_t, RTCPReceiveInformation*>::const_iterator
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001419 receiveInfoIt = _receivedInfoMap.begin();
1420 if (receiveInfoIt == _receivedInfoMap.end()) {
1421 return -1;
1422 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001423 uint32_t num = accNumCandidates;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001424 if (candidateSet) {
1425 while( num < size && receiveInfoIt != _receivedInfoMap.end()) {
1426 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1427 if (receiveInfo == NULL) {
1428 return 0;
1429 }
pbos@webrtc.org2f446732013-04-08 11:08:41 +00001430 for (uint32_t i = 0;
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001431 (num < size) && (i < receiveInfo->TmmbrSet.lengthOfSet()); i++) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001432 if (receiveInfo->GetTMMBRSet(i, num, candidateSet,
stefan@webrtc.orga678a3b2013-01-21 07:42:11 +00001433 _clock->TimeInMilliseconds()) == 0) {
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001434 num++;
1435 }
1436 }
1437 receiveInfoIt++;
1438 }
1439 } else {
1440 while (receiveInfoIt != _receivedInfoMap.end()) {
1441 RTCPReceiveInformation* receiveInfo = receiveInfoIt->second;
1442 if(receiveInfo == NULL) {
niklase@google.com470e71d2011-07-07 08:21:25 +00001443 return -1;
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001444 }
hta@webrtc.org54536bb2012-05-03 14:07:23 +00001445 num += receiveInfo->TmmbrSet.lengthOfSet();
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001446 receiveInfoIt++;
niklase@google.com470e71d2011-07-07 08:21:25 +00001447 }
pwestin@webrtc.org26f8d9c2012-01-19 15:53:09 +00001448 }
1449 return num;
niklase@google.com470e71d2011-07-07 08:21:25 +00001450}
1451
pbos@webrtc.orgd900e8b2013-07-03 15:12:26 +00001452} // namespace webrtc