| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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/net/rtcp/rtcp_builder.h" | 5 #include "media/cast/net/rtcp/rtcp_builder.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 DCHECK(event_type_4_bits); | 37 DCHECK(event_type_4_bits); |
| 38 DCHECK(~(event_type_4_bits & 0xfff0)); | 38 DCHECK(~(event_type_4_bits & 0xfff0)); |
| 39 return (event_type_4_bits << 12) | time_delta_12_bits; | 39 return (event_type_4_bits << 12) | time_delta_12_bits; |
| 40 } | 40 } |
| 41 | 41 |
| 42 bool EventTimestampLessThan(const RtcpReceiverEventLogMessage& lhs, | 42 bool EventTimestampLessThan(const RtcpReceiverEventLogMessage& lhs, |
| 43 const RtcpReceiverEventLogMessage& rhs) { | 43 const RtcpReceiverEventLogMessage& rhs) { |
| 44 return lhs.event_timestamp < rhs.event_timestamp; | 44 return lhs.event_timestamp < rhs.event_timestamp; |
| 45 } | 45 } |
| 46 | 46 |
| 47 void AddReceiverLogEntries( | |
| 48 const RtcpReceiverLogMessage& redundancy_receiver_log_message, | |
| 49 RtcpReceiverLogMessage* receiver_log_message, | |
| 50 size_t* remaining_space, | |
| 51 size_t* number_of_frames, | |
| 52 size_t* total_number_of_messages_to_send) { | |
| 53 RtcpReceiverLogMessage::const_iterator it = | |
| 54 redundancy_receiver_log_message.begin(); | |
| 55 while (it != redundancy_receiver_log_message.end() && | |
| 56 *remaining_space >= | |
| 57 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) { | |
| 58 receiver_log_message->push_front(*it); | |
| 59 size_t num_event_logs = (*remaining_space - kRtcpReceiverFrameLogSize) / | |
| 60 kRtcpReceiverEventLogSize; | |
| 61 RtcpReceiverEventLogMessages& event_log_messages = | |
| 62 receiver_log_message->front().event_log_messages_; | |
| 63 if (num_event_logs < event_log_messages.size()) | |
| 64 event_log_messages.resize(num_event_logs); | |
| 65 | |
| 66 *remaining_space -= kRtcpReceiverFrameLogSize + | |
| 67 event_log_messages.size() * kRtcpReceiverEventLogSize; | |
| 68 ++number_of_frames; | |
| 69 *total_number_of_messages_to_send += event_log_messages.size(); | |
| 70 ++it; | |
| 71 } | |
| 72 } | |
| 73 | |
| 74 // A class to build a string representing the NACK list in Cast message. | 47 // A class to build a string representing the NACK list in Cast message. |
| 75 // | 48 // |
| 76 // The string will look like "23:3-6 25:1,5-6", meaning packets 3 to 6 in frame | 49 // The string will look like "23:3-6 25:1,5-6", meaning packets 3 to 6 in frame |
| 77 // 23 are being NACK'ed (i.e. they are missing from the receiver's point of | 50 // 23 are being NACK'ed (i.e. they are missing from the receiver's point of |
| 78 // view) and packets 1, 5 and 6 are missing in frame 25. A frame that is | 51 // view) and packets 1, 5 and 6 are missing in frame 25. A frame that is |
| 79 // completely missing will show as "26:65535". | 52 // completely missing will show as "26:65535". |
| 80 class NackStringBuilder { | 53 class NackStringBuilder { |
| 81 public: | 54 public: |
| 82 NackStringBuilder() | 55 NackStringBuilder() |
| 83 : frame_count_(0), | 56 : frame_count_(0), |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 writer_ = base::BigEndianWriter(NULL, 0); | 163 writer_ = base::BigEndianWriter(NULL, 0); |
| 191 PacketRef ret = packet_; | 164 PacketRef ret = packet_; |
| 192 packet_ = NULL; | 165 packet_ = NULL; |
| 193 return ret; | 166 return ret; |
| 194 } | 167 } |
| 195 | 168 |
| 196 PacketRef RtcpBuilder::BuildRtcpFromReceiver( | 169 PacketRef RtcpBuilder::BuildRtcpFromReceiver( |
| 197 const RtcpReportBlock* report_block, | 170 const RtcpReportBlock* report_block, |
| 198 const RtcpReceiverReferenceTimeReport* rrtr, | 171 const RtcpReceiverReferenceTimeReport* rrtr, |
| 199 const RtcpCastMessage* cast_message, | 172 const RtcpCastMessage* cast_message, |
| 200 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, | 173 const ReceiverRtcpEventSubscriber::RtcpEvents* rtcp_events, |
| 201 base::TimeDelta target_delay) { | 174 base::TimeDelta target_delay) { |
| 202 Start(); | 175 Start(); |
| 203 | 176 |
| 204 if (report_block) | 177 if (report_block) |
| 205 AddRR(report_block); | 178 AddRR(report_block); |
| 206 if (rrtr) | 179 if (rrtr) |
| 207 AddRrtr(rrtr); | 180 AddRrtr(rrtr); |
| 208 if (cast_message) | 181 if (cast_message) |
| 209 AddCast(cast_message, target_delay); | 182 AddCast(cast_message, target_delay); |
| 210 if (rtcp_events) | 183 if (rtcp_events) |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 writer_.WriteU32(ssrc_); // Add our own SSRC. | 332 writer_.WriteU32(ssrc_); // Add our own SSRC. |
| 360 writer_.WriteU8(5); // Add block type. | 333 writer_.WriteU8(5); // Add block type. |
| 361 writer_.WriteU8(0); // Add reserved. | 334 writer_.WriteU8(0); // Add reserved. |
| 362 writer_.WriteU16(3); // Block length. | 335 writer_.WriteU16(3); // Block length. |
| 363 writer_.WriteU32(ssrc_); // Add the media (received RTP) SSRC. | 336 writer_.WriteU32(ssrc_); // Add the media (received RTP) SSRC. |
| 364 writer_.WriteU32(dlrr.last_rr); | 337 writer_.WriteU32(dlrr.last_rr); |
| 365 writer_.WriteU32(dlrr.delay_since_last_rr); | 338 writer_.WriteU32(dlrr.delay_since_last_rr); |
| 366 } | 339 } |
| 367 | 340 |
| 368 void RtcpBuilder::AddReceiverLog( | 341 void RtcpBuilder::AddReceiverLog( |
| 369 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events) { | 342 const ReceiverRtcpEventSubscriber::RtcpEvents& rtcp_events) { |
| 370 size_t total_number_of_messages_to_send = 0; | 343 size_t total_number_of_messages_to_send = 0; |
| 371 RtcpReceiverLogMessage receiver_log_message; | 344 RtcpReceiverLogMessage receiver_log_message; |
| 372 | 345 |
| 373 if (!GetRtcpReceiverLogMessage(rtcp_events, | 346 if (!GetRtcpReceiverLogMessage(rtcp_events, |
| 374 &receiver_log_message, | 347 &receiver_log_message, |
| 375 &total_number_of_messages_to_send)) { | 348 &total_number_of_messages_to_send)) { |
| 376 return; | 349 return; |
| 377 } | 350 } |
| 378 | 351 |
| 379 AddRtcpHeader(kPacketTypeApplicationDefined, kReceiverLogSubtype); | 352 AddRtcpHeader(kPacketTypeApplicationDefined, kReceiverLogSubtype); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 } | 407 } |
| 435 if (frame_log_messages.event_log_messages_.empty()) { | 408 if (frame_log_messages.event_log_messages_.empty()) { |
| 436 // We sent all messages on this frame; pop the frame header. | 409 // We sent all messages on this frame; pop the frame header. |
| 437 receiver_log_message.pop_front(); | 410 receiver_log_message.pop_front(); |
| 438 } | 411 } |
| 439 } | 412 } |
| 440 DCHECK_EQ(total_number_of_messages_to_send, 0u); | 413 DCHECK_EQ(total_number_of_messages_to_send, 0u); |
| 441 } | 414 } |
| 442 | 415 |
| 443 bool RtcpBuilder::GetRtcpReceiverLogMessage( | 416 bool RtcpBuilder::GetRtcpReceiverLogMessage( |
| 444 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events, | 417 const ReceiverRtcpEventSubscriber::RtcpEvents& rtcp_events, |
| 445 RtcpReceiverLogMessage* receiver_log_message, | 418 RtcpReceiverLogMessage* receiver_log_message, |
| 446 size_t* total_number_of_messages_to_send) { | 419 size_t* total_number_of_messages_to_send) { |
| 447 size_t number_of_frames = 0; | 420 size_t number_of_frames = 0; |
| 448 size_t remaining_space = | 421 size_t remaining_space = writer_.remaining(); |
| 449 std::min<size_t>(kMaxReceiverLogBytes, writer_.remaining()); | |
| 450 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize + | 422 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize + |
| 451 kRtcpReceiverEventLogSize) { | 423 kRtcpReceiverEventLogSize) { |
| 452 return false; | 424 return false; |
| 453 } | 425 } |
| 454 | 426 |
| 455 // We use this to do event timestamp sorting and truncating for events of | 427 // We use this to do event timestamp sorting and truncating for events of |
| 456 // a single frame. | 428 // a single frame. |
| 457 std::vector<RtcpReceiverEventLogMessage> sorted_log_messages; | 429 std::vector<RtcpReceiverEventLogMessage> sorted_log_messages; |
| 458 | 430 |
| 459 // Account for the RTCP header for an application-defined packet. | 431 // Account for the RTCP header for an application-defined packet. |
| 460 remaining_space -= kRtcpCastLogHeaderSize; | 432 remaining_space -= kRtcpCastLogHeaderSize; |
| 461 | 433 |
| 462 ReceiverRtcpEventSubscriber::RtcpEventMultiMap::const_reverse_iterator rit = | 434 ReceiverRtcpEventSubscriber::RtcpEvents::const_reverse_iterator rit = |
| 463 rtcp_events.rbegin(); | 435 rtcp_events.rbegin(); |
| 464 | 436 |
| 465 while (rit != rtcp_events.rend() && | 437 while (rit != rtcp_events.rend() && |
| 466 remaining_space >= | 438 remaining_space >= |
| 467 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) { | 439 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) { |
| 468 const RtpTimestamp rtp_timestamp = rit->first; | 440 const RtpTimestamp rtp_timestamp = rit->first; |
| 469 RtcpReceiverFrameLogMessage frame_log(rtp_timestamp); | 441 RtcpReceiverFrameLogMessage frame_log(rtp_timestamp); |
| 470 remaining_space -= kRtcpReceiverFrameLogSize; | 442 remaining_space -= kRtcpReceiverFrameLogSize; |
| 471 ++number_of_frames; | 443 ++number_of_frames; |
| 472 | 444 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 503 frame_log.event_log_messages_.push_front(*sorted_rit); | 475 frame_log.event_log_messages_.push_front(*sorted_rit); |
| 504 ++events_in_frame; | 476 ++events_in_frame; |
| 505 ++*total_number_of_messages_to_send; | 477 ++*total_number_of_messages_to_send; |
| 506 remaining_space -= kRtcpReceiverEventLogSize; | 478 remaining_space -= kRtcpReceiverEventLogSize; |
| 507 ++sorted_rit; | 479 ++sorted_rit; |
| 508 } | 480 } |
| 509 | 481 |
| 510 receiver_log_message->push_front(frame_log); | 482 receiver_log_message->push_front(frame_log); |
| 511 } | 483 } |
| 512 | 484 |
| 513 rtcp_events_history_.push_front(*receiver_log_message); | |
| 514 | |
| 515 // We don't try to match RTP timestamps of redundancy frame logs with those | |
| 516 // from the newest set (which would save the space of an extra RTP timestamp | |
| 517 // over the wire). Unless the redundancy frame logs are very recent, it's | |
| 518 // unlikely there will be a match anyway. | |
| 519 if (rtcp_events_history_.size() > kFirstRedundancyOffset) { | |
| 520 // Add first redundnacy messages, if enough space remaining | |
| 521 AddReceiverLogEntries(rtcp_events_history_[kFirstRedundancyOffset], | |
| 522 receiver_log_message, | |
| 523 &remaining_space, | |
| 524 &number_of_frames, | |
| 525 total_number_of_messages_to_send); | |
| 526 } | |
| 527 | |
| 528 if (rtcp_events_history_.size() > kSecondRedundancyOffset) { | |
| 529 // Add second redundancy messages, if enough space remaining | |
| 530 AddReceiverLogEntries(rtcp_events_history_[kSecondRedundancyOffset], | |
| 531 receiver_log_message, | |
| 532 &remaining_space, | |
| 533 &number_of_frames, | |
| 534 total_number_of_messages_to_send); | |
| 535 } | |
| 536 | |
| 537 if (rtcp_events_history_.size() > kReceiveLogMessageHistorySize) { | |
| 538 rtcp_events_history_.pop_back(); | |
| 539 } | |
| 540 | |
| 541 DCHECK_LE(rtcp_events_history_.size(), kReceiveLogMessageHistorySize); | |
| 542 | |
| 543 VLOG(3) << "number of frames: " << number_of_frames; | 485 VLOG(3) << "number of frames: " << number_of_frames; |
| 544 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; | 486 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; |
| 545 return number_of_frames > 0; | 487 return number_of_frames > 0; |
| 546 } | 488 } |
| 547 | 489 |
| 548 } // namespace cast | 490 } // namespace cast |
| 549 } // namespace media | 491 } // namespace media |
| OLD | NEW |