Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: media/cast/rtcp/rtcp_sender.cc

Issue 102413014: Cast:Splitting rtcp sender (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/cast/rtcp/rtcp_sender.h ('k') | media/cast/rtcp/rtcp_sender_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_sender.h" 5 #include "media/cast/rtcp/rtcp_sender.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "media/cast/cast_environment.h" 11 #include "media/cast/cast_environment.h"
12 #include "media/cast/net/cast_net_defines.h"
12 #include "media/cast/net/pacing/paced_sender.h" 13 #include "media/cast/net/pacing/paced_sender.h"
13 #include "media/cast/rtcp/rtcp_utility.h" 14 #include "media/cast/rtcp/rtcp_utility.h"
14 #include "net/base/big_endian.h" 15 #include "net/base/big_endian.h"
15 16
16 static const size_t kRtcpCastLogHeaderSize = 12; 17 static const size_t kRtcpCastLogHeaderSize = 12;
17 static const size_t kRtcpSenderFrameLogSize = 4; 18 static const size_t kRtcpSenderFrameLogSize = 4;
18 static const size_t kRtcpReceiverFrameLogSize = 8; 19 static const size_t kRtcpReceiverFrameLogSize = 8;
19 static const size_t kRtcpReceiverEventLogSize = 4; 20 static const size_t kRtcpReceiverEventLogSize = 4;
20 21
21 namespace { 22 namespace {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 const std::string& c_name) 130 const std::string& c_name)
130 : ssrc_(sending_ssrc), 131 : ssrc_(sending_ssrc),
131 c_name_(c_name), 132 c_name_(c_name),
132 transport_(outgoing_transport), 133 transport_(outgoing_transport),
133 cast_environment_(cast_environment) { 134 cast_environment_(cast_environment) {
134 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; 135 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config";
135 } 136 }
136 137
137 RtcpSender::~RtcpSender() {} 138 RtcpSender::~RtcpSender() {}
138 139
139 void RtcpSender::SendRtcpFromRtpSender(uint32 packet_type_flags,
140 const RtcpSenderInfo* sender_info,
141 const RtcpDlrrReportBlock* dlrr,
142 RtcpSenderLogMessage* sender_log) {
143 if (packet_type_flags & kRtcpRr ||
144 packet_type_flags & kRtcpPli ||
145 packet_type_flags & kRtcpRrtr ||
146 packet_type_flags & kRtcpCast ||
147 packet_type_flags & kRtcpReceiverLog ||
148 packet_type_flags & kRtcpRpsi ||
149 packet_type_flags & kRtcpRemb ||
150 packet_type_flags & kRtcpNack) {
151 NOTREACHED() << "Invalid argument";
152 }
153
154 std::vector<uint8> packet;
155 packet.reserve(kIpPacketSize);
156 if (packet_type_flags & kRtcpSr) {
157 DCHECK(sender_info) << "Invalid argument";
158 BuildSR(*sender_info, NULL, &packet);
159 BuildSdec(&packet);
160 }
161 if (packet_type_flags & kRtcpBye) {
162 BuildBye(&packet);
163 }
164 if (packet_type_flags & kRtcpDlrr) {
165 DCHECK(dlrr) << "Invalid argument";
166 BuildDlrrRb(dlrr, &packet);
167 }
168 if (packet_type_flags & kRtcpSenderLog) {
169 DCHECK(sender_log) << "Invalid argument";
170 BuildSenderLog(sender_log, &packet);
171 }
172 if (packet.empty())
173 return; // Sanity don't send empty packets.
174
175 transport_->SendRtcpPacket(packet);
176 }
177
178 void RtcpSender::SendRtcpFromRtpReceiver( 140 void RtcpSender::SendRtcpFromRtpReceiver(
179 uint32 packet_type_flags, 141 uint32 packet_type_flags,
180 const RtcpReportBlock* report_block, 142 const RtcpReportBlock* report_block,
181 const RtcpReceiverReferenceTimeReport* rrtr, 143 const RtcpReceiverReferenceTimeReport* rrtr,
182 const RtcpCastMessage* cast_message, 144 const RtcpCastMessage* cast_message,
183 RtcpReceiverLogMessage* receiver_log) { 145 RtcpReceiverLogMessage* receiver_log) {
184 if (packet_type_flags & kRtcpSr || 146 if (packet_type_flags & kRtcpSr ||
185 packet_type_flags & kRtcpDlrr || 147 packet_type_flags & kRtcpDlrr ||
186 packet_type_flags & kRtcpSenderLog) { 148 packet_type_flags & kRtcpSenderLog) {
187 NOTREACHED() << "Invalid argument"; 149 NOTREACHED() << "Invalid argument";
(...skipping 27 matching lines...) Expand all
215 } 177 }
216 if (packet_type_flags & kRtcpReceiverLog) { 178 if (packet_type_flags & kRtcpReceiverLog) {
217 DCHECK(receiver_log) << "Invalid argument"; 179 DCHECK(receiver_log) << "Invalid argument";
218 BuildReceiverLog(receiver_log, &packet); 180 BuildReceiverLog(receiver_log, &packet);
219 } 181 }
220 if (packet.empty()) return; // Sanity don't send empty packets. 182 if (packet.empty()) return; // Sanity don't send empty packets.
221 183
222 transport_->SendRtcpPacket(packet); 184 transport_->SendRtcpPacket(packet);
223 } 185 }
224 186
225 void RtcpSender::BuildSR(const RtcpSenderInfo& sender_info,
226 const RtcpReportBlock* report_block,
227 std::vector<uint8>* packet) const {
228 // Sender report.
229 size_t start_size = packet->size();
230 DCHECK_LT(start_size + 52, kIpPacketSize) << "Not enough buffer space";
231 if (start_size + 52 > kIpPacketSize) return;
232
233 uint16 number_of_rows = (report_block) ? 12 : 6;
234 packet->resize(start_size + 28);
235
236 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 28);
237 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0));
238 big_endian_writer.WriteU8(kPacketTypeSenderReport);
239 big_endian_writer.WriteU16(number_of_rows);
240 big_endian_writer.WriteU32(ssrc_);
241 big_endian_writer.WriteU32(sender_info.ntp_seconds);
242 big_endian_writer.WriteU32(sender_info.ntp_fraction);
243 big_endian_writer.WriteU32(sender_info.rtp_timestamp);
244 big_endian_writer.WriteU32(sender_info.send_packet_count);
245 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count));
246
247 if (report_block) {
248 AddReportBlocks(*report_block, packet); // Adds 24 bytes.
249 }
250 }
251
252 void RtcpSender::BuildRR(const RtcpReportBlock* report_block, 187 void RtcpSender::BuildRR(const RtcpReportBlock* report_block,
253 std::vector<uint8>* packet) const { 188 std::vector<uint8>* packet) const {
254 size_t start_size = packet->size(); 189 size_t start_size = packet->size();
255 DCHECK_LT(start_size + 32, kIpPacketSize) << "Not enough buffer space"; 190 DCHECK_LT(start_size + 32, kIpPacketSize) << "Not enough buffer space";
256 if (start_size + 32 > kIpPacketSize) return; 191 if (start_size + 32 > kIpPacketSize) return;
257 192
258 uint16 number_of_rows = (report_block) ? 7 : 1; 193 uint16 number_of_rows = (report_block) ? 7 : 1;
259 packet->resize(start_size + 8); 194 packet->resize(start_size + 8);
260 195
261 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); 196 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8);
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 460
526 packet->resize(start_size + 8); 461 packet->resize(start_size + 8);
527 462
528 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); 463 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8);
529 big_endian_writer.WriteU8(0x80 + 1); 464 big_endian_writer.WriteU8(0x80 + 1);
530 big_endian_writer.WriteU8(kPacketTypeBye); 465 big_endian_writer.WriteU8(kPacketTypeBye);
531 big_endian_writer.WriteU16(1); // Length. 466 big_endian_writer.WriteU16(1); // Length.
532 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 467 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
533 } 468 }
534 469
535 /*
536 0 1 2 3
537 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
538 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
539 |V=2|P|reserved | PT=XR=207 | length |
540 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
541 | SSRC |
542 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
543 | BT=5 | reserved | block length |
544 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
545 | SSRC_1 (SSRC of first receiver) | sub-
546 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
547 | last RR (LRR) | 1
548 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
549 | delay since last RR (DLRR) |
550 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
551 */
552 void RtcpSender::BuildDlrrRb(const RtcpDlrrReportBlock* dlrr,
553 std::vector<uint8>* packet) const {
554 size_t start_size = packet->size();
555 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space";
556 if (start_size + 24 > kIpPacketSize) return;
557
558 packet->resize(start_size + 24);
559
560 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24);
561 big_endian_writer.WriteU8(0x80);
562 big_endian_writer.WriteU8(kPacketTypeXr);
563 big_endian_writer.WriteU16(5); // Length.
564 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
565 big_endian_writer.WriteU8(5); // Add block type.
566 big_endian_writer.WriteU8(0); // Add reserved.
567 big_endian_writer.WriteU16(3); // Block length.
568 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC.
569 big_endian_writer.WriteU32(dlrr->last_rr);
570 big_endian_writer.WriteU32(dlrr->delay_since_last_rr);
571 }
572
573 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, 470 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr,
574 std::vector<uint8>* packet) const { 471 std::vector<uint8>* packet) const {
575 size_t start_size = packet->size(); 472 size_t start_size = packet->size();
576 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; 473 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space";
577 if (start_size + 20 > kIpPacketSize) return; 474 if (start_size + 20 > kIpPacketSize) return;
578 475
579 packet->resize(start_size + 20); 476 packet->resize(start_size + 20);
580 477
581 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); 478 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20);
582 479
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 big_endian_nack_writer.WriteU8(bitmask); 561 big_endian_nack_writer.WriteU8(bitmask);
665 ++number_of_loss_fields; 562 ++number_of_loss_fields;
666 } 563 }
667 } 564 }
668 } 565 }
669 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields); 566 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields);
670 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields); 567 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields);
671 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields); 568 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields);
672 } 569 }
673 570
674 void RtcpSender::BuildSenderLog(RtcpSenderLogMessage* sender_log_message,
675 std::vector<uint8>* packet) const {
676 DCHECK(sender_log_message);
677 DCHECK(packet);
678 size_t start_size = packet->size();
679 size_t remaining_space = kIpPacketSize - start_size;
680 DCHECK_GE(remaining_space, kRtcpCastLogHeaderSize + kRtcpSenderFrameLogSize)
681 << "Not enough buffer space";
682 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpSenderFrameLogSize)
683 return;
684
685 size_t space_for_x_messages =
686 (remaining_space - kRtcpCastLogHeaderSize) / kRtcpSenderFrameLogSize;
687 size_t number_of_messages = std::min(space_for_x_messages,
688 sender_log_message->size());
689
690 size_t log_size = kRtcpCastLogHeaderSize +
691 number_of_messages * kRtcpSenderFrameLogSize;
692 packet->resize(start_size + log_size);
693
694 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), log_size);
695 big_endian_writer.WriteU8(0x80 + kSenderLogSubtype);
696 big_endian_writer.WriteU8(kPacketTypeApplicationDefined);
697 big_endian_writer.WriteU16(static_cast<uint16>(2 + number_of_messages));
698 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
699 big_endian_writer.WriteU32(kCast);
700
701 for (; number_of_messages > 0; --number_of_messages) {
702 DCHECK(!sender_log_message->empty());
703 const RtcpSenderFrameLogMessage& message = sender_log_message->front();
704 big_endian_writer.WriteU8(static_cast<uint8>(message.frame_status));
705 // We send the 24 east significant bits of the RTP timestamp.
706 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 16));
707 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp >> 8));
708 big_endian_writer.WriteU8(static_cast<uint8>(message.rtp_timestamp));
709 sender_log_message->pop_front();
710 }
711 }
712
713 void RtcpSender::BuildReceiverLog(RtcpReceiverLogMessage* receiver_log_message, 571 void RtcpSender::BuildReceiverLog(RtcpReceiverLogMessage* receiver_log_message,
714 std::vector<uint8>* packet) const { 572 std::vector<uint8>* packet) const {
715 DCHECK(receiver_log_message); 573 DCHECK(receiver_log_message);
716 const size_t packet_start_size = packet->size(); 574 const size_t packet_start_size = packet->size();
717 size_t number_of_frames = 0; 575 size_t number_of_frames = 0;
718 size_t total_number_of_messages_to_send = 0; 576 size_t total_number_of_messages_to_send = 0;
719 size_t rtcp_log_size = 0; 577 size_t rtcp_log_size = 0;
720 578
721 if (!ScanRtcpReceiverLogMessage(*receiver_log_message, 579 if (!ScanRtcpReceiverLogMessage(*receiver_log_message,
722 packet_start_size, 580 packet_start_size,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 if (frame_log_messages.event_log_messages_.empty()) { 649 if (frame_log_messages.event_log_messages_.empty()) {
792 // We sent all messages on this frame; pop the frame header. 650 // We sent all messages on this frame; pop the frame header.
793 receiver_log_message->pop_front(); 651 receiver_log_message->pop_front();
794 } 652 }
795 } 653 }
796 DCHECK_EQ(total_number_of_messages_to_send, 0); 654 DCHECK_EQ(total_number_of_messages_to_send, 0);
797 } 655 }
798 656
799 } // namespace cast 657 } // namespace cast
800 } // namespace media 658 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/rtcp/rtcp_sender.h ('k') | media/cast/rtcp/rtcp_sender_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698