OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 #include <limits> | 6 #include <limits> |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/big_endian.h" | 9 #include "base/big_endian.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 value1 |= packet_id_or_zero; | 62 value1 |= packet_id_or_zero; |
63 value1 <<= 32; | 63 value1 <<= 32; |
64 value1 |= frame_rtp_timestamp.lower_32_bits(); | 64 value1 |= frame_rtp_timestamp.lower_32_bits(); |
65 return std::make_pair( | 65 return std::make_pair( |
66 value1, static_cast<uint64_t>(event_timestamp.ToInternalValue())); | 66 value1, static_cast<uint64_t>(event_timestamp.ToInternalValue())); |
67 } | 67 } |
68 | 68 |
69 } // namespace | 69 } // namespace |
70 | 70 |
71 SenderRtcpSession::SenderRtcpSession( | 71 SenderRtcpSession::SenderRtcpSession( |
72 const RtcpCastMessageCallback& cast_callback, | 72 std::unique_ptr<SenderRtcpObserver> observer, |
73 const RtcpRttCallback& rtt_callback, | |
74 const RtcpLogMessageCallback& log_callback, | |
75 const RtcpPliCallback pli_callback, | |
76 base::TickClock* clock, | 73 base::TickClock* clock, |
77 PacedPacketSender* packet_sender, | 74 PacedPacketSender* packet_sender, |
78 uint32_t local_ssrc, | 75 uint32_t local_ssrc, |
79 uint32_t remote_ssrc) | 76 uint32_t remote_ssrc) |
80 : clock_(clock), | 77 : clock_(clock), |
81 packet_sender_(packet_sender), | 78 packet_sender_(packet_sender), |
82 local_ssrc_(local_ssrc), | 79 local_ssrc_(local_ssrc), |
83 remote_ssrc_(remote_ssrc), | 80 remote_ssrc_(remote_ssrc), |
84 cast_callback_(cast_callback), | 81 sender_rtcp_observer_(std::move(observer)), |
85 rtt_callback_(rtt_callback), | |
86 log_callback_(log_callback), | |
87 pli_callback_(pli_callback), | |
88 largest_seen_timestamp_(base::TimeTicks::FromInternalValue( | 82 largest_seen_timestamp_(base::TimeTicks::FromInternalValue( |
89 std::numeric_limits<int64_t>::min())), | 83 std::numeric_limits<int64_t>::min())), |
90 parser_(local_ssrc, remote_ssrc), | 84 parser_(local_ssrc, remote_ssrc), |
91 ack_frame_id_wrap_helper_(kFirstFrameId - 1) {} | 85 ack_frame_id_wrap_helper_(kFirstFrameId - 1) {} |
92 | 86 |
93 SenderRtcpSession::~SenderRtcpSession() {} | 87 SenderRtcpSession::~SenderRtcpSession() {} |
94 | 88 |
95 bool SenderRtcpSession::IncomingRtcpPacket(const uint8_t* data, size_t length) { | 89 bool SenderRtcpSession::IncomingRtcpPacket(const uint8_t* data, size_t length) { |
96 // Check if this is a valid RTCP packet. | 90 // Check if this is a valid RTCP packet. |
97 if (!IsRtcpPacket(data, length)) { | 91 if (!IsRtcpPacket(data, length)) { |
98 VLOG(1) << "Rtcp@" << this << "::IncomingRtcpPacket() -- " | 92 VLOG(1) << "Rtcp@" << this << "::IncomingRtcpPacket() -- " |
99 << "Received an invalid (non-RTCP?) packet."; | 93 << "Received an invalid (non-RTCP?) packet."; |
100 return false; | 94 return false; |
101 } | 95 } |
102 | 96 |
103 // Check if this packet is to us. | 97 // Check if this packet is to us. |
104 uint32_t ssrc_of_sender = GetSsrcOfSender(data, length); | 98 uint32_t ssrc_of_sender = GetSsrcOfSender(data, length); |
105 if (ssrc_of_sender != remote_ssrc_) { | 99 if (ssrc_of_sender != remote_ssrc_) { |
106 return false; | 100 return false; |
107 } | 101 } |
108 | 102 |
109 // Parse this packet. | 103 // Parse this packet. |
110 base::BigEndianReader reader(reinterpret_cast<const char*>(data), length); | 104 base::BigEndianReader reader(reinterpret_cast<const char*>(data), length); |
111 if (parser_.Parse(&reader)) { | 105 if (parser_.Parse(&reader)) { |
112 if (parser_.has_picture_loss_indicator()) { | 106 if (parser_.has_picture_loss_indicator()) |
113 if (!pli_callback_.is_null()) | 107 sender_rtcp_observer_->OnPliReceived(); |
114 pli_callback_.Run(); | |
115 } | |
116 if (parser_.has_receiver_reference_time_report()) { | 108 if (parser_.has_receiver_reference_time_report()) { |
117 base::TimeTicks t = ConvertNtpToTimeTicks( | 109 base::TimeTicks t = ConvertNtpToTimeTicks( |
118 parser_.receiver_reference_time_report().ntp_seconds, | 110 parser_.receiver_reference_time_report().ntp_seconds, |
119 parser_.receiver_reference_time_report().ntp_fraction); | 111 parser_.receiver_reference_time_report().ntp_fraction); |
120 if (t > largest_seen_timestamp_) { | 112 if (t > largest_seen_timestamp_) { |
121 largest_seen_timestamp_ = t; | 113 largest_seen_timestamp_ = t; |
122 } else if ((largest_seen_timestamp_ - t).InMilliseconds() > | 114 } else if ((largest_seen_timestamp_ - t).InMilliseconds() > |
123 kOutOfOrderMaxAgeMs) { | 115 kOutOfOrderMaxAgeMs) { |
124 // Reject packet, it is too old. | 116 // Reject packet, it is too old. |
125 VLOG(1) << "Rejecting RTCP packet as it is too old (" | 117 VLOG(1) << "Rejecting RTCP packet as it is too old (" |
126 << (largest_seen_timestamp_ - t).InMilliseconds() << " ms)"; | 118 << (largest_seen_timestamp_ - t).InMilliseconds() << " ms)"; |
127 return true; | 119 return true; |
128 } | 120 } |
129 } | 121 } |
130 if (parser_.has_receiver_log()) { | 122 if (parser_.has_receiver_log()) { |
131 if (DedupeReceiverLog(parser_.mutable_receiver_log())) { | 123 if (DedupeReceiverLog(parser_.mutable_receiver_log())) { |
132 OnReceivedReceiverLog(parser_.receiver_log()); | 124 sender_rtcp_observer_->OnReceiverLogReceived(parser_.receiver_log()); |
133 } | 125 } |
134 } | 126 } |
135 if (parser_.has_last_report()) { | 127 if (parser_.has_last_report()) { |
136 OnReceivedDelaySinceLastReport(parser_.last_report(), | 128 OnReceivedDelaySinceLastReport(parser_.last_report(), |
137 parser_.delay_since_last_report()); | 129 parser_.delay_since_last_report()); |
138 } | 130 } |
139 if (parser_.has_cast_message()) { | 131 if (parser_.has_cast_message()) { |
140 parser_.mutable_cast_message()->ack_frame_id = | 132 parser_.mutable_cast_message()->ack_frame_id = |
141 ack_frame_id_wrap_helper_.MapTo32bitsFrameId( | 133 ack_frame_id_wrap_helper_.MapTo32bitsFrameId( |
142 parser_.mutable_cast_message()->ack_frame_id); | 134 parser_.mutable_cast_message()->ack_frame_id); |
143 OnReceivedCastFeedback(parser_.cast_message()); | 135 sender_rtcp_observer_->OnCastMessageReceived(parser_.cast_message()); |
144 } | 136 } |
145 } | 137 } |
146 return true; | 138 return true; |
147 } | 139 } |
148 | 140 |
149 void SenderRtcpSession::OnReceivedDelaySinceLastReport( | 141 void SenderRtcpSession::OnReceivedDelaySinceLastReport( |
150 uint32_t last_report, | 142 uint32_t last_report, |
151 uint32_t delay_since_last_report) { | 143 uint32_t delay_since_last_report) { |
152 RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report); | 144 RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report); |
153 if (it == last_reports_sent_map_.end()) { | 145 if (it == last_reports_sent_map_.end()) { |
154 return; // Feedback on another report. | 146 return; // Feedback on another report. |
155 } | 147 } |
156 | 148 |
157 const base::TimeDelta sender_delay = clock_->NowTicks() - it->second; | 149 const base::TimeDelta sender_delay = clock_->NowTicks() - it->second; |
158 const base::TimeDelta receiver_delay = | 150 const base::TimeDelta receiver_delay = |
159 ConvertFromNtpDiff(delay_since_last_report); | 151 ConvertFromNtpDiff(delay_since_last_report); |
160 current_round_trip_time_ = sender_delay - receiver_delay; | 152 current_round_trip_time_ = sender_delay - receiver_delay; |
161 // If the round trip time was computed as less than 1 ms, assume clock | 153 // If the round trip time was computed as less than 1 ms, assume clock |
162 // imprecision by one or both peers caused a bad value to be calculated. | 154 // imprecision by one or both peers caused a bad value to be calculated. |
163 // While plenty of networks do easily achieve less than 1 ms round trip time, | 155 // While plenty of networks do easily achieve less than 1 ms round trip time, |
164 // such a level of precision cannot be measured with our approach; and 1 ms is | 156 // such a level of precision cannot be measured with our approach; and 1 ms is |
165 // good enough to represent "under 1 ms" for our use cases. | 157 // good enough to represent "under 1 ms" for our use cases. |
166 current_round_trip_time_ = | 158 current_round_trip_time_ = |
167 std::max(current_round_trip_time_, base::TimeDelta::FromMilliseconds(1)); | 159 std::max(current_round_trip_time_, base::TimeDelta::FromMilliseconds(1)); |
168 | 160 |
169 if (!rtt_callback_.is_null()) | 161 sender_rtcp_observer_->OnRttReceived(current_round_trip_time_); |
170 rtt_callback_.Run(current_round_trip_time_); | |
171 } | 162 } |
172 | 163 |
173 void SenderRtcpSession::SaveLastSentNtpTime(const base::TimeTicks& now, | 164 void SenderRtcpSession::SaveLastSentNtpTime(const base::TimeTicks& now, |
174 uint32_t last_ntp_seconds, | 165 uint32_t last_ntp_seconds, |
175 uint32_t last_ntp_fraction) { | 166 uint32_t last_ntp_fraction) { |
176 // Make sure |now| is always greater than the last element in | 167 // Make sure |now| is always greater than the last element in |
177 // |last_reports_sent_queue_|. | 168 // |last_reports_sent_queue_|. |
178 if (!last_reports_sent_queue_.empty()) { | 169 if (!last_reports_sent_queue_.empty()) { |
179 DCHECK(now >= last_reports_sent_queue_.back().second); | 170 DCHECK(now >= last_reports_sent_queue_.back().second); |
180 } | 171 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 sender_info.ntp_fraction = current_ntp_fractions; | 236 sender_info.ntp_fraction = current_ntp_fractions; |
246 sender_info.rtp_timestamp = current_time_as_rtp_timestamp; | 237 sender_info.rtp_timestamp = current_time_as_rtp_timestamp; |
247 sender_info.send_packet_count = send_packet_count; | 238 sender_info.send_packet_count = send_packet_count; |
248 sender_info.send_octet_count = send_octet_count; | 239 sender_info.send_octet_count = send_octet_count; |
249 | 240 |
250 RtcpBuilder rtcp_builder(local_ssrc_); | 241 RtcpBuilder rtcp_builder(local_ssrc_); |
251 packet_sender_->SendRtcpPacket(local_ssrc_, | 242 packet_sender_->SendRtcpPacket(local_ssrc_, |
252 rtcp_builder.BuildRtcpFromSender(sender_info)); | 243 rtcp_builder.BuildRtcpFromSender(sender_info)); |
253 } | 244 } |
254 | 245 |
255 void SenderRtcpSession::OnReceivedCastFeedback( | |
256 const RtcpCastMessage& cast_message) { | |
257 if (cast_callback_.is_null()) | |
258 return; | |
259 cast_callback_.Run(cast_message); | |
260 } | |
261 | |
262 void SenderRtcpSession::OnReceivedReceiverLog( | |
263 const RtcpReceiverLogMessage& receiver_log) { | |
264 if (log_callback_.is_null()) | |
265 return; | |
266 log_callback_.Run(receiver_log); | |
267 } | |
268 | |
269 } // namespace cast | 246 } // namespace cast |
270 } // namespace media | 247 } // namespace media |
OLD | NEW |