| 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 |