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 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 return false; | 445 return false; |
446 } | 446 } |
447 std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp); | 447 std::map<uint32_t, int64_t>::const_iterator it = last_xr_rr_.find(mid_ntp); |
448 if (it == last_xr_rr_.end()) { | 448 if (it == last_xr_rr_.end()) { |
449 return false; | 449 return false; |
450 } | 450 } |
451 *time_ms = it->second; | 451 *time_ms = it->second; |
452 return true; | 452 return true; |
453 } | 453 } |
454 | 454 |
455 int32_t RTCPSender::AddReportBlock(const RTCPReportBlock& report_block) { | |
456 if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) { | |
457 LOG(LS_WARNING) << "Too many report blocks."; | |
458 return -1; | |
459 } | |
460 rtcp::ReportBlock* block = &report_blocks_[report_block.remoteSSRC]; | |
461 block->To(report_block.remoteSSRC); | |
462 block->WithFractionLost(report_block.fractionLost); | |
463 if (!block->WithCumulativeLost(report_block.cumulativeLost)) { | |
464 LOG(LS_WARNING) << "Cumulative lost is oversized."; | |
465 return -1; | |
466 } | |
467 block->WithExtHighestSeqNum(report_block.extendedHighSeqNum); | |
468 block->WithJitter(report_block.jitter); | |
469 block->WithLastSr(report_block.lastSR); | |
470 block->WithDelayLastSr(report_block.delaySinceLastSR); | |
471 | |
472 return 0; | |
473 } | |
474 | |
475 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) { | 455 rtc::scoped_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) { |
476 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { | 456 for (int i = (RTCP_NUMBER_OF_SR - 2); i >= 0; i--) { |
477 // shift old | 457 // shift old |
478 last_send_report_[i + 1] = last_send_report_[i]; | 458 last_send_report_[i + 1] = last_send_report_[i]; |
479 last_rtcp_time_[i + 1] = last_rtcp_time_[i]; | 459 last_rtcp_time_[i + 1] = last_rtcp_time_[i]; |
480 } | 460 } |
481 | 461 |
482 last_rtcp_time_[0] = Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_); | 462 last_rtcp_time_[0] = Clock::NtpToMs(ctx.ntp_sec_, ctx.ntp_frac_); |
483 last_send_report_[0] = (ctx.ntp_sec_ << 16) + (ctx.ntp_frac_ >> 16); | 463 last_send_report_[0] = (ctx.ntp_sec_ << 16) + (ctx.ntp_frac_ >> 16); |
484 | 464 |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 minIntervalMs = RTCP_INTERVAL_VIDEO_MS; | 888 minIntervalMs = RTCP_INTERVAL_VIDEO_MS; |
909 } | 889 } |
910 // The interval between RTCP packets is varied randomly over the | 890 // The interval between RTCP packets is varied randomly over the |
911 // range [1/2,3/2] times the calculated interval. | 891 // range [1/2,3/2] times the calculated interval. |
912 uint32_t timeToNext = | 892 uint32_t timeToNext = |
913 random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2); | 893 random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2); |
914 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; | 894 next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext; |
915 | 895 |
916 StatisticianMap statisticians = | 896 StatisticianMap statisticians = |
917 receive_statistics_->GetActiveStatisticians(); | 897 receive_statistics_->GetActiveStatisticians(); |
918 if (!statisticians.empty()) { | 898 RTC_DCHECK(report_blocks_.empty()); |
919 for (auto it = statisticians.begin(); it != statisticians.end(); ++it) { | 899 for (auto& it : statisticians) { |
920 RTCPReportBlock report_block; | 900 AddReportBlock(feedback_state, it.first, it.second); |
921 if (PrepareReportBlock(feedback_state, it->first, it->second, | |
922 &report_block)) { | |
923 // TODO(danilchap) AddReportBlock may fail (for 2 different reasons). | |
924 // Probably it shouldn't be ignored. | |
925 AddReportBlock(report_block); | |
926 } | |
927 } | |
928 } | 901 } |
929 } | 902 } |
930 } | 903 } |
931 | 904 |
932 bool RTCPSender::PrepareReportBlock(const FeedbackState& feedback_state, | 905 bool RTCPSender::AddReportBlock(const FeedbackState& feedback_state, |
933 uint32_t ssrc, | 906 uint32_t ssrc, |
934 StreamStatistician* statistician, | 907 StreamStatistician* statistician) { |
935 RTCPReportBlock* report_block) { | |
936 // Do we have receive statistics to send? | 908 // Do we have receive statistics to send? |
937 RtcpStatistics stats; | 909 RtcpStatistics stats; |
938 if (!statistician->GetStatistics(&stats, true)) | 910 if (!statistician->GetStatistics(&stats, true)) |
939 return false; | 911 return false; |
940 report_block->fractionLost = stats.fraction_lost; | 912 |
941 report_block->cumulativeLost = stats.cumulative_lost; | 913 if (report_blocks_.size() >= RTCP_MAX_REPORT_BLOCKS) { |
942 report_block->extendedHighSeqNum = stats.extended_max_sequence_number; | 914 LOG(LS_WARNING) << "Too many report blocks."; |
943 report_block->jitter = stats.jitter; | 915 return false; |
944 report_block->remoteSSRC = ssrc; | 916 } |
| 917 RTC_DCHECK(report_blocks_.find(ssrc) == report_blocks_.end()); |
| 918 rtcp::ReportBlock* block = &report_blocks_[ssrc]; |
| 919 block->To(ssrc); |
| 920 block->WithFractionLost(stats.fraction_lost); |
| 921 if (!block->WithCumulativeLost(stats.cumulative_lost)) { |
| 922 report_blocks_.erase(ssrc); |
| 923 LOG(LS_WARNING) << "Cumulative lost is oversized."; |
| 924 return false; |
| 925 } |
| 926 block->WithExtHighestSeqNum(stats.extended_max_sequence_number); |
| 927 block->WithJitter(stats.jitter); |
| 928 block->WithLastSr(feedback_state.remote_sr); |
945 | 929 |
946 // TODO(sprang): Do we really need separate time stamps for each report? | 930 // TODO(sprang): Do we really need separate time stamps for each report? |
947 // Get our NTP as late as possible to avoid a race. | 931 // Get our NTP as late as possible to avoid a race. |
948 uint32_t ntp_secs; | 932 uint32_t ntp_secs; |
949 uint32_t ntp_frac; | 933 uint32_t ntp_frac; |
950 clock_->CurrentNtp(ntp_secs, ntp_frac); | 934 clock_->CurrentNtp(ntp_secs, ntp_frac); |
951 | 935 |
952 // Delay since last received report. | 936 // Delay since last received report. |
953 uint32_t delaySinceLastReceivedSR = 0; | |
954 if ((feedback_state.last_rr_ntp_secs != 0) || | 937 if ((feedback_state.last_rr_ntp_secs != 0) || |
955 (feedback_state.last_rr_ntp_frac != 0)) { | 938 (feedback_state.last_rr_ntp_frac != 0)) { |
956 // Get the 16 lowest bits of seconds and the 16 highest bits of fractions. | 939 // Get the 16 lowest bits of seconds and the 16 highest bits of fractions. |
957 uint32_t now = ntp_secs & 0x0000FFFF; | 940 uint32_t now = ntp_secs & 0x0000FFFF; |
958 now <<= 16; | 941 now <<= 16; |
959 now += (ntp_frac & 0xffff0000) >> 16; | 942 now += (ntp_frac & 0xffff0000) >> 16; |
960 | 943 |
961 uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF; | 944 uint32_t receiveTime = feedback_state.last_rr_ntp_secs & 0x0000FFFF; |
962 receiveTime <<= 16; | 945 receiveTime <<= 16; |
963 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; | 946 receiveTime += (feedback_state.last_rr_ntp_frac & 0xffff0000) >> 16; |
964 | 947 |
965 delaySinceLastReceivedSR = now - receiveTime; | 948 block->WithDelayLastSr(now - receiveTime); |
966 } | 949 } |
967 report_block->delaySinceLastSR = delaySinceLastReceivedSR; | |
968 report_block->lastSR = feedback_state.remote_sr; | |
969 return true; | 950 return true; |
970 } | 951 } |
971 | 952 |
972 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { | 953 void RTCPSender::SetCsrcs(const std::vector<uint32_t>& csrcs) { |
973 assert(csrcs.size() <= kRtpCsrcSize); | 954 assert(csrcs.size() <= kRtpCsrcSize); |
974 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); | 955 CriticalSectionScoped lock(critical_section_rtcp_sender_.get()); |
975 csrcs_ = csrcs; | 956 csrcs_ = csrcs; |
976 } | 957 } |
977 | 958 |
978 int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, | 959 int32_t RTCPSender::SetApplicationSpecificData(uint8_t subType, |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1069 Transport* const transport_; | 1050 Transport* const transport_; |
1070 bool send_failure_; | 1051 bool send_failure_; |
1071 } sender(transport_); | 1052 } sender(transport_); |
1072 | 1053 |
1073 uint8_t buffer[IP_PACKET_SIZE]; | 1054 uint8_t buffer[IP_PACKET_SIZE]; |
1074 return packet.BuildExternalBuffer(buffer, IP_PACKET_SIZE, &sender) && | 1055 return packet.BuildExternalBuffer(buffer, IP_PACKET_SIZE, &sender) && |
1075 !sender.send_failure_; | 1056 !sender.send_failure_; |
1076 } | 1057 } |
1077 | 1058 |
1078 } // namespace webrtc | 1059 } // namespace webrtc |
OLD | NEW |