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