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 |
11 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" | 11 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" |
12 | 12 |
13 #include <string.h> // memcpy | 13 #include <string.h> // memcpy |
14 | 14 |
| 15 #include <utility> |
| 16 |
15 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
16 #include "webrtc/base/constructormagic.h" | 18 #include "webrtc/base/constructormagic.h" |
17 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
18 #include "webrtc/base/trace_event.h" | 20 #include "webrtc/base/trace_event.h" |
19 #include "webrtc/call.h" | 21 #include "webrtc/call.h" |
20 #include "webrtc/call/rtc_event_log.h" | 22 #include "webrtc/call/rtc_event_log.h" |
21 #include "webrtc/common_types.h" | 23 #include "webrtc/common_types.h" |
22 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h" | 24 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/app.h" |
23 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h" | 25 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h" |
24 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h" | 26 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/compound_packet.h" |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 return true; | 430 return true; |
429 } else if (now < 0x0000ffff && | 431 } else if (now < 0x0000ffff && |
430 next_time_to_send_rtcp_ > 0xffff0000) { // 65 sec margin | 432 next_time_to_send_rtcp_ > 0xffff0000) { // 65 sec margin |
431 // wrap | 433 // wrap |
432 return true; | 434 return true; |
433 } | 435 } |
434 return false; | 436 return false; |
435 } | 437 } |
436 | 438 |
437 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) { | 439 std::unique_ptr<rtcp::RtcpPacket> RTCPSender::BuildSR(const RtcpContext& ctx) { |
| 440 // Timestamp shouldn't be estimated before first media frame. |
| 441 RTC_DCHECK_GE(last_frame_capture_time_ms_, 0); |
438 // The timestamp of this RTCP packet should be estimated as the timestamp of | 442 // The timestamp of this RTCP packet should be estimated as the timestamp of |
439 // the frame being captured at this moment. We are calculating that | 443 // the frame being captured at this moment. We are calculating that |
440 // timestamp as the last frame's timestamp + the time since the last frame | 444 // timestamp as the last frame's timestamp + the time since the last frame |
441 // was captured. | 445 // was captured. |
442 uint32_t rtp_timestamp = | 446 uint32_t rtp_timestamp = |
443 start_timestamp_ + last_rtp_timestamp_ + | 447 start_timestamp_ + last_rtp_timestamp_ + |
444 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * | 448 (clock_->TimeInMilliseconds() - last_frame_capture_time_ms_) * |
445 (ctx.feedback_state_.frequency_hz / 1000); | 449 (ctx.feedback_state_.frequency_hz / 1000); |
446 | 450 |
447 rtcp::SenderReport* report = new rtcp::SenderReport(); | 451 rtcp::SenderReport* report = new rtcp::SenderReport(); |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 const uint16_t* nack_list, | 763 const uint16_t* nack_list, |
760 bool repeat, | 764 bool repeat, |
761 uint64_t pictureID) { | 765 uint64_t pictureID) { |
762 PacketContainer container(transport_, event_log_); | 766 PacketContainer container(transport_, event_log_); |
763 { | 767 { |
764 rtc::CritScope lock(&critical_section_rtcp_sender_); | 768 rtc::CritScope lock(&critical_section_rtcp_sender_); |
765 if (method_ == RtcpMode::kOff) { | 769 if (method_ == RtcpMode::kOff) { |
766 LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; | 770 LOG(LS_WARNING) << "Can't send rtcp if it is disabled."; |
767 return -1; | 771 return -1; |
768 } | 772 } |
| 773 // Add all flags as volatile. Non volatile entries will not be overwritten. |
| 774 // All new volatile flags added will be consumed by the end of this call. |
| 775 SetFlags(packet_types, true); |
| 776 |
| 777 // Prevent sending streams to send SR before any media has been sent. |
| 778 const bool can_calculate_rtp_timestamp = (last_frame_capture_time_ms_ >= 0); |
| 779 if (!can_calculate_rtp_timestamp) { |
| 780 bool consumed_sr_flag = ConsumeFlag(kRtcpSr); |
| 781 bool consumed_report_flag = sending_ && ConsumeFlag(kRtcpReport); |
| 782 bool sender_report = consumed_report_flag || consumed_sr_flag; |
| 783 if (sender_report && AllVolatileFlagsConsumed()) { |
| 784 // This call was for Sender Report and nothing else. |
| 785 return 0; |
| 786 } |
| 787 if (sending_ && method_ == RtcpMode::kCompound) { |
| 788 // Not allowed to send any RTCP packet without sender report. |
| 789 return -1; |
| 790 } |
| 791 } |
| 792 |
| 793 if (packet_type_counter_.first_packet_time_ms == -1) |
| 794 packet_type_counter_.first_packet_time_ms = clock_->TimeInMilliseconds(); |
769 | 795 |
770 // We need to send our NTP even if we haven't received any reports. | 796 // We need to send our NTP even if we haven't received any reports. |
771 uint32_t ntp_sec; | 797 uint32_t ntp_sec; |
772 uint32_t ntp_frac; | 798 uint32_t ntp_frac; |
773 clock_->CurrentNtp(ntp_sec, ntp_frac); | 799 clock_->CurrentNtp(ntp_sec, ntp_frac); |
774 RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID, | 800 RtcpContext context(feedback_state, nack_size, nack_list, repeat, pictureID, |
775 ntp_sec, ntp_frac); | 801 ntp_sec, ntp_frac); |
776 | 802 |
777 PrepareReport(packet_types, feedback_state); | 803 PrepareReport(feedback_state); |
778 | 804 |
779 std::unique_ptr<rtcp::RtcpPacket> packet_bye; | 805 std::unique_ptr<rtcp::RtcpPacket> packet_bye; |
780 | 806 |
781 auto it = report_flags_.begin(); | 807 auto it = report_flags_.begin(); |
782 while (it != report_flags_.end()) { | 808 while (it != report_flags_.end()) { |
783 auto builder_it = builders_.find(it->type); | 809 auto builder_it = builders_.find(it->type); |
784 RTC_DCHECK(builder_it != builders_.end()); | 810 RTC_DCHECK(builder_it != builders_.end()); |
785 if (it->is_volatile) { | 811 if (it->is_volatile) { |
786 report_flags_.erase(it++); | 812 report_flags_.erase(it++); |
787 } else { | 813 } else { |
(...skipping 23 matching lines...) Expand all Loading... |
811 remote_ssrc_, packet_type_counter_); | 837 remote_ssrc_, packet_type_counter_); |
812 } | 838 } |
813 | 839 |
814 RTC_DCHECK(AllVolatileFlagsConsumed()); | 840 RTC_DCHECK(AllVolatileFlagsConsumed()); |
815 } | 841 } |
816 | 842 |
817 size_t bytes_sent = container.SendPackets(max_payload_length_); | 843 size_t bytes_sent = container.SendPackets(max_payload_length_); |
818 return bytes_sent == 0 ? -1 : 0; | 844 return bytes_sent == 0 ? -1 : 0; |
819 } | 845 } |
820 | 846 |
821 void RTCPSender::PrepareReport(const std::set<RTCPPacketType>& packetTypes, | 847 void RTCPSender::PrepareReport(const FeedbackState& feedback_state) { |
822 const FeedbackState& feedback_state) { | |
823 // Add all flags as volatile. Non volatile entries will not be overwritten | |
824 // and all new volatile flags added will be consumed by the end of this call. | |
825 SetFlags(packetTypes, true); | |
826 | |
827 if (packet_type_counter_.first_packet_time_ms == -1) | |
828 packet_type_counter_.first_packet_time_ms = clock_->TimeInMilliseconds(); | |
829 | |
830 bool generate_report; | 848 bool generate_report; |
831 if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) { | 849 if (IsFlagPresent(kRtcpSr) || IsFlagPresent(kRtcpRr)) { |
832 // Report type already explicitly set, don't automatically populate. | 850 // Report type already explicitly set, don't automatically populate. |
833 generate_report = true; | 851 generate_report = true; |
834 RTC_DCHECK(ConsumeFlag(kRtcpReport) == false); | 852 RTC_DCHECK(ConsumeFlag(kRtcpReport) == false); |
835 } else { | 853 } else { |
836 generate_report = | 854 generate_report = |
837 (ConsumeFlag(kRtcpReport) && method_ == RtcpMode::kReducedSize) || | 855 (ConsumeFlag(kRtcpReport) && method_ == RtcpMode::kReducedSize) || |
838 method_ == RtcpMode::kCompound; | 856 method_ == RtcpMode::kCompound; |
839 if (generate_report) | 857 if (generate_report) |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 // but we can't because of an incorrect warning (C4822) in MVS 2013. | 1055 // but we can't because of an incorrect warning (C4822) in MVS 2013. |
1038 } sender(transport_, event_log_); | 1056 } sender(transport_, event_log_); |
1039 | 1057 |
1040 RTC_DCHECK_LE(max_payload_length_, static_cast<size_t>(IP_PACKET_SIZE)); | 1058 RTC_DCHECK_LE(max_payload_length_, static_cast<size_t>(IP_PACKET_SIZE)); |
1041 uint8_t buffer[IP_PACKET_SIZE]; | 1059 uint8_t buffer[IP_PACKET_SIZE]; |
1042 return packet.BuildExternalBuffer(buffer, max_payload_length_, &sender) && | 1060 return packet.BuildExternalBuffer(buffer, max_payload_length_, &sender) && |
1043 !sender.send_failure_; | 1061 !sender.send_failure_; |
1044 } | 1062 } |
1045 | 1063 |
1046 } // namespace webrtc | 1064 } // namespace webrtc |
OLD | NEW |