OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" | 28 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/receiver_report.h" |
29 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 29 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
30 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" | 30 #include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h" |
31 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | 31 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
32 | 32 |
33 namespace webrtc { | 33 namespace webrtc { |
34 | 34 |
35 using RTCPUtility::RTCPCnameInformation; | 35 using RTCPUtility::RTCPCnameInformation; |
36 | 36 |
37 NACKStringBuilder::NACKStringBuilder() | 37 NACKStringBuilder::NACKStringBuilder() |
38 : stream_(""), count_(0), prevNack_(0), consecutive_(false) { | 38 : stream_(""), count_(0), prevNack_(0), consecutive_(false) {} |
39 } | |
40 | 39 |
41 NACKStringBuilder::~NACKStringBuilder() {} | 40 NACKStringBuilder::~NACKStringBuilder() {} |
42 | 41 |
43 void NACKStringBuilder::PushNACK(uint16_t nack) | 42 void NACKStringBuilder::PushNACK(uint16_t nack) { |
44 { | |
45 if (count_ == 0) { | 43 if (count_ == 0) { |
46 stream_ << nack; | 44 stream_ << nack; |
47 } else if (nack == prevNack_ + 1) { | 45 } else if (nack == prevNack_ + 1) { |
48 consecutive_ = true; | 46 consecutive_ = true; |
49 } else { | 47 } else { |
50 if (consecutive_) { | 48 if (consecutive_) { |
51 stream_ << "-" << prevNack_; | 49 stream_ << "-" << prevNack_; |
52 consecutive_ = false; | 50 consecutive_ = false; |
53 } | 51 } |
54 stream_ << "," << nack; | 52 stream_ << "," << nack; |
(...skipping 13 matching lines...) Expand all Loading... |
68 RTCPSender::FeedbackState::FeedbackState() | 66 RTCPSender::FeedbackState::FeedbackState() |
69 : send_payload_type(0), | 67 : send_payload_type(0), |
70 frequency_hz(0), | 68 frequency_hz(0), |
71 packets_sent(0), | 69 packets_sent(0), |
72 media_bytes_sent(0), | 70 media_bytes_sent(0), |
73 send_bitrate(0), | 71 send_bitrate(0), |
74 last_rr_ntp_secs(0), | 72 last_rr_ntp_secs(0), |
75 last_rr_ntp_frac(0), | 73 last_rr_ntp_frac(0), |
76 remote_sr(0), | 74 remote_sr(0), |
77 has_last_xr_rr(false), | 75 has_last_xr_rr(false), |
78 module(nullptr) { | 76 module(nullptr) {} |
79 } | |
80 | 77 |
81 class PacketContainer : public rtcp::Empty, | 78 class PacketContainer : public rtcp::Empty, |
82 public rtcp::RtcpPacket::PacketReadyCallback { | 79 public rtcp::RtcpPacket::PacketReadyCallback { |
83 public: | 80 public: |
84 explicit PacketContainer(Transport* transport) | 81 explicit PacketContainer(Transport* transport) |
85 : transport_(transport), bytes_sent_(0) {} | 82 : transport_(transport), bytes_sent_(0) {} |
86 virtual ~PacketContainer() { | 83 virtual ~PacketContainer() { |
87 for (RtcpPacket* packet : appended_packets_) | 84 for (RtcpPacket* packet : appended_packets_) |
88 delete packet; | 85 delete packet; |
89 } | 86 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 builders_[kRtcpApp] = &RTCPSender::BuildAPP; | 187 builders_[kRtcpApp] = &RTCPSender::BuildAPP; |
191 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; | 188 builders_[kRtcpTmmbr] = &RTCPSender::BuildTMMBR; |
192 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; | 189 builders_[kRtcpTmmbn] = &RTCPSender::BuildTMMBN; |
193 builders_[kRtcpNack] = &RTCPSender::BuildNACK; | 190 builders_[kRtcpNack] = &RTCPSender::BuildNACK; |
194 builders_[kRtcpXrVoipMetric] = &RTCPSender::BuildVoIPMetric; | 191 builders_[kRtcpXrVoipMetric] = &RTCPSender::BuildVoIPMetric; |
195 builders_[kRtcpXrReceiverReferenceTime] = | 192 builders_[kRtcpXrReceiverReferenceTime] = |
196 &RTCPSender::BuildReceiverReferenceTime; | 193 &RTCPSender::BuildReceiverReferenceTime; |
197 builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr; | 194 builders_[kRtcpXrDlrrReportBlock] = &RTCPSender::BuildDlrr; |
198 } | 195 } |
199 | 196 |
200 RTCPSender::~RTCPSender() { | 197 RTCPSender::~RTCPSender() {} |
201 } | |
202 | 198 |
203 RtcpMode RTCPSender::Status() const { | 199 RtcpMode RTCPSender::Status() const { |
204 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 200 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
205 return method_; | 201 return method_; |
206 } | 202 } |
207 | 203 |
208 void RTCPSender::SetRTCPStatus(RtcpMode method) { | 204 void RTCPSender::SetRTCPStatus(RtcpMode method) { |
209 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 205 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
210 method_ = method; | 206 method_ = method; |
211 | 207 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 auto it = csrc_cnames_.find(SSRC); | 333 auto it = csrc_cnames_.find(SSRC); |
338 | 334 |
339 if (it == csrc_cnames_.end()) | 335 if (it == csrc_cnames_.end()) |
340 return -1; | 336 return -1; |
341 | 337 |
342 csrc_cnames_.erase(it); | 338 csrc_cnames_.erase(it); |
343 return 0; | 339 return 0; |
344 } | 340 } |
345 | 341 |
346 bool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const { | 342 bool RTCPSender::TimeToSendRTCPReport(bool sendKeyframeBeforeRTP) const { |
347 /* | 343 /* |
348 For audio we use a fix 5 sec interval | 344 For audio we use a fix 5 sec interval |
349 | 345 |
350 For video we use 1 sec interval fo a BW smaller than 360 kbit/s, | 346 For video we use 1 sec interval fo a BW smaller than 360 kbit/s, |
351 technicaly we break the max 5% RTCP BW for video below 10 kbit/s but | 347 technicaly we break the max 5% RTCP BW for video below 10 kbit/s but |
352 that should be extremely rare | 348 that should be extremely rare |
353 | 349 |
354 | 350 |
355 From RFC 3550 | 351 From RFC 3550 |
356 | 352 |
357 MAX RTCP BW is 5% if the session BW | 353 MAX RTCP BW is 5% if the session BW |
358 A send report is approximately 65 bytes inc CNAME | 354 A send report is approximately 65 bytes inc CNAME |
359 A receiver report is approximately 28 bytes | 355 A receiver report is approximately 28 bytes |
360 | 356 |
361 The RECOMMENDED value for the reduced minimum in seconds is 360 | 357 The RECOMMENDED value for the reduced minimum in seconds is 360 |
362 divided by the session bandwidth in kilobits/second. This minimum | 358 divided by the session bandwidth in kilobits/second. This minimum |
363 is smaller than 5 seconds for bandwidths greater than 72 kb/s. | 359 is smaller than 5 seconds for bandwidths greater than 72 kb/s. |
364 | 360 |
365 If the participant has not yet sent an RTCP packet (the variable | 361 If the participant has not yet sent an RTCP packet (the variable |
366 initial is true), the constant Tmin is set to 2.5 seconds, else it | 362 initial is true), the constant Tmin is set to 2.5 seconds, else it |
367 is set to 5 seconds. | 363 is set to 5 seconds. |
368 | 364 |
369 The interval between RTCP packets is varied randomly over the | 365 The interval between RTCP packets is varied randomly over the |
370 range [0.5,1.5] times the calculated interval to avoid unintended | 366 range [0.5,1.5] times the calculated interval to avoid unintended |
371 synchronization of all participants | 367 synchronization of all participants |
372 | 368 |
373 if we send | 369 if we send |
374 If the participant is a sender (we_sent true), the constant C is | 370 If the participant is a sender (we_sent true), the constant C is |
375 set to the average RTCP packet size (avg_rtcp_size) divided by 25% | 371 set to the average RTCP packet size (avg_rtcp_size) divided by 25% |
376 of the RTCP bandwidth (rtcp_bw), and the constant n is set to the | 372 of the RTCP bandwidth (rtcp_bw), and the constant n is set to the |
377 number of senders. | 373 number of senders. |
378 | 374 |
379 if we receive only | 375 if we receive only |
380 If we_sent is not true, the constant C is set | 376 If we_sent is not true, the constant C is set |
381 to the average RTCP packet size divided by 75% of the RTCP | 377 to the average RTCP packet size divided by 75% of the RTCP |
382 bandwidth. The constant n is set to the number of receivers | 378 bandwidth. The constant n is set to the number of receivers |
383 (members - senders). If the number of senders is greater than | 379 (members - senders). If the number of senders is greater than |
384 25%, senders and receivers are treated together. | 380 25%, senders and receivers are treated together. |
385 | 381 |
386 reconsideration NOT required for peer-to-peer | 382 reconsideration NOT required for peer-to-peer |
387 "timer reconsideration" is | 383 "timer reconsideration" is |
388 employed. This algorithm implements a simple back-off mechanism | 384 employed. This algorithm implements a simple back-off mechanism |
389 which causes users to hold back RTCP packet transmission if the | 385 which causes users to hold back RTCP packet transmission if the |
390 group sizes are increasing. | 386 group sizes are increasing. |
391 | 387 |
392 n = number of members | 388 n = number of members |
393 C = avg_size/(rtcpBW/4) | 389 C = avg_size/(rtcpBW/4) |
394 | 390 |
395 3. The deterministic calculated interval Td is set to max(Tmin, n*C). | 391 3. The deterministic calculated interval Td is set to max(Tmin, n*C). |
396 | 392 |
397 4. The calculated interval T is set to a number uniformly distributed | 393 4. The calculated interval T is set to a number uniformly distributed |
398 between 0.5 and 1.5 times the deterministic calculated interval. | 394 between 0.5 and 1.5 times the deterministic calculated interval. |
399 | 395 |
400 5. The resulting value of T is divided by e-3/2=1.21828 to compensate | 396 5. The resulting value of T is divided by e-3/2=1.21828 to compensate |
401 for the fact that the timer reconsideration algorithm converges to | 397 for the fact that the timer reconsideration algorithm converges to |
402 a value of the RTCP bandwidth below the intended average | 398 a value of the RTCP bandwidth below the intended average |
403 */ | 399 */ |
404 | 400 |
405 int64_t now = clock_->TimeInMilliseconds(); | 401 int64_t now = clock_->TimeInMilliseconds(); |
406 | 402 |
407 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 403 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
408 | 404 |
409 if (method_ == RtcpMode::kOff) | 405 if (method_ == RtcpMode::kOff) |
410 return false; | 406 return false; |
411 | 407 |
412 if (!audio_ && sendKeyframeBeforeRTP) { | 408 if (!audio_ && sendKeyframeBeforeRTP) { |
413 // for video key-frames we want to send the RTCP before the large key-frame | 409 // for video key-frames we want to send the RTCP before the large key-frame |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 bool RTCPSender::PrepareReportBlock(const FeedbackState& feedback_state, | 953 bool RTCPSender::PrepareReportBlock(const FeedbackState& feedback_state, |
958 uint32_t ssrc, | 954 uint32_t ssrc, |
959 StreamStatistician* statistician, | 955 StreamStatistician* statistician, |
960 RTCPReportBlock* report_block) { | 956 RTCPReportBlock* report_block) { |
961 // Do we have receive statistics to send? | 957 // Do we have receive statistics to send? |
962 RtcpStatistics stats; | 958 RtcpStatistics stats; |
963 if (!statistician->GetStatistics(&stats, true)) | 959 if (!statistician->GetStatistics(&stats, true)) |
964 return false; | 960 return false; |
965 report_block->fractionLost = stats.fraction_lost; | 961 report_block->fractionLost = stats.fraction_lost; |
966 report_block->cumulativeLost = stats.cumulative_lost; | 962 report_block->cumulativeLost = stats.cumulative_lost; |
967 report_block->extendedHighSeqNum = | 963 report_block->extendedHighSeqNum = stats.extended_max_sequence_number; |
968 stats.extended_max_sequence_number; | |
969 report_block->jitter = stats.jitter; | 964 report_block->jitter = stats.jitter; |
970 report_block->remoteSSRC = ssrc; | 965 report_block->remoteSSRC = ssrc; |
971 | 966 |
972 // TODO(sprang): Do we really need separate time stamps for each report? | 967 // TODO(sprang): Do we really need separate time stamps for each report? |
973 // Get our NTP as late as possible to avoid a race. | 968 // Get our NTP as late as possible to avoid a race. |
974 uint32_t ntp_secs; | 969 uint32_t ntp_secs; |
975 uint32_t ntp_frac; | 970 uint32_t ntp_frac; |
976 clock_->CurrentNtp(ntp_secs, ntp_frac); | 971 clock_->CurrentNtp(ntp_secs, ntp_frac); |
977 | 972 |
978 // Delay since last received report. | 973 // Delay since last received report. |
979 uint32_t delaySinceLastReceivedSR = 0; | 974 uint32_t delaySinceLastReceivedSR = 0; |
980 if ((feedback_state.last_rr_ntp_secs != 0) || | 975 if ((feedback_state.last_rr_ntp_secs != 0) || |
981 (feedback_state.last_rr_ntp_frac != 0)) { | 976 (feedback_state.last_rr_ntp_frac != 0)) { |
982 // Get the 16 lowest bits of seconds and the 16 highest bits of fractions. | 977 // Get the 16 lowest bits of seconds and the 16 highest bits of fractions. |
983 uint32_t now = ntp_secs & 0x0000FFFF; | 978 uint32_t now = ntp_secs & 0x0000FFFF; |
984 now <<= 16; | 979 now <<= 16; |
985 now += (ntp_frac & 0xffff0000) >> 16; | 980 now += (ntp_frac & 0xffff0000) >> 16; |
986 | 981 |
987 uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF; | 982 uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF; |
988 receiveTime <<= 16; | 983 receiveTime <<= 16; |
989 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; | 984 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; |
990 | 985 |
991 delaySinceLastReceivedSR = now-receiveTime; | 986 delaySinceLastReceivedSR = now - receiveTime; |
992 } | 987 } |
993 report_block->delaySinceLastSR = delaySinceLastReceivedSR; | 988 report_block->delaySinceLastSR = delaySinceLastReceivedSR; |
994 report_block->lastSR = feedback_state.remote_sr; | 989 report_block->lastSR = feedback_state.remote_sr; |
995 return true; | 990 return true; |
996 } | 991 } |
997 | 992 |
998 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { | 993 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { |
999 assert(csrcs.size() <= kRtpCsrcSize); | 994 assert(csrcs.size() <= kRtpCsrcSize); |
1000 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 995 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
1001 csrcs_ = csrcs; | 996 csrcs_ = csrcs; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1095 Transport* const transport_; | 1090 Transport* const transport_; |
1096 bool send_failure_; | 1091 bool send_failure_; |
1097 } sender(transport_); | 1092 } sender(transport_); |
1098 | 1093 |
1099 uint8_t buffer[IP_PACKET_SIZE]; | 1094 uint8_t buffer[IP_PACKET_SIZE]; |
1100 return packet.BuildExternalBuffer(buffer, IP_PACKET_SIZE, &sender) && | 1095 return packet.BuildExternalBuffer(buffer, IP_PACKET_SIZE, &sender) && |
1101 !sender.send_failure_; | 1096 !sender.send_failure_; |
1102 } | 1097 } |
1103 | 1098 |
1104 } // namespace webrtc | 1099 } // namespace webrtc |
OLD | NEW |