1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/cast/net/rtcp/rtcp.h" 6 7 #include "media/cast/cast_config.h" 8 #include "media/cast/cast_defines.h" 9 #include "media/cast/cast_environment.h" 10 #include "media/cast/net/cast_transport_defines.h" 11 #include "media/cast/net/pacing/paced_sender.h" 12 #include "media/cast/net/rtcp/rtcp_builder.h" 13 #include "media/cast/net/rtcp/rtcp_defines.h" 14 #include "media/cast/net/rtcp/rtcp_utility.h" 15 16 using base::TimeDelta; 17 18 namespace media { 19 namespace cast { 20 21 static const int32 kStatsHistoryWindowMs = 10000; // 10 seconds. 22 // Reject packets that are older than 0.5 seconds older than 23 // the newest packet we've seen so far. This protect internal 24 // states from crazy routers. (Based on RRTR) 25 static const int32 kOutOfOrderMaxAgeMs = 500; 26 27 namespace { 28 29 // A receiver frame event is identified by frame RTP timestamp, event timestamp 30 // and event type. 31 // A receiver packet event is identified by all of the above plus packet id. 32 // The key format is as follows: 33 // First uint64: 34 // bits 0-11: zeroes (unused). 35 // bits 12-15: event type ID. 36 // bits 16-31: packet ID if packet event, 0 otherwise. 37 // bits 32-63: RTP timestamp. 38 // Second uint64: 39 // bits 0-63: event TimeTicks internal value. 40 std::pair<uint64, uint64> GetReceiverEventKey( 41 uint32 frame_rtp_timestamp, 42 const base::TimeTicks& event_timestamp, 43 uint8 event_type, 44 uint16 packet_id_or_zero) { 45 uint64 value1 = event_type; 46 value1 <<= 16; 47 value1 |= packet_id_or_zero; 48 value1 <<= 32; 49 value1 |= frame_rtp_timestamp; 50 return std::make_pair( 51 value1, static_cast<uint64>(event_timestamp.ToInternalValue())); 52 } 53 54 } // namespace 55 56 57 Rtcp::Rtcp(const RtcpCastMessageCallback& cast_callback, 58 const RtcpRttCallback& rtt_callback, 59 const RtcpLogMessageCallback& log_callback, 60 base::TickClock* clock, 61 PacedPacketSender* packet_sender, 62 uint32 local_ssrc, 63 uint32 remote_ssrc) 64 : cast_callback_(cast_callback), 65 rtt_callback_(rtt_callback), 66 log_callback_(log_callback), 67 clock_(clock), 68 rtcp_builder_(local_ssrc), 69 packet_sender_(packet_sender), 70 local_ssrc_(local_ssrc), 71 remote_ssrc_(remote_ssrc), 72 last_report_truncated_ntp_(0), 73 local_clock_ahead_by_(ClockDriftSmoother::GetDefaultTimeConstant()), 74 lip_sync_rtp_timestamp_(0), 75 lip_sync_ntp_timestamp_(0) { 76 } 77 78 Rtcp::~Rtcp() {} 79 80 bool Rtcp::IsRtcpPacket(const uint8* packet, size_t length) { 81 if (length < kMinLengthOfRtcp) { 82 LOG(ERROR) << "Invalid RTCP packet received."; 83 return false; 84 } 85 86 uint8 packet_type = packet[1]; 87 return packet_type >= kPacketTypeLow && packet_type <= kPacketTypeHigh; 88 } 89 90 uint32 Rtcp::GetSsrcOfSender(const uint8* rtcp_buffer, size_t length) { 91 if (length < kMinLengthOfRtcp) 92 return 0; 93 uint32 ssrc_of_sender; 94 base::BigEndianReader big_endian_reader( 95 reinterpret_cast<const char*>(rtcp_buffer), length); 96 big_endian_reader.Skip(4); // Skip header. 97 big_endian_reader.ReadU32(&ssrc_of_sender); 98 return ssrc_of_sender; 99 } 100 101 bool Rtcp::IncomingRtcpPacket(const uint8* data, size_t length) { 102 // Check if this is a valid RTCP packet. 103 if (!IsRtcpPacket(data, length)) { 104 VLOG(1) << "Rtcp@" << this << "::IncomingRtcpPacket() -- " 105 << "Received an invalid (non-RTCP?) packet."; 106 return false; 107 } 108 109 // Check if this packet is to us. 110 uint32 ssrc_of_sender = GetSsrcOfSender(data, length); 111 if (ssrc_of_sender != remote_ssrc_) { 112 return false; 113 } 114 115 // Parse this packet. 116 RtcpParser parser(local_ssrc_, remote_ssrc_); 117 base::BigEndianReader reader(reinterpret_cast<const char*>(data), length); 118 if (parser.Parse(&reader)) { 119 if (parser.has_receiver_reference_time_report()) { 120 base::TimeTicks t = ConvertNtpToTimeTicks( 121 parser.receiver_reference_time_report().ntp_seconds, 122 parser.receiver_reference_time_report().ntp_fraction); 123 if (t > largest_seen_timestamp_) { 124 largest_seen_timestamp_ = t; 125 } else if ((largest_seen_timestamp_ - t).InMilliseconds() > 126 kOutOfOrderMaxAgeMs) { 127 // Reject packet, it is too old. 128 VLOG(1) << "Rejecting RTCP packet as it is too old (" 129 << (largest_seen_timestamp_ - t).InMilliseconds() 130 << " ms)"; 131 return true; 132 } 133 134 OnReceivedNtp(parser.receiver_reference_time_report().ntp_seconds, 135 parser.receiver_reference_time_report().ntp_fraction); 136 } 137 if (parser.has_sender_report()) { 138 OnReceivedNtp(parser.sender_report().ntp_seconds, 139 parser.sender_report().ntp_fraction); 140 OnReceivedLipSyncInfo(parser.sender_report().rtp_timestamp, 141 parser.sender_report().ntp_seconds, 142 parser.sender_report().ntp_fraction); 143 } 144 if (parser.has_receiver_log()) { 145 if (DedupeReceiverLog(parser.mutable_receiver_log())) { 146 OnReceivedReceiverLog(parser.receiver_log()); 147 } 148 } 149 if (parser.has_last_report()) { 150 OnReceivedDelaySinceLastReport(parser.last_report(), 151 parser.delay_since_last_report()); 152 } 153 if (parser.has_cast_message()) { 154 parser.mutable_cast_message()->ack_frame_id = 155 ack_frame_id_wrap_helper_.MapTo32bitsFrameId( 156 parser.mutable_cast_message()->ack_frame_id); 157 OnReceivedCastFeedback(parser.cast_message()); 158 } 159 } 160 return true; 161 } 162 163 bool Rtcp::DedupeReceiverLog(RtcpReceiverLogMessage* receiver_log) { 164 RtcpReceiverLogMessage::iterator i = receiver_log->begin(); 165 while (i != receiver_log->end()) { 166 RtcpReceiverEventLogMessages* messages = &i->event_log_messages_; 167 RtcpReceiverEventLogMessages::iterator j = messages->begin(); 168 while (j != messages->end()) { 169 ReceiverEventKey key = GetReceiverEventKey(i->rtp_timestamp_, 170 j->event_timestamp, 171 j->type, 172 j->packet_id); 173 RtcpReceiverEventLogMessages::iterator tmp = j; 174 ++j; 175 if (receiver_event_key_set_.insert(key).second) { 176 receiver_event_key_queue_.push(key); 177 if (receiver_event_key_queue_.size() > kReceiverRtcpEventHistorySize) { 178 receiver_event_key_set_.erase(receiver_event_key_queue_.front()); 179 receiver_event_key_queue_.pop(); 180 } 181 } else { 182 messages->erase(tmp); 183 } 184 } 185 186 RtcpReceiverLogMessage::iterator tmp = i; 187 ++i; 188 if (messages->empty()) { 189 receiver_log->erase(tmp); 190 } 191 } 192 return !receiver_log->empty(); 193 } 194 195 void Rtcp::SendRtcpFromRtpReceiver( 196 const RtcpCastMessage* cast_message, 197 base::TimeDelta target_delay, 198 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, 199 RtpReceiverStatistics* rtp_receiver_statistics) { 200 base::TimeTicks now = clock_->NowTicks(); 201 RtcpReportBlock report_block; 202 RtcpReceiverReferenceTimeReport rrtr; 203 204 // Attach our NTP to all RTCP packets; with this information a "smart" sender 205 // can make decisions based on how old the RTCP message is. 206 ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction); 207 SaveLastSentNtpTime(now, rrtr.ntp_seconds, rrtr.ntp_fraction); 208 209 if (rtp_receiver_statistics) { 210 report_block.remote_ssrc = 0; // Not needed to set send side. 211 report_block.media_ssrc = remote_ssrc_; // SSRC of the RTP packet sender. 212 rtp_receiver_statistics->GetStatistics( 213 &report_block.fraction_lost, &report_block.cumulative_lost, 214 &report_block.extended_high_sequence_number, &report_block.jitter); 215 216 report_block.last_sr = last_report_truncated_ntp_; 217 if (!time_last_report_received_.is_null()) { 218 uint32 delay_seconds = 0; 219 uint32 delay_fraction = 0; 220 base::TimeDelta delta = now - time_last_report_received_; 221 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, 222 &delay_fraction); 223 report_block.delay_since_last_sr = 224 ConvertToNtpDiff(delay_seconds, delay_fraction); 225 } else { 226 report_block.delay_since_last_sr = 0; 227 } 228 } 229 packet_sender_->SendRtcpPacket( 230 local_ssrc_, 231 rtcp_builder_.BuildRtcpFromReceiver( 232 rtp_receiver_statistics ? &report_block : NULL, 233 &rrtr, 234 cast_message, 235 rtcp_events, 236 target_delay)); 237 } 238 239 void Rtcp::SendRtcpFromRtpSender(base::TimeTicks current_time, 240 uint32 current_time_as_rtp_timestamp, 241 uint32 send_packet_count, 242 size_t send_octet_count) { 243 uint32 current_ntp_seconds = 0; 244 uint32 current_ntp_fractions = 0; 245 ConvertTimeTicksToNtp(current_time, ¤t_ntp_seconds, 246 ¤t_ntp_fractions); 247 SaveLastSentNtpTime(current_time, current_ntp_seconds, 248 current_ntp_fractions); 249 250 RtcpSenderInfo sender_info; 251 sender_info.ntp_seconds = current_ntp_seconds; 252 sender_info.ntp_fraction = current_ntp_fractions; 253 sender_info.rtp_timestamp = current_time_as_rtp_timestamp; 254 sender_info.send_packet_count = send_packet_count; 255 sender_info.send_octet_count = send_octet_count; 256 257 packet_sender_->SendRtcpPacket( 258 local_ssrc_, 259 rtcp_builder_.BuildRtcpFromSender(sender_info)); 260 } 261 262 void Rtcp::OnReceivedNtp(uint32 ntp_seconds, uint32 ntp_fraction) { 263 last_report_truncated_ntp_ = ConvertToNtpDiff(ntp_seconds, ntp_fraction); 264 265 const base::TimeTicks now = clock_->NowTicks(); 266 time_last_report_received_ = now; 267 268 // TODO(miu): This clock offset calculation does not account for packet 269 // transit time over the network. End2EndTest.EvilNetwork confirms that this 270 // contributes a very significant source of error here. Determine whether 271 // RTT should be factored-in, and how that changes the rest of the 272 // calculation. 273 const base::TimeDelta measured_offset = 274 now - ConvertNtpToTimeTicks(ntp_seconds, ntp_fraction); 275 local_clock_ahead_by_.Update(now, measured_offset); 276 if (measured_offset < local_clock_ahead_by_.Current()) { 277 // Logically, the minimum offset between the clocks has to be the correct 278 // one. For example, the time it took to transmit the current report may 279 // have been lower than usual, and so some of the error introduced by the 280 // transmission time can be eliminated. 281 local_clock_ahead_by_.Reset(now, measured_offset); 282 } 283 VLOG(1) << "Local clock is ahead of the remote clock by: " 284 << "measured=" << measured_offset.InMicroseconds() << " usec, " 285 << "filtered=" << local_clock_ahead_by_.Current().InMicroseconds() 286 << " usec."; 287 } 288 289 void Rtcp::OnReceivedLipSyncInfo(uint32 rtp_timestamp, uint32 ntp_seconds, 290 uint32 ntp_fraction) { 291 if (ntp_seconds == 0) { 292 NOTREACHED(); 293 return; 294 } 295 lip_sync_rtp_timestamp_ = rtp_timestamp; 296 lip_sync_ntp_timestamp_ = 297 (static_cast<uint64>(ntp_seconds) << 32) | ntp_fraction; 298 } 299 300 bool Rtcp::GetLatestLipSyncTimes(uint32* rtp_timestamp, 301 base::TimeTicks* reference_time) const { 302 if (!lip_sync_ntp_timestamp_) 303 return false; 304 305 const base::TimeTicks local_reference_time = 306 ConvertNtpToTimeTicks(static_cast<uint32>(lip_sync_ntp_timestamp_ >> 32), 307 static_cast<uint32>(lip_sync_ntp_timestamp_)) + 308 local_clock_ahead_by_.Current(); 309 310 // Sanity-check: Getting regular lip sync updates? 311 DCHECK((clock_->NowTicks() - local_reference_time) < 312 base::TimeDelta::FromMinutes(1)); 313 314 *rtp_timestamp = lip_sync_rtp_timestamp_; 315 *reference_time = local_reference_time; 316 return true; 317 } 318 319 void Rtcp::OnReceivedDelaySinceLastReport(uint32 last_report, 320 uint32 delay_since_last_report) { 321 RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report); 322 if (it == last_reports_sent_map_.end()) { 323 return; // Feedback on another report. 324 } 325 326 const base::TimeDelta sender_delay = clock_->NowTicks() - it->second; 327 const base::TimeDelta receiver_delay = 328 ConvertFromNtpDiff(delay_since_last_report); 329 current_round_trip_time_ = sender_delay - receiver_delay; 330 // If the round trip time was computed as less than 1 ms, assume clock 331 // imprecision by one or both peers caused a bad value to be calculated. 332 // While plenty of networks do easily achieve less than 1 ms round trip time, 333 // such a level of precision cannot be measured with our approach; and 1 ms is 334 // good enough to represent "under 1 ms" for our use cases. 335 current_round_trip_time_ = 336 std::max(current_round_trip_time_, base::TimeDelta::FromMilliseconds(1)); 337 338 if (!rtt_callback_.is_null()) 339 rtt_callback_.Run(current_round_trip_time_); 340 } 341 342 void Rtcp::OnReceivedCastFeedback(const RtcpCastMessage& cast_message) { 343 if (cast_callback_.is_null()) 344 return; 345 cast_callback_.Run(cast_message); 346 } 347 348 void Rtcp::SaveLastSentNtpTime(const base::TimeTicks& now, 349 uint32 last_ntp_seconds, 350 uint32 last_ntp_fraction) { 351 // Make sure |now| is always greater than the last element in 352 // |last_reports_sent_queue_|. 353 if (!last_reports_sent_queue_.empty()) 354 DCHECK(now >= last_reports_sent_queue_.back().second); 355 356 uint32 last_report = ConvertToNtpDiff(last_ntp_seconds, last_ntp_fraction); 357 last_reports_sent_map_[last_report] = now; 358 last_reports_sent_queue_.push(std::make_pair(last_report, now)); 359 360 const base::TimeTicks timeout = 361 now - TimeDelta::FromMilliseconds(kStatsHistoryWindowMs); 362 363 // Cleanup old statistics older than |timeout|. 364 while (!last_reports_sent_queue_.empty()) { 365 RtcpSendTimePair oldest_report = last_reports_sent_queue_.front(); 366 if (oldest_report.second < timeout) { 367 last_reports_sent_map_.erase(oldest_report.first); 368 last_reports_sent_queue_.pop(); 369 } else { 370 break; 371 } 372 } 373 } 374 375 void Rtcp::OnReceivedReceiverLog(const RtcpReceiverLogMessage& receiver_log) { 376 if (log_callback_.is_null()) 377 return; 378 log_callback_.Run(receiver_log); 379 } 380 381 } // namespace cast 382 } // namespace media 383