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 |