1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
11 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
12
13 #include <assert.h> // assert
14 #include <string.h> // memcpy
15
16 #include <algorithm> // min
17 #include <limits> // max
18 #include <utility>
19
20 #include "webrtc/base/checks.h"
21 #include "webrtc/base/logging.h"
22 #include "webrtc/base/trace_event.h"
23 #include "webrtc/common_types.h"
24 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
25 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h"
26 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h"
27 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
28 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/nack.h"
29 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/pli.h"
30 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
31 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/sli.h"
32 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbn.h"
33 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
34 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
35 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
36 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
37
38 namespace webrtc {
39
40 using RTCPUtility::RTCPCnameInformation;
41
NACKStringBuilder()42 NACKStringBuilder::NACKStringBuilder()
43 : stream_(""), count_(0), prevNack_(0), consecutive_(false) {}
44
~NACKStringBuilder()45 NACKStringBuilder::~NACKStringBuilder() {}
46
PushNACK(uint16_t nack)47 void NACKStringBuilder::PushNACK(uint16_t nack) {
48 if (count_ == 0) {
49 stream_ << nack;
50 } else if (nack == prevNack_ + 1) {
51 consecutive_ = true;
52 } else {
53 if (consecutive_) {
54 stream_ << "-" << prevNack_;
55 consecutive_ = false;
56 }
57 stream_ << "," << nack;
58 }
59 count_++;
60 prevNack_ = nack;
61 }
62
GetResult()63 std::string NACKStringBuilder::GetResult() {
64 if (consecutive_) {
65 stream_ << "-" << prevNack_;
66 consecutive_ = false;
67 }
68 return stream_.str();
69 }
70
FeedbackState()71 RTCPSender::FeedbackState::FeedbackState()
72 : send_payload_type(0),
73 frequency_hz(0),
74 packets_sent(0),
75 media_bytes_sent(0),
76 send_bitrate(0),
77 last_rr_ntp_secs(0),
78 last_rr_ntp_frac(0),
79 remote_sr(0),
80 has_last_xr_rr(false),
81 module(nullptr) {}
82
83 class PacketContainer : public rtcp::CompoundPacket,
84 public rtcp::RtcpPacket::PacketReadyCallback {
85 public:
PacketContainer(Transport * transport)86 explicit PacketContainer(Transport* transport)
87 : transport_(transport), bytes_sent_(0) {}
~PacketContainer()88 virtual ~PacketContainer() {
89 for (RtcpPacket* packet : appended_packets_)
90 delete packet;
91 }
92
OnPacketReady(uint8_t * data,size_t length)93 void OnPacketReady(uint8_t* data, size_t length) override {
94 if (transport_->SendRtcp(data, length))
95 bytes_sent_ += length;
96 }
97
SendPackets()98 size_t SendPackets() {
99 rtcp::CompoundPacket::Build(this);
100 return bytes_sent_;
101 }
102
103 private:
104 Transport* transport_;
105 size_t bytes_sent_;
106 };
107
108 class RTCPSender::RtcpContext {
109 public:
RtcpContext(const FeedbackState & feedback_state,int32_t nack_size,const uint16_t * nack_list,bool repeat,uint64_t picture_id,uint32_t ntp_sec,uint32_t ntp_frac,PacketContainer * container)110 RtcpContext(const FeedbackState& feedback_state,
111 int32_t nack_size,
112 const uint16_t* nack_list,
113 bool repeat,
114 uint64_t picture_id,
115 uint32_t ntp_sec,
116 uint32_t ntp_frac,
117 PacketContainer* container)
118 : feedback_state_(feedback_state),
119 nack_size_(nack_size),
120 nack_list_(nack_list),
121 repeat_(repeat),
122 picture_id_(picture_id),
123 ntp_sec_(ntp_sec),
124 ntp_frac_(ntp_frac),
125 container_(container) {}
126
~RtcpContext()127 virtual ~RtcpContext() {}
128
129 const FeedbackState& feedback_state_;
130 const int32_t nack_size_;
131 const uint16_t* nack_list_;
132 const bool repeat_;
133 const uint64_t picture_id_;
134 const uint32_t ntp_sec_;
135 const uint32_t ntp_frac_;
136
137 PacketContainer* const container_;
138 };
139
RTCPSender(bool audio,Clock * clock,ReceiveStatistics * receive_statistics,RtcpPacketTypeCounterObserver * packet_type_counter_observer,Transport * outgoing_transport)140 RTCPSender::RTCPSender(
141 bool audio,
142 Clock* clock,
143 ReceiveStatistics* receive_statistics,
144 RtcpPacketTypeCounterObserver* packet_type_counter_observer,
145 Transport* outgoing_transport)
146 : audio_(audio),
147 clock_(clock),
148 random_(clock_->TimeInMicroseconds()),
149 method_(RtcpMode::kOff),
150 transport_(outgoing_transport),
151
152 critical_section_rtcp_sender_(
153 CriticalSectionWrapper::CreateCriticalSection()),
154 using_nack_(false),
155 sending_(false),
156 remb_enabled_(false),
157 next_time_to_send_rtcp_(0),
158 start_timestamp_(0),
159 last_rtp_timestamp_(0),
160 last_frame_capture_time_ms_(-1),
161 ssrc_(0),
162 remote_ssrc_(0),
163 receive_statistics_(receive_statistics),
164
165 sequence_number_fir_(0),
166
167 remb_bitrate_(0),
168
169 tmmbr_help_(),
170 tmmbr_send_(0),
171 packet_oh_send_(0),
172
173 app_sub_type_(0),
174 app_name_(0),
175 app_data_(nullptr),
176 app_length_(0),
177
178 xr_send_receiver_reference_time_enabled_(false),
179 packet_type_counter_observer_(packet_type_counter_observer) {
180 memset(last_send_report_, 0, sizeof(last_send_report_));
181 memset(last_rtcp_time_, 0, sizeof(last_rtcp_time_));
182 RTC_DCHECK(transport_ != nullptr);
183
184 builders_[kRtcpSr] = &RTCPSender::BuildSR;
185 builders_[kRtcpRr] = &RTCPSender::BuildRR;
186 builders_[kRtcpSdes] = &RTCPSender::BuildSDES;
187 builders_[kRtcpPli] = &RTCPSender::BuildPLI;
188 builders_[kRtcpFir] = &RTCPSender::BuildFIR;
189 builders_[kRtcpSli] = &RTCPSender::BuildSLI;
190 builders_[kRtcpRpsi] = &RTCPSender::BuildRPSI;
191 builders_[kRtcpRemb] = &RTCPSender::BuildREMB;
192 builders_[kRtcpBye] = &RTCPSender::BuildBYE;
193 builders_[kRtcpApp] = &RTCPSender::BuildAPP;
194 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR;
195 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN;
196 builders_[kRtcpNack] = &RTCPSender::BuildNACK;
197 builders_[kRtcpXrVoipMetric] = &RTCPSender::BuildVoIPMetric;
198 builders_[kRtcpXrReceiverReferenceTime] =
199 &RTCPSender::BuildReceiverReferenceTime;
200 builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr;
201 }
202
~RTCPSender()203 RTCPSender::~RTCPSender() {}
204
Status() const205 RtcpMode RTCPSender::Status() const {
206 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
207 return method_;
208 }
209
SetRTCPStatus(RtcpMode method)210 void RTCPSender::SetRTCPStatus(RtcpMode method) {
211 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
212 method_ = method;
213
214 if (method == RtcpMode::kOff)
215 return;
216 next_time_to_send_rtcp_ =
217 clock_->TimeInMilliseconds() +
218 (audio_ ? RTCP_INTERVAL_AUDIO_MS / 2 : RTCP_INTERVAL_VIDEO_MS / 2);
219 }
220
Sending() const221 bool RTCPSender::Sending() const {
222 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
223 return sending_;
224 }
225
SetSendingStatus(const FeedbackState & feedback_state,bool sending)226 int32_t RTCPSender::SetSendingStatus(const FeedbackState& feedback_state,
227 bool sending) {
228 bool sendRTCPBye = false;
229 {
230 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
231
232 if (method_ != RtcpMode::kOff) {
233 if (sending == false && sending_ == true) {
234 // Trigger RTCP bye
235 sendRTCPBye = true;
236 }
237 }
238 sending_ = sending;
239 }
240 if (sendRTCPBye)
241 return SendRTCP(feedback_state, kRtcpBye);
242 return 0;
243 }
244
REMB() const245 bool RTCPSender::REMB() const {
246 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
247 return remb_enabled_;
248 }
249
SetREMBStatus(bool enable)250 void RTCPSender::SetREMBStatus(bool enable) {
251 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
252 remb_enabled_ = enable;
253 }
254
SetREMBData(uint32_t bitrate,const std::vector<uint32_t> & ssrcs)255 void RTCPSender::SetREMBData(uint32_t bitrate,
256 const std::vector<uint32_t>& ssrcs) {
257 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
258 remb_bitrate_ = bitrate;
259 remb_ssrcs_ = ssrcs;
260
261 if (remb_enabled_)
262 SetFlag(kRtcpRemb, false);
263 // Send a REMB immediately if we have a new REMB. The frequency of REMBs is
264 // throttled by the caller.
265 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds();
266 }
267
TMMBR() const268 bool RTCPSender::TMMBR() const {
269 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
270 return IsFlagPresent(RTCPPacketType::kRtcpTmmbr);
271 }
272
SetTMMBRStatus(bool enable)273 void RTCPSender::SetTMMBRStatus(bool enable) {
274 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
275 if (enable) {
276 SetFlag(RTCPPacketType::kRtcpTmmbr, false);
277 } else {
278 ConsumeFlag(RTCPPacketType::kRtcpTmmbr, true);
279 }
280 }
281
SetStartTimestamp(uint32_t start_timestamp)282 void RTCPSender::SetStartTimestamp(uint32_t start_timestamp) {
283 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
284 start_timestamp_ = start_timestamp;
285 }
286
SetLastRtpTime(uint32_t rtp_timestamp,int64_t capture_time_ms)287 void RTCPSender::SetLastRtpTime(uint32_t rtp_timestamp,
288 int64_t capture_time_ms) {
289 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
290 last_rtp_timestamp_ = rtp_timestamp;
291 if (capture_time_ms < 0) {
292 // We don't currently get a capture time from VoiceEngine.
293 last_frame_capture_time_ms_ = clock_->TimeInMilliseconds();
294 } else {
295 last_frame_capture_time_ms_ = capture_time_ms;
296 }
297 }
298
SetSSRC(uint32_t ssrc)299 void RTCPSender::SetSSRC(uint32_t ssrc) {
300 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
301
302 if (ssrc_ != 0) {
303 // not first SetSSRC, probably due to a collision
304 // schedule a new RTCP report
305 // make sure that we send a RTP packet
306 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + 100;
307 }
308 ssrc_ = ssrc;
309 }
310
SetRemoteSSRC(uint32_t ssrc)311 void RTCPSender::SetRemoteSSRC(uint32_t ssrc) {
312 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
313 remote_ssrc_ = ssrc;
314 }
315
SetCNAME(const char * c_name)316 int32_t RTCPSender::SetCNAME(const char* c_name) {
317 if (!c_name)
318 return -1;
319
320 RTC_DCHECK_LT(strlen(c_name), static_cast<size_t>(RTCP_CNAME_SIZE));
321 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
322 cname_ = c_name;
323 return 0;
324 }
325
AddMixedCNAME(uint32_t SSRC,const char * c_name)326 int32_t RTCPSender::AddMixedCNAME(uint32_t SSRC, const char* c_name) {
327 assert(c_name);
328 RTC_DCHECK_LT(strlen(c_name), static_cast<size_t>(RTCP_CNAME_SIZE));
329 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
330 if (csrc_cnames_.size() >= kRtpCsrcSize)
331 return -1;
332
333 csrc_cnames_[SSRC] = c_name;
334 return 0;
335 }
336
RemoveMixedCNAME(uint32_t SSRC)337 int32_t RTCPSender::RemoveMixedCNAME(uint32_t SSRC) {
338 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
339 auto it = csrc_cnames_.find(SSRC);
340
341 if (it == csrc_cnames_.end())
342 return -1;
343
344 csrc_cnames_.erase(it);
345 return 0;
346 }
347
TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const348 bool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const {
349 /*
350 For audio we use a fix 5 sec interval
351
352 For video we use 1 sec interval fo a BW smaller than 360 kbit/s,
353 technicaly we break the max 5% RTCP BW for video below 10 kbit/s but
354 that should be extremely rare
355
356
357 From RFC 3550
358
359 MAX RTCP BW is 5% if the session BW
360 A send report is approximately 65 bytes inc CNAME
361 A receiver report is approximately 28 bytes
362
363 The RECOMMENDED value for the reduced minimum in seconds is 360
364 divided by the session bandwidth in kilobits/second. This minimum
365 is smaller than 5 seconds for bandwidths greater than 72 kb/s.
366
367 If the participant has not yet sent an RTCP packet (the variable
368 initial is true), the constant Tmin is set to 2.5 seconds, else it
369 is set to 5 seconds.
370
371 The interval between RTCP packets is varied randomly over the
372 range [0.5,1.5] times the calculated interval to avoid unintended
373 synchronization of all participants
374
375 if we send
376 If the participant is a sender (we_sent true), the constant C is
377 set to the average RTCP packet size (avg_rtcp_size) divided by 25%
378 of the RTCP bandwidth (rtcp_bw), and the constant n is set to the
379 number of senders.
380
381 if we receive only
382 If we_sent is not true, the constant C is set
383 to the average RTCP packet size divided by 75% of the RTCP
384 bandwidth. The constant n is set to the number of receivers
385 (members - senders). If the number of senders is greater than
386 25%, senders and receivers are treated together.
387
388 reconsideration NOT required for peer-to-peer
389 "timer reconsideration" is
390 employed. This algorithm implements a simple back-off mechanism
391 which causes users to hold back RTCP packet transmission if the
392 group sizes are increasing.
393
394 n = number of members
395 C = avg_size/(rtcpBW/4)
396
397 3. The deterministic calculated interval Td is set to max(Tmin, n*C).
398
399 4. The calculated interval T is set to a number uniformly distributed
400 between 0.5 and 1.5 times the deterministic calculated interval.
401
402 5. The resulting value of T is divided by e-3/2=1.21828 to compensate
403 for the fact that the timer reconsideration algorithm converges to
404 a value of the RTCP bandwidth below the intended average
405 */
406
407 int64_t now = clock_->TimeInMilliseconds();
408
409 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
410
411 if (method_ == RtcpMode::kOff)
412 return false;
413
414 if (!audio_ && sendKeyframeBeforeRTP) {
415 // for video key-frames we want to send the RTCP before the large key-frame
416 // if we have a 100 ms margin
417 now += RTCP_SEND_BEFORE_KEY_FRAME_MS;
418 }
419
420 if (now >= next_time_to_send_rtcp_) {
421 return true;
422 } else if (now < 0x0000ffff &&
423 next_time_to_send_rtcp_ > 0xffff0000) { // 65 sec margin
424 // wrap
425 return true;
426 }
427 return false;
428 }
429
SendTimeOfSendReport(uint32_t sendReport)430 int64_t RTCPSender::SendTimeOfSendReport(uint32_t sendReport) {
431 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
432
433 // This is only saved when we are the sender
434 if ((last_send_report_[0] == 0) || (sendReport == 0)) {
435 return 0; // will be ignored
436 } else {
437 for (int i = 0; i < RTCP_NUMBER_OF_SR; ++i) {
438 if (last_send_report_[i] == sendReport)
439 return last_rtcp_time_[i];
440 }
441 }
442 return 0;
443 }
444
SendTimeOfXrRrReport(uint32_t mid_ntp,int64_t * time_ms) const445 bool RTCPSender::SendTimeOfXrRrReport(uint32_t mid_ntp,
446 int64_t* time_ms) const {
447 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
448
449 if (last_xr_rr_.empty()) {
450 return false;
451 }
452 std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp);
453 if (it == last_xr_rr_.end()) {
454 return false;
455 }
456 *time_ms = it->second;
457 return true;
458 }
459
BuildSR(const RtcpContext & ctx)460 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) {
461 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) {
462 // shift old
463 last_send_report_[i + 1] = last_send_report_[i];
464 last_rtcp_time_[i + 1] = last_rtcp_time_[i];
465 }
466
467 last_rtcp_time_[0] = Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_);
468 last_send_report_[0] = (ctx.ntp_sec_ << 16) + (ctx.ntp_frac_ >> 16);
469
470 // The timestamp of this RTCP packet should be estimated as the timestamp of
471 // the frame being captured at this moment. We are calculating that
472 // timestamp as the last frame's timestamp + the time since the last frame
473 // was captured.
474 uint32_t rtp_timestamp =
475 start_timestamp_ + last_rtp_timestamp_ +
476 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) *
477 (ctx.feedback_state_.frequency_hz / 1000);
478
479 rtcp::SenderReport* report = new rtcp::SenderReport();
480 report->From(ssrc_);
481 report->WithNtpSec(ctx.ntp_sec_);
482 report->WithNtpFrac(ctx.ntp_frac_);
483 report->WithRtpTimestamp(rtp_timestamp);
484 report->WithPacketCount(ctx.feedback_state_.packets_sent);
485 report->WithOctetCount(ctx.feedback_state_.media_bytes_sent);
486
487 for (auto it : report_blocks_)
488 report->WithReportBlock(it.second);
489
490 report_blocks_.clear();
491
492 return rtc::scoped_ptr<rtcp::SenderReport>(report);
493 }
494
BuildSDES(const RtcpContext & ctx)495 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSDES(
496 const RtcpContext& ctx) {
497 size_t length_cname = cname_.length();
498 RTC_CHECK_LT(length_cname, static_cast<size_t>(RTCP_CNAME_SIZE));
499
500 rtcp::Sdes* sdes = new rtcp::Sdes();
501 sdes->WithCName(ssrc_, cname_);
502
503 for (const auto it : csrc_cnames_)
504 sdes->WithCName(it.first, it.second);
505
506 return rtc::scoped_ptr<rtcp::Sdes>(sdes);
507 }
508
BuildRR(const RtcpContext & ctx)509 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildRR(const RtcpContext& ctx) {
510 rtcp::ReceiverReport* report = new rtcp::ReceiverReport();
511 report->From(ssrc_);
512 for (auto it : report_blocks_)
513 report->WithReportBlock(it.second);
514
515 report_blocks_.clear();
516 return rtc::scoped_ptr<rtcp::ReceiverReport>(report);
517 }
518
BuildPLI(const RtcpContext & ctx)519 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildPLI(const RtcpContext& ctx) {
520 rtcp::Pli* pli = new rtcp::Pli();
521 pli->From(ssrc_);
522 pli->To(remote_ssrc_);
523
524 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
525 "RTCPSender::PLI");
526 ++packet_type_counter_.pli_packets;
527 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_PLICount",
528 ssrc_, packet_type_counter_.pli_packets);
529
530 return rtc::scoped_ptr<rtcp::Pli>(pli);
531 }
532
BuildFIR(const RtcpContext & ctx)533 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildFIR(const RtcpContext& ctx) {
534 if (!ctx.repeat_)
535 ++sequence_number_fir_; // Do not increase if repetition.
536
537 rtcp::Fir* fir = new rtcp::Fir();
538 fir->From(ssrc_);
539 fir->To(remote_ssrc_);
540 fir->WithCommandSeqNum(sequence_number_fir_);
541
542 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
543 "RTCPSender::FIR");
544 ++packet_type_counter_.fir_packets;
545 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_FIRCount",
546 ssrc_, packet_type_counter_.fir_packets);
547
548 return rtc::scoped_ptr<rtcp::Fir>(fir);
549 }
550
551 /*
552 0 1 2 3
553 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
554 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
555 | First | Number | PictureID |
556 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
557 */
BuildSLI(const RtcpContext & ctx)558 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSLI(const RtcpContext& ctx) {
559 rtcp::Sli* sli = new rtcp::Sli();
560 sli->From(ssrc_);
561 sli->To(remote_ssrc_);
562 // Crop picture id to 6 least significant bits.
563 sli->WithPictureId(ctx.picture_id_ & 0x3F);
564
565 return rtc::scoped_ptr<rtcp::Sli>(sli);
566 }
567
568 /*
569 0 1 2 3
570 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
571 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
572 | PB |0| Payload Type| Native RPSI bit string |
573 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
574 | defined per codec ... | Padding (0) |
575 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
576 */
577 /*
578 * Note: not generic made for VP8
579 */
BuildRPSI(const RtcpContext & ctx)580 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildRPSI(
581 const RtcpContext& ctx) {
582 if (ctx.feedback_state_.send_payload_type == 0xFF)
583 return nullptr;
584
585 rtcp::Rpsi* rpsi = new rtcp::Rpsi();
586 rpsi->From(ssrc_);
587 rpsi->To(remote_ssrc_);
588 rpsi->WithPayloadType(ctx.feedback_state_.send_payload_type);
589 rpsi->WithPictureId(ctx.picture_id_);
590
591 return rtc::scoped_ptr<rtcp::Rpsi>(rpsi);
592 }
593
BuildREMB(const RtcpContext & ctx)594 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildREMB(
595 const RtcpContext& ctx) {
596 rtcp::Remb* remb = new rtcp::Remb();
597 remb->From(ssrc_);
598 for (uint32_t ssrc : remb_ssrcs_)
599 remb->AppliesTo(ssrc);
600 remb->WithBitrateBps(remb_bitrate_);
601
602 TRACE_EVENT_INSTANT0(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
603 "RTCPSender::REMB");
604
605 return rtc::scoped_ptr<rtcp::Remb>(remb);
606 }
607
SetTargetBitrate(unsigned int target_bitrate)608 void RTCPSender::SetTargetBitrate(unsigned int target_bitrate) {
609 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
610 tmmbr_send_ = target_bitrate / 1000;
611 }
612
BuildTMMBR(const RtcpContext & ctx)613 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildTMMBR(
614 const RtcpContext& ctx) {
615 if (ctx.feedback_state_.module == nullptr)
616 return nullptr;
617 // Before sending the TMMBR check the received TMMBN, only an owner is
618 // allowed to raise the bitrate:
619 // * If the sender is an owner of the TMMBN -> send TMMBR
620 // * If not an owner but the TMMBR would enter the TMMBN -> send TMMBR
621
622 // get current bounding set from RTCP receiver
623 bool tmmbrOwner = false;
624 // store in candidateSet, allocates one extra slot
625 TMMBRSet* candidateSet = tmmbr_help_.CandidateSet();
626
627 // holding critical_section_rtcp_sender_ while calling RTCPreceiver which
628 // will accuire criticalSectionRTCPReceiver_ is a potental deadlock but
629 // since RTCPreceiver is not doing the reverse we should be fine
630 int32_t lengthOfBoundingSet =
631 ctx.feedback_state_.module->BoundingSet(&tmmbrOwner, candidateSet);
632
633 if (lengthOfBoundingSet > 0) {
634 for (int32_t i = 0; i < lengthOfBoundingSet; i++) {
635 if (candidateSet->Tmmbr(i) == tmmbr_send_ &&
636 candidateSet->PacketOH(i) == packet_oh_send_) {
637 // Do not send the same tuple.
638 return nullptr;
639 }
640 }
641 if (!tmmbrOwner) {
642 // use received bounding set as candidate set
643 // add current tuple
644 candidateSet->SetEntry(lengthOfBoundingSet, tmmbr_send_, packet_oh_send_,
645 ssrc_);
646 int numCandidates = lengthOfBoundingSet + 1;
647
648 // find bounding set
649 TMMBRSet* boundingSet = nullptr;
650 int numBoundingSet = tmmbr_help_.FindTMMBRBoundingSet(boundingSet);
651 if (numBoundingSet > 0 || numBoundingSet <= numCandidates)
652 tmmbrOwner = tmmbr_help_.IsOwner(ssrc_, numBoundingSet);
653 if (!tmmbrOwner) {
654 // Did not enter bounding set, no meaning to send this request.
655 return nullptr;
656 }
657 }
658 }
659
660 if (!tmmbr_send_)
661 return nullptr;
662
663 rtcp::Tmmbr* tmmbr = new rtcp::Tmmbr();
664 tmmbr->From(ssrc_);
665 tmmbr->To(remote_ssrc_);
666 tmmbr->WithBitrateKbps(tmmbr_send_);
667 tmmbr->WithOverhead(packet_oh_send_);
668
669 return rtc::scoped_ptr<rtcp::Tmmbr>(tmmbr);
670 }
671
BuildTMMBN(const RtcpContext & ctx)672 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildTMMBN(
673 const RtcpContext& ctx) {
674 TMMBRSet* boundingSet = tmmbr_help_.BoundingSetToSend();
675 if (boundingSet == nullptr)
676 return nullptr;
677
678 rtcp::Tmmbn* tmmbn = new rtcp::Tmmbn();
679 tmmbn->From(ssrc_);
680 for (uint32_t i = 0; i < boundingSet->lengthOfSet(); i++) {
681 if (boundingSet->Tmmbr(i) > 0) {
682 tmmbn->WithTmmbr(boundingSet->Ssrc(i), boundingSet->Tmmbr(i),
683 boundingSet->PacketOH(i));
684 }
685 }
686
687 return rtc::scoped_ptr<rtcp::Tmmbn>(tmmbn);
688 }
689
BuildAPP(const RtcpContext & ctx)690 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildAPP(const RtcpContext& ctx) {
691 rtcp::App* app = new rtcp::App();
692 app->From(ssrc_);
693 app->WithSubType(app_sub_type_);
694 app->WithName(app_name_);
695 app->WithData(app_data_.get(), app_length_);
696
697 return rtc::scoped_ptr<rtcp::App>(app);
698 }
699
BuildNACK(const RtcpContext & ctx)700 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildNACK(
701 const RtcpContext& ctx) {
702 rtcp::Nack* nack = new rtcp::Nack();
703 nack->From(ssrc_);
704 nack->To(remote_ssrc_);
705 nack->WithList(ctx.nack_list_, ctx.nack_size_);
706
707 // Report stats.
708 NACKStringBuilder stringBuilder;
709 for (int idx = 0; idx < ctx.nack_size_; ++idx) {
710 stringBuilder.PushNACK(ctx.nack_list_[idx]);
711 nack_stats_.ReportRequest(ctx.nack_list_[idx]);
712 }
713 packet_type_counter_.nack_requests = nack_stats_.requests();
714 packet_type_counter_.unique_nack_requests = nack_stats_.unique_requests();
715
716 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"),
717 "RTCPSender::NACK", "nacks",
718 TRACE_STR_COPY(stringBuilder.GetResult().c_str()));
719 ++packet_type_counter_.nack_packets;
720 TRACE_COUNTER_ID1(TRACE_DISABLED_BY_DEFAULT("webrtc_rtp"), "RTCP_NACKCount",
721 ssrc_, packet_type_counter_.nack_packets);
722
723 return rtc::scoped_ptr<rtcp::Nack>(nack);
724 }
725
BuildBYE(const RtcpContext & ctx)726 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildBYE(const RtcpContext& ctx) {
727 rtcp::Bye* bye = new rtcp::Bye();
728 bye->From(ssrc_);
729 for (uint32_t csrc : csrcs_)
730 bye->WithCsrc(csrc);
731
732 return rtc::scoped_ptr<rtcp::Bye>(bye);
733 }
734
BuildReceiverReferenceTime(const RtcpContext & ctx)735 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildReceiverReferenceTime(
736 const RtcpContext& ctx) {
737 if (last_xr_rr_.size() >= RTCP_NUMBER_OF_SR)
738 last_xr_rr_.erase(last_xr_rr_.begin());
739 last_xr_rr_.insert(std::pair<uint32_t, int64_t>(
740 RTCPUtility::MidNtp(ctx.ntp_sec_, ctx.ntp_frac_),
741 Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_)));
742
743 rtcp::Xr* xr = new rtcp::Xr();
744 xr->From(ssrc_);
745
746 rtcp::Rrtr rrtr;
747 rrtr.WithNtp(NtpTime(ctx.ntp_sec_, ctx.ntp_frac_));
748
749 xr->WithRrtr(&rrtr);
750
751 // TODO(sprang): Merge XR report sending to contain all of RRTR, DLRR, VOIP?
752
753 return rtc::scoped_ptr<rtcp::Xr>(xr);
754 }
755
BuildDlrr(const RtcpContext & ctx)756 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildDlrr(
757 const RtcpContext& ctx) {
758 rtcp::Xr* xr = new rtcp::Xr();
759 xr->From(ssrc_);
760
761 rtcp::Dlrr dlrr;
762 const RtcpReceiveTimeInfo& info = ctx.feedback_state_.last_xr_rr;
763 dlrr.WithDlrrItem(info.sourceSSRC, info.lastRR, info.delaySinceLastRR);
764
765 xr->WithDlrr(&dlrr);
766
767 return rtc::scoped_ptr<rtcp::Xr>(xr);
768 }
769
770 // TODO(sprang): Add a unit test for this, or remove if the code isn't used.
BuildVoIPMetric(const RtcpContext & context)771 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildVoIPMetric(
772 const RtcpContext& context) {
773 rtcp::Xr* xr = new rtcp::Xr();
774 xr->From(ssrc_);
775
776 rtcp::VoipMetric voip;
777 voip.To(remote_ssrc_);
778 voip.WithVoipMetric(xr_voip_metric_);
779
780 xr->WithVoipMetric(&voip);
781
782 return rtc::scoped_ptr<rtcp::Xr>(xr);
783 }
784
SendRTCP(const FeedbackState & feedback_state,RTCPPacketType packetType,int32_t nack_size,const uint16_t * nack_list,bool repeat,uint64_t pictureID)785 int32_t RTCPSender::SendRTCP(const FeedbackState& feedback_state,
786 RTCPPacketType packetType,
787 int32_t nack_size,
788 const uint16_t* nack_list,
789 bool repeat,
790 uint64_t pictureID) {
791 return SendCompoundRTCP(
792 feedback_state, std::set<RTCPPacketType>(&packetType, &packetType + 1),
793 nack_size, nack_list, repeat, pictureID);
794 }
795
SendCompoundRTCP(const FeedbackState & feedback_state,const std::set<RTCPPacketType> & packet_types,int32_t nack_size,const uint16_t * nack_list,bool repeat,uint64_t pictureID)796 int32_t RTCPSender::SendCompoundRTCP(
797 const FeedbackState& feedback_state,
798 const std::set<RTCPPacketType>& packet_types,
799 int32_t nack_size,
800 const uint16_t* nack_list,
801 bool repeat,
802 uint64_t pictureID) {
803 PacketContainer container(transport_);
804 {
805 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
806 if (method_ == RtcpMode::kOff) {
807 LOG(LS_WARNING) << "Can't send rtcp if it is disabled.";
808 return -1;
809 }
810
811 // We need to send our NTP even if we haven't received any reports.
812 uint32_t ntp_sec;
813 uint32_t ntp_frac;
814 clock_->CurrentNtp(ntp_sec, ntp_frac);
815 RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID,
816 ntp_sec, ntp_frac, &container);
817
818 PrepareReport(packet_types, feedback_state);
819
820 auto it = report_flags_.begin();
821 while (it != report_flags_.end()) {
822 auto builder_it = builders_.find(it->type);
823 RTC_DCHECK(builder_it != builders_.end());
824 if (it->is_volatile) {
825 report_flags_.erase(it++);
826 } else {
827 ++it;
828 }
829
830 BuilderFunc func = builder_it->second;
831 rtc::scoped_ptr<rtcp::RtcpPacket> packet = (this->*func)(context);
832 if (packet.get() == nullptr)
833 return -1;
834 container.Append(packet.release());
835 }
836
837 if (packet_type_counter_observer_ != nullptr) {
838 packet_type_counter_observer_->RtcpPacketTypesCounterUpdated(
839 remote_ssrc_, packet_type_counter_);
840 }
841
842 RTC_DCHECK(AllVolatileFlagsConsumed());
843 }
844
845 size_t bytes_sent = container.SendPackets();
846 return bytes_sent == 0 ? -1 : 0;
847 }
848
PrepareReport(const std::set<RTCPPacketType> & packetTypes,const FeedbackState & feedback_state)849 void RTCPSender::PrepareReport(const std::set<RTCPPacketType>& packetTypes,
850 const FeedbackState& feedback_state) {
851 // Add all flags as volatile. Non volatile entries will not be overwritten
852 // and all new volatile flags added will be consumed by the end of this call.
853 SetFlags(packetTypes, true);
854
855 if (packet_type_counter_.first_packet_time_ms == -1)
856 packet_type_counter_.first_packet_time_ms = clock_->TimeInMilliseconds();
857
858 bool generate_report;
859 if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) {
860 // Report type already explicitly set, don't automatically populate.
861 generate_report = true;
862 RTC_DCHECK(ConsumeFlag(kRtcpReport) == false);
863 } else {
864 generate_report =
865 (ConsumeFlag(kRtcpReport) && method_ == RtcpMode::kReducedSize) ||
866 method_ == RtcpMode::kCompound;
867 if (generate_report)
868 SetFlag(sending_ ? kRtcpSr : kRtcpRr, true);
869 }
870
871 if (IsFlagPresent(kRtcpSr) || (IsFlagPresent(kRtcpRr) && !cname_.empty()))
872 SetFlag(kRtcpSdes, true);
873
874 if (generate_report) {
875 if (!sending_ && xr_send_receiver_reference_time_enabled_)
876 SetFlag(kRtcpXrReceiverReferenceTime, true);
877 if (feedback_state.has_last_xr_rr)
878 SetFlag(kRtcpXrDlrrReportBlock, true);
879
880 // generate next time to send an RTCP report
881 uint32_t minIntervalMs = RTCP_INTERVAL_AUDIO_MS;
882
883 if (!audio_) {
884 if (sending_) {
885 // Calculate bandwidth for video; 360 / send bandwidth in kbit/s.
886 uint32_t send_bitrate_kbit = feedback_state.send_bitrate / 1000;
887 if (send_bitrate_kbit != 0)
888 minIntervalMs = 360000 / send_bitrate_kbit;
889 }
890 if (minIntervalMs > RTCP_INTERVAL_VIDEO_MS)
891 minIntervalMs = RTCP_INTERVAL_VIDEO_MS;
892 }
893 // The interval between RTCP packets is varied randomly over the
894 // range [1/2,3/2] times the calculated interval.
895 uint32_t timeToNext =
896 random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2);
897 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext;
898
899 StatisticianMap statisticians =
900 receive_statistics_->GetActiveStatisticians();
901 RTC_DCHECK(report_blocks_.empty());
902 for (auto& it : statisticians) {
903 AddReportBlock(feedback_state, it.first, it.second);
904 }
905 }
906 }
907
AddReportBlock(const FeedbackState & feedback_state,uint32_t ssrc,StreamStatistician * statistician)908 bool RTCPSender::AddReportBlock(const FeedbackState& feedback_state,
909 uint32_t ssrc,
910 StreamStatistician* statistician) {
911 // Do we have receive statistics to send?
912 RtcpStatistics stats;
913 if (!statistician->GetStatistics(&stats, true))
914 return false;
915
916 if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) {
917 LOG(LS_WARNING) << "Too many report blocks.";
918 return false;
919 }
920 RTC_DCHECK(report_blocks_.find(ssrc) == report_blocks_.end());
921 rtcp::ReportBlock* block = &report_blocks_[ssrc];
922 block->To(ssrc);
923 block->WithFractionLost(stats.fraction_lost);
924 if (!block->WithCumulativeLost(stats.cumulative_lost)) {
925 report_blocks_.erase(ssrc);
926 LOG(LS_WARNING) << "Cumulative lost is oversized.";
927 return false;
928 }
929 block->WithExtHighestSeqNum(stats.extended_max_sequence_number);
930 block->WithJitter(stats.jitter);
931 block->WithLastSr(feedback_state.remote_sr);
932
933 // TODO(sprang): Do we really need separate time stamps for each report?
934 // Get our NTP as late as possible to avoid a race.
935 uint32_t ntp_secs;
936 uint32_t ntp_frac;
937 clock_->CurrentNtp(ntp_secs, ntp_frac);
938
939 // Delay since last received report.
940 if ((feedback_state.last_rr_ntp_secs != 0) ||
941 (feedback_state.last_rr_ntp_frac != 0)) {
942 // Get the 16 lowest bits of seconds and the 16 highest bits of fractions.
943 uint32_t now = ntp_secs & 0x0000FFFF;
944 now <<= 16;
945 now += (ntp_frac & 0xffff0000) >> 16;
946
947 uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF;
948 receiveTime <<= 16;
949 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16;
950
951 block->WithDelayLastSr(now - receiveTime);
952 }
953 return true;
954 }
955
SetCsrcs(const std::vector<uint32_t> & csrcs)956 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) {
957 assert(csrcs.size() <= kRtpCsrcSize);
958 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
959 csrcs_ = csrcs;
960 }
961
SetApplicationSpecificData(uint8_t subType,uint32_t name,const uint8_t * data,uint16_t length)962 int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType,
963 uint32_t name,
964 const uint8_t* data,
965 uint16_t length) {
966 if (length % 4 != 0) {
967 LOG(LS_ERROR) << "Failed to SetApplicationSpecificData.";
968 return -1;
969 }
970 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
971
972 SetFlag(kRtcpApp, true);
973 app_sub_type_ = subType;
974 app_name_ = name;
975 app_data_.reset(new uint8_t[length]);
976 app_length_ = length;
977 memcpy(app_data_.get(), data, length);
978 return 0;
979 }
980
SetRTCPVoIPMetrics(const RTCPVoIPMetric * VoIPMetric)981 int32_t RTCPSender::SetRTCPVoIPMetrics(const RTCPVoIPMetric* VoIPMetric) {
982 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
983 memcpy(&xr_voip_metric_, VoIPMetric, sizeof(RTCPVoIPMetric));
984
985 SetFlag(kRtcpXrVoipMetric, true);
986 return 0;
987 }
988
SendRtcpXrReceiverReferenceTime(bool enable)989 void RTCPSender::SendRtcpXrReceiverReferenceTime(bool enable) {
990 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
991 xr_send_receiver_reference_time_enabled_ = enable;
992 }
993
RtcpXrReceiverReferenceTime() const994 bool RTCPSender::RtcpXrReceiverReferenceTime() const {
995 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
996 return xr_send_receiver_reference_time_enabled_;
997 }
998
999 // no callbacks allowed inside this function
SetTMMBN(const TMMBRSet * boundingSet,uint32_t maxBitrateKbit)1000 int32_t RTCPSender::SetTMMBN(const TMMBRSet* boundingSet,
1001 uint32_t maxBitrateKbit) {
1002 CriticalSectionScoped lock(critical_section_rtcp_sender_.get());
1003
1004 if (0 == tmmbr_help_.SetTMMBRBoundingSetToSend(boundingSet, maxBitrateKbit)) {
1005 SetFlag(kRtcpTmmbn, true);
1006 return 0;
1007 }
1008 return -1;
1009 }
1010
SetFlag(RTCPPacketType type,bool is_volatile)1011 void RTCPSender::SetFlag(RTCPPacketType type, bool is_volatile) {
1012 report_flags_.insert(ReportFlag(type, is_volatile));
1013 }
1014
SetFlags(const std::set<RTCPPacketType> & types,bool is_volatile)1015 void RTCPSender::SetFlags(const std::set<RTCPPacketType>& types,
1016 bool is_volatile) {
1017 for (RTCPPacketType type : types)
1018 SetFlag(type, is_volatile);
1019 }
1020
IsFlagPresent(RTCPPacketType type) const1021 bool RTCPSender::IsFlagPresent(RTCPPacketType type) const {
1022 return report_flags_.find(ReportFlag(type, false)) != report_flags_.end();
1023 }
1024
ConsumeFlag(RTCPPacketType type,bool forced)1025 bool RTCPSender::ConsumeFlag(RTCPPacketType type, bool forced) {
1026 auto it = report_flags_.find(ReportFlag(type, false));
1027 if (it == report_flags_.end())
1028 return false;
1029 if (it->is_volatile || forced)
1030 report_flags_.erase((it));
1031 return true;
1032 }
1033
AllVolatileFlagsConsumed() const1034 bool RTCPSender::AllVolatileFlagsConsumed() const {
1035 for (const ReportFlag& flag : report_flags_) {
1036 if (flag.is_volatile)
1037 return false;
1038 }
1039 return true;
1040 }
1041
SendFeedbackPacket(const rtcp::TransportFeedback & packet)1042 bool RTCPSender::SendFeedbackPacket(const rtcp::TransportFeedback& packet) {
1043 class Sender : public rtcp::RtcpPacket::PacketReadyCallback {
1044 public:
1045 explicit Sender(Transport* transport)
1046 : transport_(transport), send_failure_(false) {}
1047
1048 void OnPacketReady(uint8_t* data, size_t length) override {
1049 if (!transport_->SendRtcp(data, length))
1050 send_failure_ = true;
1051 }
1052
1053 Transport* const transport_;
1054 bool send_failure_;
1055 } sender(transport_);
1056
1057 uint8_t buffer[IP_PACKET_SIZE];
1058 return packet.BuildExternalBuffer(buffer, IP_PACKET_SIZE, &sender) &&
1059 !sender.send_failure_;
1060 }
1061
1062 } // namespace webrtc
1063