| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "media/cast/rtcp/rtcp.h" | 5 #include "media/cast/rtcp/rtcp.h" |
| 6 | 6 |
| 7 #include "base/big_endian.h" | 7 #include "base/big_endian.h" |
| 8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
| 9 #include "media/cast/cast_config.h" | 9 #include "media/cast/cast_config.h" |
| 10 #include "media/cast/cast_defines.h" | 10 #include "media/cast/cast_defines.h" |
| 11 #include "media/cast/cast_environment.h" | 11 #include "media/cast/cast_environment.h" |
| 12 #include "media/cast/rtcp/rtcp_defines.h" | 12 #include "media/cast/rtcp/rtcp_defines.h" |
| 13 #include "media/cast/rtcp/rtcp_receiver.h" | 13 #include "media/cast/rtcp/rtcp_receiver.h" |
| 14 #include "media/cast/rtcp/rtcp_sender.h" | 14 #include "media/cast/rtcp/rtcp_sender.h" |
| 15 #include "media/cast/rtcp/rtcp_utility.h" | 15 #include "media/cast/rtcp/rtcp_utility.h" |
| 16 #include "media/cast/transport/cast_transport_defines.h" | 16 #include "media/cast/transport/cast_transport_defines.h" |
| 17 | 17 |
| 18 namespace media { | 18 namespace media { |
| 19 namespace cast { | 19 namespace cast { |
| 20 | 20 |
| 21 static const int kMaxRttMs = 10000; // 10 seconds. | 21 static const int kMaxRttMs = 10000; // 10 seconds. |
| 22 static const uint16 kMaxDelay = 2000; |
| 22 | 23 |
| 23 // Time limit for received RTCP messages when we stop using it for lip-sync. | 24 // Time limit for received RTCP messages when we stop using it for lip-sync. |
| 24 static const int64 kMaxDiffSinceReceivedRtcpMs = 100000; // 100 seconds. | 25 static const int64 kMaxDiffSinceReceivedRtcpMs = 100000; // 100 seconds. |
| 25 | 26 |
| 26 class LocalRtcpRttFeedback : public RtcpRttFeedback { | 27 class LocalRtcpRttFeedback : public RtcpRttFeedback { |
| 27 public: | 28 public: |
| 28 explicit LocalRtcpRttFeedback(Rtcp* rtcp) : rtcp_(rtcp) {} | 29 explicit LocalRtcpRttFeedback(Rtcp* rtcp) : rtcp_(rtcp) {} |
| 29 | 30 |
| 30 virtual void OnReceivedDelaySinceLastReport( | 31 virtual void OnReceivedDelaySinceLastReport( |
| 31 uint32 receivers_ssrc, uint32 last_report, | 32 uint32 receivers_ssrc, uint32 last_report, |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 const ReceiverRtcpEventSubscriber* event_subscriber) { | 235 const ReceiverRtcpEventSubscriber* event_subscriber) { |
| 235 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); | 236 DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN)); |
| 236 uint32 packet_type_flags = 0; | 237 uint32 packet_type_flags = 0; |
| 237 | 238 |
| 238 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 239 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
| 239 transport::RtcpReportBlock report_block; | 240 transport::RtcpReportBlock report_block; |
| 240 RtcpReceiverReferenceTimeReport rrtr; | 241 RtcpReceiverReferenceTimeReport rrtr; |
| 241 | 242 |
| 242 // Attach our NTP to all RTCP packets; with this information a "smart" sender | 243 // Attach our NTP to all RTCP packets; with this information a "smart" sender |
| 243 // can make decisions based on how old the RTCP message is. | 244 // can make decisions based on how old the RTCP message is. |
| 244 packet_type_flags |= RtcpSender::kRtcpRrtr; | 245 packet_type_flags |= transport::kRtcpRrtr; |
| 245 ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction); | 246 ConvertTimeTicksToNtp(now, &rrtr.ntp_seconds, &rrtr.ntp_fraction); |
| 246 SaveLastSentNtpTime(now, rrtr.ntp_seconds, rrtr.ntp_fraction); | 247 SaveLastSentNtpTime(now, rrtr.ntp_seconds, rrtr.ntp_fraction); |
| 247 | 248 |
| 248 if (cast_message) { | 249 if (cast_message) { |
| 249 packet_type_flags |= RtcpSender::kRtcpCast; | 250 packet_type_flags |= transport::kRtcpCast; |
| 250 } | 251 } |
| 251 if (event_subscriber) { | 252 if (event_subscriber) { |
| 252 packet_type_flags |= RtcpSender::kRtcpReceiverLog; | 253 packet_type_flags |= transport::kRtcpReceiverLog; |
| 253 } | 254 } |
| 254 if (rtcp_mode_ == kRtcpCompound || now >= next_time_to_send_rtcp_) { | 255 if (rtcp_mode_ == kRtcpCompound || now >= next_time_to_send_rtcp_) { |
| 255 packet_type_flags |= RtcpSender::kRtcpRr; | 256 packet_type_flags |= transport::kRtcpRr; |
| 256 | 257 |
| 257 report_block.remote_ssrc = 0; // Not needed to set send side. | 258 report_block.remote_ssrc = 0; // Not needed to set send side. |
| 258 report_block.media_ssrc = remote_ssrc_; // SSRC of the RTP packet sender. | 259 report_block.media_ssrc = remote_ssrc_; // SSRC of the RTP packet sender. |
| 259 if (rtp_receiver_statistics_) { | 260 if (rtp_receiver_statistics_) { |
| 260 rtp_receiver_statistics_->GetStatistics( | 261 rtp_receiver_statistics_->GetStatistics( |
| 261 &report_block.fraction_lost, &report_block.cumulative_lost, | 262 &report_block.fraction_lost, &report_block.cumulative_lost, |
| 262 &report_block.extended_high_sequence_number, &report_block.jitter); | 263 &report_block.extended_high_sequence_number, &report_block.jitter); |
| 263 cast_environment_->Logging()->InsertGenericEvent(now, kJitterMs, | 264 cast_environment_->Logging()->InsertGenericEvent(now, kJitterMs, |
| 264 report_block.jitter); | 265 report_block.jitter); |
| 265 cast_environment_->Logging()->InsertGenericEvent( | 266 cast_environment_->Logging()->InsertGenericEvent( |
| 266 now, kPacketLoss, report_block.fraction_lost); | 267 now, kPacketLoss, report_block.fraction_lost); |
| 267 } | 268 } |
| 268 | 269 |
| 269 report_block.last_sr = last_report_received_; | 270 report_block.last_sr = last_report_received_; |
| 270 if (!time_last_report_received_.is_null()) { | 271 if (!time_last_report_received_.is_null()) { |
| 271 uint32 delay_seconds = 0; | 272 uint32 delay_seconds = 0; |
| 272 uint32 delay_fraction = 0; | 273 uint32 delay_fraction = 0; |
| 273 base::TimeDelta delta = now - time_last_report_received_; | 274 base::TimeDelta delta = now - time_last_report_received_; |
| 274 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, | 275 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, |
| 275 &delay_fraction); | 276 &delay_fraction); |
| 276 report_block.delay_since_last_sr = | 277 report_block.delay_since_last_sr = |
| 277 ConvertToNtpDiff(delay_seconds, delay_fraction); | 278 ConvertToNtpDiff(delay_seconds, delay_fraction); |
| 278 } else { | 279 } else { |
| 279 report_block.delay_since_last_sr = 0; | 280 report_block.delay_since_last_sr = 0; |
| 280 } | 281 } |
| 281 UpdateNextTimeToSendRtcp(); | 282 UpdateNextTimeToSendRtcp(); |
| 282 } | 283 } |
| 283 rtcp_sender_->SendRtcpFromRtpReceiver( | 284 rtcp_sender_->SendRtcpFromRtpReceiver( |
| 284 packet_type_flags, &report_block, &rrtr, cast_message, event_subscriber); | 285 packet_type_flags, &report_block, &rrtr, cast_message, event_subscriber, |
| 286 target_delay_ms_); |
| 285 } | 287 } |
| 286 | 288 |
| 287 void Rtcp::SendRtcpFromRtpSender( | 289 void Rtcp::SendRtcpFromRtpSender( |
| 288 const transport::RtcpSenderLogMessage& sender_log_message) { | 290 const transport::RtcpSenderLogMessage& sender_log_message) { |
| 289 DCHECK(transport_sender_); | 291 DCHECK(transport_sender_); |
| 290 uint32 packet_type_flags = RtcpSender::kRtcpSr; | 292 uint32 packet_type_flags = transport::kRtcpSr; |
| 291 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 293 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
| 292 | 294 |
| 293 if (sender_log_message.size()) { | 295 if (sender_log_message.size()) { |
| 294 packet_type_flags |= RtcpSender::kRtcpSenderLog; | 296 packet_type_flags |= transport::kRtcpSenderLog; |
| 295 } | 297 } |
| 296 | 298 |
| 297 transport::RtcpSenderInfo sender_info; | 299 transport::RtcpSenderInfo sender_info; |
| 298 if (rtp_sender_statistics_) { | 300 if (rtp_sender_statistics_) { |
| 299 rtp_sender_statistics_->GetStatistics(now, &sender_info); | 301 rtp_sender_statistics_->GetStatistics(now, &sender_info); |
| 300 } else { | 302 } else { |
| 301 memset(&sender_info, 0, sizeof(sender_info)); | 303 memset(&sender_info, 0, sizeof(sender_info)); |
| 302 } | 304 } |
| 303 SaveLastSentNtpTime(now, sender_info.ntp_seconds, sender_info.ntp_fraction); | 305 SaveLastSentNtpTime(now, sender_info.ntp_seconds, sender_info.ntp_fraction); |
| 304 | 306 |
| 305 transport::RtcpDlrrReportBlock dlrr; | 307 transport::RtcpDlrrReportBlock dlrr; |
| 306 if (!time_last_report_received_.is_null()) { | 308 if (!time_last_report_received_.is_null()) { |
| 307 packet_type_flags |= RtcpSender::kRtcpDlrr; | 309 packet_type_flags |= transport::kRtcpDlrr; |
| 308 dlrr.last_rr = last_report_received_; | 310 dlrr.last_rr = last_report_received_; |
| 309 uint32 delay_seconds = 0; | 311 uint32 delay_seconds = 0; |
| 310 uint32 delay_fraction = 0; | 312 uint32 delay_fraction = 0; |
| 311 base::TimeDelta delta = now - time_last_report_received_; | 313 base::TimeDelta delta = now - time_last_report_received_; |
| 312 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, | 314 ConvertTimeToFractions(delta.InMicroseconds(), &delay_seconds, |
| 313 &delay_fraction); | 315 &delay_fraction); |
| 314 | 316 |
| 315 dlrr.delay_since_last_rr = ConvertToNtpDiff(delay_seconds, delay_fraction); | 317 dlrr.delay_since_last_rr = ConvertToNtpDiff(delay_seconds, delay_fraction); |
| 316 } | 318 } |
| 317 | 319 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 *rtp_timestamp_in_ticks = ConvertNtpToTimeTicks(last_received_ntp_seconds_, | 387 *rtp_timestamp_in_ticks = ConvertNtpToTimeTicks(last_received_ntp_seconds_, |
| 386 last_received_ntp_fraction_) + | 388 last_received_ntp_fraction_) + |
| 387 base::TimeDelta::FromMilliseconds(rtp_time_diff_ms); | 389 base::TimeDelta::FromMilliseconds(rtp_time_diff_ms); |
| 388 return true; | 390 return true; |
| 389 } | 391 } |
| 390 | 392 |
| 391 void Rtcp::SetCastReceiverEventHistorySize(size_t size) { | 393 void Rtcp::SetCastReceiverEventHistorySize(size_t size) { |
| 392 rtcp_receiver_->SetCastReceiverEventHistorySize(size); | 394 rtcp_receiver_->SetCastReceiverEventHistorySize(size); |
| 393 } | 395 } |
| 394 | 396 |
| 397 void Rtcp::SetTargetDelay(base::TimeDelta target_delay) { |
| 398 target_delay_ms_ = static_cast<uint16>(target_delay.InMilliseconds()); |
| 399 DCHECK(target_delay_ms_ < kMaxDelay); |
| 400 } |
| 401 |
| 395 void Rtcp::OnReceivedDelaySinceLastReport(uint32 receivers_ssrc, | 402 void Rtcp::OnReceivedDelaySinceLastReport(uint32 receivers_ssrc, |
| 396 uint32 last_report, | 403 uint32 last_report, |
| 397 uint32 delay_since_last_report) { | 404 uint32 delay_since_last_report) { |
| 398 RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report); | 405 RtcpSendTimeMap::iterator it = last_reports_sent_map_.find(last_report); |
| 399 if (it == last_reports_sent_map_.end()) { | 406 if (it == last_reports_sent_map_.end()) { |
| 400 return; // Feedback on another report. | 407 return; // Feedback on another report. |
| 401 } | 408 } |
| 402 | 409 |
| 403 base::TimeDelta sender_delay = | 410 base::TimeDelta sender_delay = |
| 404 cast_environment_->Clock()->NowTicks() - it->second; | 411 cast_environment_->Clock()->NowTicks() - it->second; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 int random = base::RandInt(0, 999); | 496 int random = base::RandInt(0, 999); |
| 490 base::TimeDelta time_to_next = | 497 base::TimeDelta time_to_next = |
| 491 (rtcp_interval_ / 2) + (rtcp_interval_ * random / 1000); | 498 (rtcp_interval_ / 2) + (rtcp_interval_ * random / 1000); |
| 492 | 499 |
| 493 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 500 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
| 494 next_time_to_send_rtcp_ = now + time_to_next; | 501 next_time_to_send_rtcp_ = now + time_to_next; |
| 495 } | 502 } |
| 496 | 503 |
| 497 } // namespace cast | 504 } // namespace cast |
| 498 } // namespace media | 505 } // namespace media |
| OLD | NEW |