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 |