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/rand_util.h" 8 #include "media/cast/cast_config.h" 9 #include "media/cast/cast_defines.h" 10 #include "media/cast/cast_environment.h" 11 #include "media/cast/rtcp/rtcp_defines.h" 12 #include "media/cast/rtcp/rtcp_receiver.h" 13 #include "media/cast/rtcp/rtcp_sender.h" 14 #include "media/cast/rtcp/rtcp_utility.h" 15 #include "net/base/big_endian.h" 16 17 namespace media { 18 namespace cast { 19 20 static const int kMaxRttMs = 10000; // 10 seconds. 21 22 // Time limit for received RTCP messages when we stop using it for lip-sync. 23 static const int64 kMaxDiffSinceReceivedRtcpMs = 100000; // 100 seconds. 24 25 class LocalRtcpRttFeedback : public RtcpRttFeedback { 26 public: 27 explicit LocalRtcpRttFeedback(Rtcp* rtcp) 28 : rtcp_(rtcp) { 29 } 30 31 virtual void OnReceivedDelaySinceLastReport( 32 uint32 receivers_ssrc, 33 uint32 last_report, 34 uint32 delay_since_last_report) OVERRIDE { 35 rtcp_->OnReceivedDelaySinceLastReport(receivers_ssrc, 36 last_report, 37 delay_since_last_report); 38 } 39 40 private: 41 Rtcp* rtcp_; 42 }; 43 44 RtcpCastMessage::RtcpCastMessage(uint32 media_ssrc) 45 : media_ssrc_(media_ssrc) {} 46 47 RtcpCastMessage::~RtcpCastMessage() {} 48 49 RtcpNackMessage::RtcpNackMessage() {} 50 RtcpNackMessage::~RtcpNackMessage() {} 51 52 RtcpRembMessage::RtcpRembMessage() {} 53 RtcpRembMessage::~RtcpRembMessage() {} 54 55 RtcpReceiverFrameLogMessage::RtcpReceiverFrameLogMessage(uint32 timestamp) 56 : rtp_timestamp_(timestamp) {} 57 58 RtcpReceiverFrameLogMessage::~RtcpReceiverFrameLogMessage() {} 59 60 class LocalRtcpReceiverFeedback : public RtcpReceiverFeedback { 61 public: 62 LocalRtcpReceiverFeedback(Rtcp* rtcp, 63 scoped_refptr<CastEnvironment> cast_environment) 64 : rtcp_(rtcp), cast_environment_(cast_environment) { 65 } 66 67 virtual void OnReceivedSenderReport( 68 const RtcpSenderInfo& remote_sender_info) OVERRIDE { 69 rtcp_->OnReceivedNtp(remote_sender_info.ntp_seconds, 70 remote_sender_info.ntp_fraction); 71 if (remote_sender_info.send_packet_count != 0) { 72 rtcp_->OnReceivedLipSyncInfo(remote_sender_info.rtp_timestamp, 73 remote_sender_info.ntp_seconds, 74 remote_sender_info.ntp_fraction); 75 } 76 } 77 78 virtual void OnReceiverReferenceTimeReport( 79 const RtcpReceiverReferenceTimeReport& remote_time_report) OVERRIDE { 80 rtcp_->OnReceivedNtp(remote_time_report.ntp_seconds, 81 remote_time_report.ntp_fraction); 82 } 83 84 virtual void OnReceivedSendReportRequest() OVERRIDE { 85 rtcp_->OnReceivedSendReportRequest(); 86 } 87 88 virtual void OnReceivedReceiverLog( 89 const RtcpReceiverLogMessage& receiver_log) OVERRIDE { 90 // Add received log messages into our log system. 91 RtcpReceiverLogMessage::const_iterator it = receiver_log.begin(); 92 93 for (; it != receiver_log.end(); ++it) { 94 uint32 rtp_timestamp = it->rtp_timestamp_; 95 96 RtcpReceiverEventLogMessages::const_iterator event_it = 97 it->event_log_messages_.begin(); 98 for (; event_it != it->event_log_messages_.end(); ++event_it) { 99 // TODO(pwestin): we need to send in the event_it->event_timestamp to 100 // the log system too. 101 switch (event_it->type) { 102 case kPacketReceived: 103 cast_environment_->Logging()->InsertPacketEvent(kPacketReceived, 104 rtp_timestamp, kFrameIdUnknown, event_it->packet_id, 0, 0); 105 break; 106 case kAckSent: 107 case kAudioFrameDecoded: 108 case kVideoFrameDecoded: 109 cast_environment_->Logging()->InsertFrameEvent(event_it->type, 110 rtp_timestamp, kFrameIdUnknown); 111 break; 112 case kAudioPlayoutDelay: 113 case kVideoRenderDelay: 114 cast_environment_->Logging()->InsertFrameEventWithDelay( 115 event_it->type, rtp_timestamp, kFrameIdUnknown, 116 event_it->delay_delta); 117 break; 118 default: 119 VLOG(2) << "Received log message via RTCP that we did not expect: " 120 << static_cast<int>(event_it->type); 121 break; 122 } 123 } 124 } 125 } 126 127 virtual void OnReceivedSenderLog( 128 const RtcpSenderLogMessage& sender_log) OVERRIDE { 129 RtcpSenderLogMessage::const_iterator it = sender_log.begin(); 130 131 for (; it != sender_log.end(); ++it) { 132 uint32 rtp_timestamp = it->rtp_timestamp; 133 CastLoggingEvent log_event = kUnknown; 134 135 // These events are provided to know the status of frames that never 136 // reached the receiver. The timing information for these events are not 137 // relevant and is not sent over the wire. 138 switch (it->frame_status) { 139 case kRtcpSenderFrameStatusDroppedByFlowControl: 140 // A frame that have been dropped by the flow control would have 141 // kVideoFrameCaptured as its last event in the log. 142 log_event = kVideoFrameCaptured; 143 break; 144 case kRtcpSenderFrameStatusDroppedByEncoder: 145 // A frame that have been dropped by the encoder would have 146 // kVideoFrameSentToEncoder as its last event in the log. 147 log_event = kVideoFrameSentToEncoder; 148 break; 149 case kRtcpSenderFrameStatusSentToNetwork: 150 // A frame that have be encoded is always sent to the network. We 151 // do not add a new log entry for this. 152 log_event = kVideoFrameEncoded; 153 break; 154 default: 155 continue; 156 } 157 // TODO(pwestin): how do we handle the truncated rtp_timestamp? 158 // Add received log messages into our log system. 159 cast_environment_->Logging()->InsertFrameEvent(log_event, rtp_timestamp, 160 kFrameIdUnknown); 161 } 162 } 163 164 private: 165 Rtcp* rtcp_; 166 scoped_refptr<CastEnvironment> cast_environment_; 167 }; 168 169 Rtcp::Rtcp(scoped_refptr<CastEnvironment> cast_environment, 170 RtcpSenderFeedback* sender_feedback, 171 PacedPacketSender* paced_packet_sender, 172 RtpSenderStatistics* rtp_sender_statistics, 173 RtpReceiverStatistics* rtp_receiver_statistics, 174 RtcpMode rtcp_mode, 175 const base::TimeDelta& rtcp_interval, 176 uint32 local_ssrc, 177 uint32 remote_ssrc, 178 const std::string& c_name) 179 : rtcp_interval_(rtcp_interval), 180 rtcp_mode_(rtcp_mode), 181 local_ssrc_(local_ssrc), 182 remote_ssrc_(remote_ssrc), 183 rtp_sender_statistics_(rtp_sender_statistics), 184 rtp_receiver_statistics_(rtp_receiver_statistics), 185 receiver_feedback_(new LocalRtcpReceiverFeedback(this, cast_environment)), 186 rtt_feedback_(new LocalRtcpRttFeedback(this)), 187 rtcp_sender_(new RtcpSender(cast_environment, paced_packet_sender, 188 local_ssrc, c_name)), 189 last_report_received_(0), 190 last_received_rtp_timestamp_(0), 191 last_received_ntp_seconds_(0), 192 last_received_ntp_fraction_(0), 193 min_rtt_(base::TimeDelta::FromMilliseconds(kMaxRttMs)), 194 number_of_rtt_in_avg_(0), 195 cast_environment_(cast_environment) { 196 rtcp_receiver_.reset(new RtcpReceiver(cast_environment, 197 sender_feedback, 198 receiver_feedback_.get(), 199 rtt_feedback_.get(), 200 local_ssrc)); 201 rtcp_receiver_->SetRemoteSSRC(remote_ssrc); 202 } 203 204 Rtcp::~Rtcp() {} 205 206 // static 207 bool Rtcp::IsRtcpPacket(const uint8* packet, size_t length) { 208 DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet"; 209 if (length < kMinLengthOfRtcp) return false; 210 211 uint8 packet_type = packet[1]; 212 if (packet_type >= kPacketTypeLow && packet_type <= kPacketTypeHigh) { 213 return true; 214 } 215 return false; 216 } 217 218 // static 219 uint32 Rtcp::GetSsrcOfSender(const uint8* rtcp_buffer, size_t length) { 220 DCHECK_GE(length, kMinLengthOfRtcp) << "Invalid RTCP packet"; 221 uint32 ssrc_of_sender; 222 net::BigEndianReader big_endian_reader(rtcp_buffer, length); 223 big_endian_reader.Skip(4); // Skip header 224 big_endian_reader.ReadU32(&ssrc_of_sender); 225 return ssrc_of_sender; 226 } 227 228 base::TimeTicks Rtcp::TimeToSendNextRtcpReport() { 229 if (next_time_to_send_rtcp_.is_null()) { 230 UpdateNextTimeToSendRtcp(); 231 } 232 return next_time_to_send_rtcp_; 233 } 234 235 void Rtcp::IncomingRtcpPacket(const uint8* rtcp_buffer, size_t length) { 236 RtcpParser rtcp_parser(rtcp_buffer, length); 237 if (!rtcp_parser.IsValid()) { 238 // Silently ignore packet. 239 DLOG(ERROR) << "Received invalid RTCP packet"; 240 return; 241 } 242 rtcp_receiver_->IncomingRtcpPacket(&rtcp_parser); 243 } 244 245 void Rtcp::SendRtcpFromRtpReceiver(const RtcpCastMessage* cast_message, 246 RtcpReceiverLogMessage* receiver_log) { 247 uint32 packet_type_flags = 0; 248 249 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 250 RtcpReportBlock report_block; 251 RtcpReceiverReferenceTimeReport rrtr; 252 253 if (cast_message) { 254 packet_type_flags |= RtcpSender::kRtcpCast; 255 cast_environment_->Logging()->InsertGenericEvent(kAckSent, 256 cast_message->ack_frame_id_); 257 } 258 if (receiver_log) { 259 packet_type_flags |= RtcpSender::kRtcpReceiverLog; 260 } 261 if (rtcp_mode_ == kRtcpCompound || now >= next_time_to_send_rtcp_) { 262 packet_type_flags |= RtcpSender::kRtcpRr; 263 264 report_block.remote_ssrc = 0; // Not needed to set send side. 265 report_block.media_ssrc = remote_ssrc_; // SSRC of the RTP packet sender. 266 if (rtp_receiver_statistics_) { 267 rtp_receiver_statistics_->GetStatistics( 268 &report_block.fraction_lost, 269 &report_block.cumulative_lost, 270 &report_block.extended_high_sequence_number, 271 &report_block.jitter); 272 cast_environment_->Logging()->InsertGenericEvent(kJitterMs, 273 report_block.jitter); 274 cast_environment_->Logging()->InsertGenericEvent(kPacketLoss, 275 report_block.fraction_lost); 276 277 } 278 279 report_block.last_sr = last_report_received_; 280 if (!time_last_report_received_.is_null()) { 281 uint32 delay_seconds = 0; 282 uint32 delay_fraction = 0; 283 base::TimeDelta delta = now - time_last_report_received_; 284 ConvertTimeToFractions(delta.InMicroseconds(), 285 &delay_seconds, 286 &delay_fraction); 287 report_block.delay_since_last_sr = 288 ConvertToNtpDiff(delay_seconds, delay_fraction); 289 } else { 290 report_block.delay_since_last_sr = 0; 291 } 292 293 packet_type_flags |= RtcpSender::kRtcpRrtr; 294 ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction); 295 SaveLastSentNtpTime(now, rrtr.ntp_seconds, rrtr.ntp_fraction); 296 UpdateNextTimeToSendRtcp(); 297 } 298 rtcp_sender_->SendRtcpFromRtpReceiver(packet_type_flags, 299 &report_block, 300 &rrtr, 301 cast_message, 302 receiver_log); 303 } 304 305 void Rtcp::SendRtcpFromRtpSender( 306 RtcpSenderLogMessage* sender_log_message) { 307 uint32 packet_type_flags = RtcpSender::kRtcpSr; 308 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 309 310 if (sender_log_message) { 311 packet_type_flags |= RtcpSender::kRtcpSenderLog; 312 } 313 314 RtcpSenderInfo sender_info; 315 if (rtp_sender_statistics_) { 316 rtp_sender_statistics_->GetStatistics(now, &sender_info); 317 } else { 318 memset(&sender_info, 0, sizeof(sender_info)); 319 } 320 SaveLastSentNtpTime(now, sender_info.ntp_seconds, sender_info.ntp_fraction); 321 322 RtcpDlrrReportBlock dlrr; 323 if (!time_last_report_received_.is_null()) { 324 packet_type_flags |= RtcpSender::kRtcpDlrr; 325 dlrr.last_rr = last_report_received_; 326 uint32 delay_seconds = 0; 327 uint32 delay_fraction = 0; 328 base::TimeDelta delta = now - time_last_report_received_; 329 ConvertTimeToFractions(delta.InMicroseconds(), 330 &delay_seconds, 331 &delay_fraction); 332 333 dlrr.delay_since_last_rr = ConvertToNtpDiff(delay_seconds, delay_fraction); 334 } 335 336 rtcp_sender_->SendRtcpFromRtpSender(packet_type_flags, 337 &sender_info, 338 &dlrr, 339 sender_log_message); 340 UpdateNextTimeToSendRtcp(); 341 } 342 343 void Rtcp::OnReceivedNtp(uint32 ntp_seconds, uint32 ntp_fraction) { 344 last_report_received_ = (ntp_seconds << 16) + (ntp_fraction >> 16); 345 346 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 347 time_last_report_received_ = now; 348 } 349 350 void Rtcp::OnReceivedLipSyncInfo(uint32 rtp_timestamp, 351 uint32 ntp_seconds, 352 uint32 ntp_fraction) { 353 last_received_rtp_timestamp_ = rtp_timestamp; 354 last_received_ntp_seconds_ = ntp_seconds; 355 last_received_ntp_fraction_ = ntp_fraction; 356 } 357 358 void Rtcp::OnReceivedSendReportRequest() { 359 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 360 361 // Trigger a new RTCP report at next timer. 362 next_time_to_send_rtcp_ = now; 363 } 364 365 bool Rtcp::RtpTimestampInSenderTime(int frequency, uint32 rtp_timestamp, 366 base::TimeTicks* rtp_timestamp_in_ticks) const { 367 if (last_received_ntp_seconds_ == 0) return false; 368 369 int wrap = CheckForWrapAround(rtp_timestamp, last_received_rtp_timestamp_); 370 int64 rtp_timestamp_int64 = rtp_timestamp; 371 int64 last_received_rtp_timestamp_int64 = last_received_rtp_timestamp_; 372 373 if (wrap == 1) { 374 rtp_timestamp_int64 += (1LL << 32); 375 } else if (wrap == -1) { 376 last_received_rtp_timestamp_int64 += (1LL << 32); 377 } 378 // Time since the last RTCP message. 379 // Note that this can be negative since we can compare a rtp timestamp from 380 // a frame older than the last received RTCP message. 381 int64 rtp_timestamp_diff = 382 rtp_timestamp_int64 - last_received_rtp_timestamp_int64; 383 384 int frequency_khz = frequency / 1000; 385 int64 rtp_time_diff_ms = rtp_timestamp_diff / frequency_khz; 386 387 // Sanity check. 388 if (abs(rtp_time_diff_ms) > kMaxDiffSinceReceivedRtcpMs) return false; 389 390 *rtp_timestamp_in_ticks = ConvertNtpToTimeTicks(last_received_ntp_seconds_, 391 last_received_ntp_fraction_) + 392 base::TimeDelta::FromMilliseconds(rtp_time_diff_ms); 393 return true; 394 } 395 396 void Rtcp::OnReceivedDelaySinceLastReport(uint32 receivers_ssrc, 397 uint32 last_report, 398 uint32 delay_since_last_report) { 399 RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report); 400 if (it == last_reports_sent_map_.end()) { 401 return; // Feedback on another report. 402 } 403 404 base::TimeDelta sender_delay = cast_environment_->Clock()->NowTicks() 405 - it->second; 406 UpdateRtt(sender_delay, ConvertFromNtpDiff(delay_since_last_report)); 407 } 408 409 void Rtcp::SaveLastSentNtpTime(const base::TimeTicks& now, 410 uint32 last_ntp_seconds, 411 uint32 last_ntp_fraction) { 412 // Make sure |now| is always greater than the last element in 413 // |last_reports_sent_queue_|. 414 if (!last_reports_sent_queue_.empty()) { 415 DCHECK(now >= last_reports_sent_queue_.back().second); 416 } 417 418 uint32 last_report = ConvertToNtpDiff(last_ntp_seconds, last_ntp_fraction); 419 last_reports_sent_map_[last_report] = now; 420 last_reports_sent_queue_.push(std::make_pair(last_report, now)); 421 422 base::TimeTicks timeout = now - base::TimeDelta::FromMilliseconds(kMaxRttMs); 423 424 // Cleanup old statistics older than |timeout|. 425 while (!last_reports_sent_queue_.empty()) { 426 RtcpSendTimePair oldest_report = last_reports_sent_queue_.front(); 427 if (oldest_report.second < timeout) { 428 last_reports_sent_map_.erase(oldest_report.first); 429 last_reports_sent_queue_.pop(); 430 } else { 431 break; 432 } 433 } 434 } 435 436 void Rtcp::UpdateRtt(const base::TimeDelta& sender_delay, 437 const base::TimeDelta& receiver_delay) { 438 base::TimeDelta rtt = sender_delay - receiver_delay; 439 rtt = std::max(rtt, base::TimeDelta::FromMilliseconds(1)); 440 rtt_ = rtt; 441 min_rtt_ = std::min(min_rtt_, rtt); 442 max_rtt_ = std::max(max_rtt_, rtt); 443 444 if (number_of_rtt_in_avg_ != 0) { 445 float ac = static_cast<float>(number_of_rtt_in_avg_); 446 avg_rtt_ms_= ((ac / (ac + 1.0)) * avg_rtt_ms_) + 447 ((1.0 / (ac + 1.0)) * rtt.InMilliseconds()); 448 } else { 449 avg_rtt_ms_ = rtt.InMilliseconds(); 450 } 451 number_of_rtt_in_avg_++; 452 } 453 454 bool Rtcp::Rtt(base::TimeDelta* rtt, 455 base::TimeDelta* avg_rtt, 456 base::TimeDelta* min_rtt, 457 base::TimeDelta* max_rtt) const { 458 DCHECK(rtt) << "Invalid argument"; 459 DCHECK(avg_rtt) << "Invalid argument"; 460 DCHECK(min_rtt) << "Invalid argument"; 461 DCHECK(max_rtt) << "Invalid argument"; 462 463 if (number_of_rtt_in_avg_ == 0) return false; 464 cast_environment_->Logging()->InsertGenericEvent(kRttMs, 465 rtt->InMilliseconds()); 466 467 *rtt = rtt_; 468 *avg_rtt = base::TimeDelta::FromMilliseconds(avg_rtt_ms_); 469 *min_rtt = min_rtt_; 470 *max_rtt = max_rtt_; 471 return true; 472 } 473 474 int Rtcp::CheckForWrapAround(uint32 new_timestamp, 475 uint32 old_timestamp) const { 476 if (new_timestamp < old_timestamp) { 477 // This difference should be less than -2^31 if we have had a wrap around 478 // (e.g. |new_timestamp| = 1, |rtcp_rtp_timestamp| = 2^32 - 1). Since it is 479 // cast to a int32_t, it should be positive. 480 if (static_cast<int32>(new_timestamp - old_timestamp) > 0) { 481 return 1; // Forward wrap around. 482 } 483 } else if (static_cast<int32>(old_timestamp - new_timestamp) > 0) { 484 // This difference should be less than -2^31 if we have had a backward wrap 485 // around. Since it is cast to a int32, it should be positive. 486 return -1; 487 } 488 return 0; 489 } 490 491 void Rtcp::UpdateNextTimeToSendRtcp() { 492 int random = base::RandInt(0, 999); 493 base::TimeDelta time_to_next = (rtcp_interval_ / 2) + 494 (rtcp_interval_ * random / 1000); 495 496 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); 497 next_time_to_send_rtcp_ = now + time_to_next; 498 } 499 500 } // namespace cast 501 } // namespace media 502