1 // Copyright 2013 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/rtcp/rtcp.h" 6 7 #include "base/big_endian.h" 8 #include "base/rand_util.h" 9 #include "media/cast/cast_config.h" 10 #include "media/cast/cast_defines.h" 11 #include "media/cast/cast_environment.h" 12 #include "media/cast/rtcp/rtcp_defines.h" 13 #include "media/cast/rtcp/rtcp_receiver.h" 14 #include "media/cast/rtcp/rtcp_sender.h" 15 #include "media/cast/rtcp/rtcp_utility.h" 16 #include "media/cast/transport/cast_transport_defines.h" 17 18 namespace media { 19 namespace cast { 20 21 static const int kMaxRttMs = 10000; // 10 seconds. 22 static const int kMaxDelay = 2000; 23 24 class LocalRtcpRttFeedback : public RtcpRttFeedback { 25 public: 26 explicit LocalRtcpRttFeedback(Rtcp* rtcp) : rtcp_(rtcp) {} 27 28 virtual void OnReceivedDelaySinceLastReport( 29 uint32 receivers_ssrc, uint32 last_report, 30 uint32 delay_since_last_report) OVERRIDE { 31 rtcp_->OnReceivedDelaySinceLastReport(receivers_ssrc, last_report, 32 delay_since_last_report); 33 } 34 35 private: 36 Rtcp* rtcp_; 37 }; 38 39 class LocalRtcpReceiverFeedback : public RtcpReceiverFeedback { 40 public: 41 LocalRtcpReceiverFeedback(Rtcp* rtcp, 42 scoped_refptr<CastEnvironment> cast_environment) 43 : rtcp_(rtcp), cast_environment_(cast_environment) {} 44 45 virtual void OnReceivedSenderReport( 46 const transport::RtcpSenderInfo& remote_sender_info) OVERRIDE { 47 rtcp_->OnReceivedNtp(remote_sender_info.ntp_seconds, 48 remote_sender_info.ntp_fraction); 49 if (remote_sender_info.send_packet_count != 0) { 50 rtcp_->OnReceivedLipSyncInfo(remote_sender_info.rtp_timestamp, 51 remote_sender_info.ntp_seconds, 52 remote_sender_info.ntp_fraction); 53 } 54 } 55 56 virtual void OnReceiverReferenceTimeReport( 57 const RtcpReceiverReferenceTimeReport& remote_time_report) OVERRIDE { 58 rtcp_->OnReceivedNtp(remote_time_report.ntp_seconds, 59 remote_time_report.ntp_fraction); 60 } 61 62 virtual void OnReceivedSendReportRequest() OVERRIDE { 63 rtcp_->OnReceivedSendReportRequest(); 64 } 65 66 virtual void OnReceivedReceiverLog(const RtcpReceiverLogMessage& receiver_log) 67 OVERRIDE { 68 rtcp_->OnReceivedReceiverLog(receiver_log); 69 } 70 71 private: 72 Rtcp* rtcp_; 73 scoped_refptr<CastEnvironment> cast_environment_; 74 }; 75 76 Rtcp::Rtcp(scoped_refptr<CastEnvironment> cast_environment, 77 RtcpSenderFeedback* sender_feedback, 78 transport::CastTransportSender* const transport_sender, 79 transport::PacedPacketSender* paced_packet_sender, 80 RtpReceiverStatistics* rtp_receiver_statistics, RtcpMode rtcp_mode, 81 const base::TimeDelta& rtcp_interval, uint32 local_ssrc, 82 uint32 remote_ssrc, const std::string& c_name, 83 EventMediaType event_media_type) 84 : cast_environment_(cast_environment), 85 transport_sender_(transport_sender), 86 rtcp_interval_(rtcp_interval), 87 rtcp_mode_(rtcp_mode), 88 local_ssrc_(local_ssrc), 89 remote_ssrc_(remote_ssrc), 90 c_name_(c_name), 91 event_media_type_(event_media_type), 92 rtp_receiver_statistics_(rtp_receiver_statistics), 93 rtt_feedback_(new LocalRtcpRttFeedback(this)), 94 receiver_feedback_(new LocalRtcpReceiverFeedback(this, cast_environment)), 95 rtcp_sender_(new RtcpSender(cast_environment, paced_packet_sender, 96 local_ssrc, c_name)), 97 last_report_truncated_ntp_(0), 98 local_clock_ahead_by_(ClockDriftSmoother::GetDefaultTimeConstant()), 99 lip_sync_rtp_timestamp_(0), 100 lip_sync_ntp_timestamp_(0), 101 min_rtt_(base::TimeDelta::FromMilliseconds(kMaxRttMs)), 102 number_of_rtt_in_avg_(0) { 103 rtcp_receiver_.reset(new RtcpReceiver(cast_environment, sender_feedback, 104 receiver_feedback_.get(), 105 rtt_feedback_.get(), local_ssrc)); 106 rtcp_receiver_->SetRemoteSSRC(remote_ssrc); 107 } 108 109 Rtcp::~Rtcp() {} 110 111 // static 112 bool Rtcp::IsRtcpPacket(const uint8* packet, size_t length) { 113 DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet"; 114 if (length < kMinLengthOfRtcp) return false; 115 116 uint8 packet_type = packet[1]; 117 if (packet_type >= transport::kPacketTypeLow && 118 packet_type <= transport::kPacketTypeHigh) { 119 return true; 120 } 121 return false; 122 } 123 124 // static 125 uint32 Rtcp::GetSsrcOfSender(const uint8* rtcp_buffer, size_t length) { 126 DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet"; 127 uint32 ssrc_of_sender; 128 base::BigEndianReader big_endian_reader( 129 reinterpret_cast<const char*>(rtcp_buffer), length); 130 big_endian_reader.Skip(4); // Skip header 131 big_endian_reader.ReadU32(&ssrc_of_sender); 132 return ssrc_of_sender; 133 } 134 135 base::TimeTicks Rtcp::TimeToSendNextRtcpReport() { 136 if (next_time_to_send_rtcp_.is_null()) { 137 UpdateNextTimeToSendRtcp(); 138 } 139 return next_time_to_send_rtcp_; 140 } 141 142 void Rtcp::IncomingRtcpPacket(const uint8* rtcp_buffer, size_t length) { 143 RtcpParser rtcp_parser(rtcp_buffer, length); 144 if (!rtcp_parser.IsValid()) { 145 // Silently ignore packet. 146 DLOG(ERROR) << "Received invalid RTCP packet"; 147 return; 148 } 149 rtcp_receiver_->IncomingRtcpPacket(&rtcp_parser); 150 } 151 152 void Rtcp::SendRtcpFromRtpReceiver( 153 const RtcpCastMessage* cast_message, 154 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events) { 155 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); 156 uint32 packet_type_flags = 0; 157 158 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 159 transport::RtcpReportBlock report_block; 160 RtcpReceiverReferenceTimeReport rrtr; 161 162 // Attach our NTP to all RTCP packets; with this information a "smart" sender 163 // can make decisions based on how old the RTCP message is. 164 packet_type_flags |= transport::kRtcpRrtr; 165 ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction); 166 SaveLastSentNtpTime(now, rrtr.ntp_seconds, rrtr.ntp_fraction); 167 168 if (cast_message) { 169 packet_type_flags |= transport::kRtcpCast; 170 } 171 if (rtcp_events) { 172 packet_type_flags |= transport::kRtcpReceiverLog; 173 } 174 if (rtcp_mode_ == kRtcpCompound || now >= next_time_to_send_rtcp_) { 175 packet_type_flags |= transport::kRtcpRr; 176 177 report_block.remote_ssrc = 0; // Not needed to set send side. 178 report_block.media_ssrc = remote_ssrc_; // SSRC of the RTP packet sender. 179 if (rtp_receiver_statistics_) { 180 rtp_receiver_statistics_->GetStatistics( 181 &report_block.fraction_lost, &report_block.cumulative_lost, 182 &report_block.extended_high_sequence_number, &report_block.jitter); 183 } 184 185 report_block.last_sr = last_report_truncated_ntp_; 186 if (!time_last_report_received_.is_null()) { 187 uint32 delay_seconds = 0; 188 uint32 delay_fraction = 0; 189 base::TimeDelta delta = now - time_last_report_received_; 190 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, 191 &delay_fraction); 192 report_block.delay_since_last_sr = 193 ConvertToNtpDiff(delay_seconds, delay_fraction); 194 } else { 195 report_block.delay_since_last_sr = 0; 196 } 197 UpdateNextTimeToSendRtcp(); 198 } 199 rtcp_sender_->SendRtcpFromRtpReceiver(packet_type_flags, 200 &report_block, 201 &rrtr, 202 cast_message, 203 rtcp_events, 204 target_delay_ms_); 205 } 206 207 void Rtcp::SendRtcpFromRtpSender(base::TimeTicks current_time, 208 uint32 current_time_as_rtp_timestamp) { 209 DCHECK(transport_sender_); 210 uint32 packet_type_flags = transport::kRtcpSr; 211 uint32 current_ntp_seconds = 0; 212 uint32 current_ntp_fractions = 0; 213 ConvertTimeTicksToNtp(current_time, ¤t_ntp_seconds, 214 ¤t_ntp_fractions); 215 SaveLastSentNtpTime(current_time, current_ntp_seconds, 216 current_ntp_fractions); 217 218 transport::RtcpDlrrReportBlock dlrr; 219 if (!time_last_report_received_.is_null()) { 220 packet_type_flags |= transport::kRtcpDlrr; 221 dlrr.last_rr = last_report_truncated_ntp_; 222 uint32 delay_seconds = 0; 223 uint32 delay_fraction = 0; 224 base::TimeDelta delta = current_time - time_last_report_received_; 225 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, 226 &delay_fraction); 227 228 dlrr.delay_since_last_rr = ConvertToNtpDiff(delay_seconds, delay_fraction); 229 } 230 231 transport_sender_->SendRtcpFromRtpSender( 232 packet_type_flags, current_ntp_seconds, current_ntp_fractions, 233 current_time_as_rtp_timestamp, dlrr, local_ssrc_, c_name_); 234 UpdateNextTimeToSendRtcp(); 235 } 236 237 void Rtcp::OnReceivedNtp(uint32 ntp_seconds, uint32 ntp_fraction) { 238 last_report_truncated_ntp_ = ConvertToNtpDiff(ntp_seconds, ntp_fraction); 239 240 const base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 241 time_last_report_received_ = now; 242 243 // TODO(miu): This clock offset calculation does not account for packet 244 // transit time over the network. End2EndTest.EvilNetwork confirms that this 245 // contributes a very significant source of error here. Fix this along with 246 // the RTT clean-up. 247 const base::TimeDelta measured_offset = 248 now - ConvertNtpToTimeTicks(ntp_seconds, ntp_fraction); 249 local_clock_ahead_by_.Update(now, measured_offset); 250 if (measured_offset < local_clock_ahead_by_.Current()) { 251 // Logically, the minimum offset between the clocks has to be the correct 252 // one. For example, the time it took to transmit the current report may 253 // have been lower than usual, and so some of the error introduced by the 254 // transmission time can be eliminated. 255 local_clock_ahead_by_.Reset(now, measured_offset); 256 } 257 VLOG(1) << "Local clock is ahead of the remote clock by: " 258 << "measured=" << measured_offset.InMicroseconds() << " usec, " 259 << "filtered=" << local_clock_ahead_by_.Current().InMicroseconds() 260 << " usec."; 261 } 262 263 void Rtcp::OnReceivedLipSyncInfo(uint32 rtp_timestamp, uint32 ntp_seconds, 264 uint32 ntp_fraction) { 265 if (ntp_seconds == 0) { 266 NOTREACHED(); 267 return; 268 } 269 lip_sync_rtp_timestamp_ = rtp_timestamp; 270 lip_sync_ntp_timestamp_ = 271 (static_cast<uint64>(ntp_seconds) << 32) | ntp_fraction; 272 } 273 274 bool Rtcp::GetLatestLipSyncTimes(uint32* rtp_timestamp, 275 base::TimeTicks* reference_time) const { 276 if (!lip_sync_ntp_timestamp_) 277 return false; 278 279 const base::TimeTicks local_reference_time = 280 ConvertNtpToTimeTicks(static_cast<uint32>(lip_sync_ntp_timestamp_ >> 32), 281 static_cast<uint32>(lip_sync_ntp_timestamp_)) + 282 local_clock_ahead_by_.Current(); 283 284 // Sanity-check: Getting regular lip sync updates? 285 DCHECK((cast_environment_->Clock()->NowTicks() - local_reference_time) < 286 base::TimeDelta::FromMinutes(1)); 287 288 *rtp_timestamp = lip_sync_rtp_timestamp_; 289 *reference_time = local_reference_time; 290 return true; 291 } 292 293 void Rtcp::OnReceivedSendReportRequest() { 294 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 295 296 // Trigger a new RTCP report at next timer. 297 next_time_to_send_rtcp_ = now; 298 } 299 300 void Rtcp::SetCastReceiverEventHistorySize(size_t size) { 301 rtcp_receiver_->SetCastReceiverEventHistorySize(size); 302 } 303 304 void Rtcp::SetTargetDelay(base::TimeDelta target_delay) { 305 DCHECK(target_delay.InMilliseconds() < kMaxDelay); 306 target_delay_ms_ = static_cast<uint16>(target_delay.InMilliseconds()); 307 } 308 309 void Rtcp::OnReceivedDelaySinceLastReport(uint32 receivers_ssrc, 310 uint32 last_report, 311 uint32 delay_since_last_report) { 312 RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report); 313 if (it == last_reports_sent_map_.end()) { 314 return; // Feedback on another report. 315 } 316 317 base::TimeDelta sender_delay = 318 cast_environment_->Clock()->NowTicks() - it->second; 319 UpdateRtt(sender_delay, ConvertFromNtpDiff(delay_since_last_report)); 320 } 321 322 void Rtcp::SaveLastSentNtpTime(const base::TimeTicks& now, 323 uint32 last_ntp_seconds, 324 uint32 last_ntp_fraction) { 325 // Make sure |now| is always greater than the last element in 326 // |last_reports_sent_queue_|. 327 if (!last_reports_sent_queue_.empty()) 328 DCHECK(now >= last_reports_sent_queue_.back().second); 329 330 uint32 last_report = ConvertToNtpDiff(last_ntp_seconds, last_ntp_fraction); 331 last_reports_sent_map_[last_report] = now; 332 last_reports_sent_queue_.push(std::make_pair(last_report, now)); 333 334 base::TimeTicks timeout = now - base::TimeDelta::FromMilliseconds(kMaxRttMs); 335 336 // Cleanup old statistics older than |timeout|. 337 while (!last_reports_sent_queue_.empty()) { 338 RtcpSendTimePair oldest_report = last_reports_sent_queue_.front(); 339 if (oldest_report.second < timeout) { 340 last_reports_sent_map_.erase(oldest_report.first); 341 last_reports_sent_queue_.pop(); 342 } else { 343 break; 344 } 345 } 346 } 347 348 void Rtcp::UpdateRtt(const base::TimeDelta& sender_delay, 349 const base::TimeDelta& receiver_delay) { 350 base::TimeDelta rtt = sender_delay - receiver_delay; 351 // TODO(miu): Find out why this must be >= 1 ms, and remove the fudge if it's 352 // bogus. 353 rtt = std::max(rtt, base::TimeDelta::FromMilliseconds(1)); 354 rtt_ = rtt; 355 min_rtt_ = std::min(min_rtt_, rtt); 356 max_rtt_ = std::max(max_rtt_, rtt); 357 358 // TODO(miu): Replace "average for all time" with an EWMA, or suitable 359 // "average over recent past" mechanism. 360 if (number_of_rtt_in_avg_ != 0) { 361 const double ac = static_cast<double>(number_of_rtt_in_avg_); 362 avg_rtt_ms_ = ((ac / (ac + 1.0)) * avg_rtt_ms_) + 363 ((1.0 / (ac + 1.0)) * rtt.InMillisecondsF()); 364 } else { 365 avg_rtt_ms_ = rtt.InMillisecondsF(); 366 } 367 number_of_rtt_in_avg_++; 368 } 369 370 bool Rtcp::Rtt(base::TimeDelta* rtt, base::TimeDelta* avg_rtt, 371 base::TimeDelta* min_rtt, base::TimeDelta* max_rtt) const { 372 DCHECK(rtt) << "Invalid argument"; 373 DCHECK(avg_rtt) << "Invalid argument"; 374 DCHECK(min_rtt) << "Invalid argument"; 375 DCHECK(max_rtt) << "Invalid argument"; 376 377 if (number_of_rtt_in_avg_ == 0) return false; 378 379 *rtt = rtt_; 380 *avg_rtt = base::TimeDelta::FromMillisecondsD(avg_rtt_ms_); 381 *min_rtt = min_rtt_; 382 *max_rtt = max_rtt_; 383 return true; 384 } 385 386 void Rtcp::UpdateNextTimeToSendRtcp() { 387 int random = base::RandInt(0, 999); 388 base::TimeDelta time_to_next = 389 (rtcp_interval_ / 2) + (rtcp_interval_ * random / 1000); 390 391 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 392 next_time_to_send_rtcp_ = now + time_to_next; 393 } 394 395 void Rtcp::OnReceivedReceiverLog(const RtcpReceiverLogMessage& receiver_log) { 396 // Add received log messages into our log system. 397 RtcpReceiverLogMessage::const_iterator it = receiver_log.begin(); 398 for (; it != receiver_log.end(); ++it) { 399 uint32 rtp_timestamp = it->rtp_timestamp_; 400 401 RtcpReceiverEventLogMessages::const_iterator event_it = 402 it->event_log_messages_.begin(); 403 for (; event_it != it->event_log_messages_.end(); ++event_it) { 404 switch (event_it->type) { 405 case PACKET_RECEIVED: 406 cast_environment_->Logging()->InsertPacketEvent( 407 event_it->event_timestamp, event_it->type, 408 event_media_type_, rtp_timestamp, 409 kFrameIdUnknown, event_it->packet_id, 0, 0); 410 break; 411 case FRAME_ACK_SENT: 412 case FRAME_DECODED: 413 cast_environment_->Logging()->InsertFrameEvent( 414 event_it->event_timestamp, event_it->type, event_media_type_, 415 rtp_timestamp, kFrameIdUnknown); 416 break; 417 case FRAME_PLAYOUT: 418 cast_environment_->Logging()->InsertFrameEventWithDelay( 419 event_it->event_timestamp, event_it->type, event_media_type_, 420 rtp_timestamp, kFrameIdUnknown, event_it->delay_delta); 421 break; 422 default: 423 VLOG(2) << "Received log message via RTCP that we did not expect: " 424 << static_cast<int>(event_it->type); 425 break; 426 } 427 } 428 } 429 } 430 431 } // namespace cast 432 } // namespace media 433