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

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

Issue 387933005: Cast: Refactor RTCP handling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix test Created 6 years, 5 months 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/net/rtcp/rtcp_sender.h ('k') | media/cast/net/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 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_sender.h" 5 #include "media/cast/net/rtcp/rtcp_sender.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>
11 11
12 #include "base/big_endian.h" 12 #include "base/big_endian.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "media/cast/cast_environment.h"
15 #include "media/cast/net/cast_transport_defines.h" 14 #include "media/cast/net/cast_transport_defines.h"
16 #include "media/cast/net/pacing/paced_sender.h" 15 #include "media/cast/net/pacing/paced_sender.h"
17 #include "media/cast/net/rtcp/rtcp_defines.h" 16 #include "media/cast/net/rtcp/rtcp_defines.h"
18 #include "media/cast/net/rtcp/rtcp_utility.h" 17 #include "media/cast/net/rtcp/rtcp_utility.h"
19 18
20 namespace media { 19 namespace media {
21 namespace cast { 20 namespace cast {
22 namespace { 21 namespace {
23 22
24 // Max delta is 4095 milliseconds because we need to be able to encode it in 23 // Max delta is 4095 milliseconds because we need to be able to encode it in
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 private: 138 private:
140 std::ostringstream stream_; 139 std::ostringstream stream_;
141 int frame_count_; 140 int frame_count_;
142 int packet_count_; 141 int packet_count_;
143 int last_frame_id_; 142 int last_frame_id_;
144 int last_packet_id_; 143 int last_packet_id_;
145 bool contiguous_sequence_; 144 bool contiguous_sequence_;
146 }; 145 };
147 } // namespace 146 } // namespace
148 147
149 // TODO(mikhal): This is only used by the receiver. Consider renaming. 148 RtcpSender::RtcpSender(PacedPacketSender* outgoing_transport,
150 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment,
151 PacedPacketSender* outgoing_transport,
152 uint32 sending_ssrc, 149 uint32 sending_ssrc,
153 const std::string& c_name) 150 const std::string& c_name)
154 : ssrc_(sending_ssrc), 151 : ssrc_(sending_ssrc),
155 c_name_(c_name), 152 c_name_(c_name),
156 transport_(outgoing_transport), 153 transport_(outgoing_transport) {
157 cast_environment_(cast_environment) {
158 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; 154 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config";
159 } 155 }
160 156
161 RtcpSender::~RtcpSender() {} 157 RtcpSender::~RtcpSender() {}
162 158
163 void RtcpSender::SendRtcpFromRtpReceiver( 159 void RtcpSender::SendRtcpFromRtpReceiver(
164 uint32 packet_type_flags, 160 uint32 packet_type_flags,
165 const RtcpReportBlock* report_block, 161 const RtcpReportBlock* report_block,
166 const RtcpReceiverReferenceTimeReport* rrtr, 162 const RtcpReceiverReferenceTimeReport* rrtr,
167 const RtcpCastMessage* cast_message, 163 const RtcpCastMessage* cast_message,
168 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, 164 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events,
169 base::TimeDelta target_delay) { 165 base::TimeDelta target_delay) {
170 if (packet_type_flags & kRtcpSr || 166 if (packet_type_flags & kRtcpSr ||
171 packet_type_flags & kRtcpDlrr || 167 packet_type_flags & kRtcpDlrr ||
172 packet_type_flags & kRtcpSenderLog) { 168 packet_type_flags & kRtcpSenderLog) {
173 NOTREACHED() << "Invalid argument"; 169 NOTREACHED() << "Invalid argument";
174 } 170 }
175 if (packet_type_flags & kRtcpPli || 171 if (packet_type_flags & kRtcpPli ||
176 packet_type_flags & kRtcpRpsi || 172 packet_type_flags & kRtcpRpsi ||
177 packet_type_flags & kRtcpRemb || 173 packet_type_flags & kRtcpRemb ||
178 packet_type_flags & kRtcpNack) { 174 packet_type_flags & kRtcpNack) {
179 // Implement these for webrtc interop. 175 // Implement these for webrtc interop.
180 NOTIMPLEMENTED(); 176 NOTIMPLEMENTED();
181 } 177 }
182 PacketRef packet(new base::RefCountedData<Packet>); 178 PacketRef packet(new base::RefCountedData<Packet>);
183 packet->data.reserve(kMaxIpPacketSize); 179 packet->data.reserve(kMaxIpPacketSize);
184
185 if (packet_type_flags & kRtcpRr) { 180 if (packet_type_flags & kRtcpRr) {
186 BuildRR(report_block, &packet->data); 181 BuildRR(report_block, &packet->data);
187 if (!c_name_.empty()) { 182 if (!c_name_.empty()) {
188 BuildSdec(&packet->data); 183 BuildSdec(&packet->data);
189 } 184 }
190 } 185 }
191 if (packet_type_flags & kRtcpBye) { 186 if (packet_type_flags & kRtcpBye) {
192 BuildBye(&packet->data); 187 BuildBye(&packet->data);
193 } 188 }
194 if (packet_type_flags & kRtcpRrtr) { 189 if (packet_type_flags & kRtcpRrtr) {
195 DCHECK(rrtr) << "Invalid argument"; 190 DCHECK(rrtr) << "Invalid argument";
196 BuildRrtr(rrtr, &packet->data); 191 BuildRrtr(rrtr, &packet->data);
197 } 192 }
198 if (packet_type_flags & kRtcpCast) { 193 if (packet_type_flags & kRtcpCast) {
199 DCHECK(cast_message) << "Invalid argument"; 194 DCHECK(cast_message) << "Invalid argument";
200 BuildCast(cast_message, target_delay, &packet->data); 195 BuildCast(cast_message, target_delay, &packet->data);
201 } 196 }
202 if (packet_type_flags & kRtcpReceiverLog) { 197 if (packet_type_flags & kRtcpReceiverLog) {
203 DCHECK(rtcp_events) << "Invalid argument"; 198 DCHECK(rtcp_events) << "Invalid argument";
204 BuildReceiverLog(*rtcp_events, &packet->data); 199 BuildReceiverLog(*rtcp_events, &packet->data);
205 } 200 }
206 201
207 if (packet->data.empty()) 202 if (packet->data.empty()) {
203 NOTREACHED() << "Empty packet.";
208 return; // Sanity don't send empty packets. 204 return; // Sanity don't send empty packets.
205 }
209 206
210 transport_->SendRtcpPacket(ssrc_, packet); 207 transport_->SendRtcpPacket(ssrc_, packet);
211 } 208 }
209
210 void RtcpSender::SendRtcpFromRtpSender(
211 uint32 packet_type_flags,
212 const RtcpSenderInfo& sender_info,
213 const RtcpDlrrReportBlock& dlrr) {
214 if (packet_type_flags & kRtcpRr ||
215 packet_type_flags & kRtcpPli ||
216 packet_type_flags & kRtcpRrtr ||
217 packet_type_flags & kRtcpCast ||
218 packet_type_flags & kRtcpReceiverLog ||
219 packet_type_flags & kRtcpRpsi ||
220 packet_type_flags & kRtcpRemb ||
221 packet_type_flags & kRtcpNack) {
222 NOTREACHED() << "Invalid argument";
223 }
224 PacketRef packet(new base::RefCountedData<Packet>);
225 packet->data.reserve(kMaxIpPacketSize);
226 if (packet_type_flags & kRtcpSr) {
227 BuildSR(sender_info, &packet->data);
228 BuildSdec(&packet->data);
229 }
230 if (packet_type_flags & kRtcpBye) {
231 BuildBye(&packet->data);
232 }
233 if (packet_type_flags & kRtcpDlrr) {
234 BuildDlrrRb(dlrr, &packet->data);
235 }
236 if (packet->data.empty()) {
237 NOTREACHED() << "Empty packet.";
238 return; // Sanity - don't send empty packets.
239 }
240
241 transport_->SendRtcpPacket(ssrc_, packet);
242 }
212 243
213 void RtcpSender::BuildRR(const RtcpReportBlock* report_block, 244 void RtcpSender::BuildRR(const RtcpReportBlock* report_block,
214 Packet* packet) const { 245 Packet* packet) const {
215 size_t start_size = packet->size(); 246 size_t start_size = packet->size();
216 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; 247 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space";
217 if (start_size + 32 > kMaxIpPacketSize) 248 if (start_size + 32 > kMaxIpPacketSize)
218 return; 249 return;
219 250
220 uint16 number_of_rows = (report_block) ? 7 : 1; 251 uint16 number_of_rows = (report_block) ? 7 : 1;
221 packet->resize(start_size + 8); 252 packet->resize(start_size + 8);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 358
328 /* 359 /*
329 0 1 2 3 360 0 1 2 3
330 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 361 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
331 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 362 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
332 | PB |0| Payload Type| Native Rpsi bit string | 363 | PB |0| Payload Type| Native Rpsi bit string |
333 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 364 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
334 | defined per codec ... | Padding (0) | 365 | defined per codec ... | Padding (0) |
335 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 366 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
336 */ 367 */
337 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { 368 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi,
369 Packet* packet) const {
338 size_t start_size = packet->size(); 370 size_t start_size = packet->size();
339 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; 371 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space";
340 if (start_size + 24 > kMaxIpPacketSize) 372 if (start_size + 24 > kMaxIpPacketSize)
341 return; 373 return;
342 374
343 packet->resize(start_size + 24); 375 packet->resize(start_size + 24);
344 376
345 base::BigEndianWriter big_endian_writer( 377 base::BigEndianWriter big_endian_writer(
346 reinterpret_cast<char*>(&((*packet)[start_size])), 24); 378 reinterpret_cast<char*>(&((*packet)[start_size])), 24);
347 uint8 FMT = 3; // Reference Picture Selection Indication. 379 uint8 FMT = 3; // Reference Picture Selection Indication.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 } 413 }
382 // Add last byte of picture ID. 414 // Add last byte of picture ID.
383 big_endian_writer.WriteU8(static_cast<uint8>(rpsi->picture_id & 0x7f)); 415 big_endian_writer.WriteU8(static_cast<uint8>(rpsi->picture_id & 0x7f));
384 416
385 // Add padding. 417 // Add padding.
386 for (int j = 0; j < padding_bytes; ++j) { 418 for (int j = 0; j < padding_bytes; ++j) {
387 big_endian_writer.WriteU8(0); 419 big_endian_writer.WriteU8(0);
388 } 420 }
389 } 421 }
390 422
391 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, Packet* packet) const { 423 void RtcpSender::BuildRemb(const RtcpRembMessage* remb,
424 Packet* packet) const {
392 size_t start_size = packet->size(); 425 size_t start_size = packet->size();
393 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); 426 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size();
394 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize) 427 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize)
395 << "Not enough buffer space"; 428 << "Not enough buffer space";
396 if (start_size + remb_size > kMaxIpPacketSize) 429 if (start_size + remb_size > kMaxIpPacketSize)
397 return; 430 return;
398 431
399 packet->resize(start_size + remb_size); 432 packet->resize(start_size + remb_size);
400 433
401 base::BigEndianWriter big_endian_writer( 434 base::BigEndianWriter big_endian_writer(
(...skipping 20 matching lines...) Expand all
422 (bitrate_exponent << 2) + ((bitrate_mantissa >> 16) & 0x03))); 455 (bitrate_exponent << 2) + ((bitrate_mantissa >> 16) & 0x03)));
423 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa >> 8)); 456 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa >> 8));
424 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa)); 457 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa));
425 458
426 std::list<uint32>::const_iterator it = remb->remb_ssrcs.begin(); 459 std::list<uint32>::const_iterator it = remb->remb_ssrcs.begin();
427 for (; it != remb->remb_ssrcs.end(); ++it) { 460 for (; it != remb->remb_ssrcs.end(); ++it) {
428 big_endian_writer.WriteU32(*it); 461 big_endian_writer.WriteU32(*it);
429 } 462 }
430 } 463 }
431 464
432 void RtcpSender::BuildNack(const RtcpNackMessage* nack, Packet* packet) const { 465 void RtcpSender::BuildNack(const RtcpNackMessage* nack,
466 Packet* packet) const {
433 size_t start_size = packet->size(); 467 size_t start_size = packet->size();
434 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space"; 468 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space";
435 if (start_size + 16 > kMaxIpPacketSize) 469 if (start_size + 16 > kMaxIpPacketSize)
436 return; 470 return;
437 471
438 packet->resize(start_size + 16); 472 packet->resize(start_size + 16);
439 473
440 base::BigEndianWriter big_endian_writer( 474 base::BigEndianWriter big_endian_writer(
441 reinterpret_cast<char*>(&((*packet)[start_size])), 16); 475 reinterpret_cast<char*>(&((*packet)[start_size])), 16);
442 476
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 574
541 base::BigEndianWriter big_endian_writer( 575 base::BigEndianWriter big_endian_writer(
542 reinterpret_cast<char*>(&((*packet)[start_size])), 20); 576 reinterpret_cast<char*>(&((*packet)[start_size])), 20);
543 uint8 FMT = 15; // Application layer feedback. 577 uint8 FMT = 15; // Application layer feedback.
544 big_endian_writer.WriteU8(0x80 + FMT); 578 big_endian_writer.WriteU8(0x80 + FMT);
545 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); 579 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
546 big_endian_writer.WriteU8(0); 580 big_endian_writer.WriteU8(0);
547 size_t cast_size_pos = start_size + 3; // Save length position. 581 size_t cast_size_pos = start_size + 3; // Save length position.
548 big_endian_writer.WriteU8(4); 582 big_endian_writer.WriteU8(4);
549 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. 583 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
550 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. 584 big_endian_writer.WriteU32(cast->media_ssrc); // Remote SSRC.
551 big_endian_writer.WriteU32(kCast); 585 big_endian_writer.WriteU32(kCast);
552 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); 586 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id));
553 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. 587 size_t cast_loss_field_pos = start_size + 17; // Save loss field position.
554 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. 588 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields.
555 DCHECK_LE(target_delay.InMilliseconds(), 589 DCHECK_LE(target_delay.InMilliseconds(),
556 std::numeric_limits<uint16_t>::max()); 590 std::numeric_limits<uint16_t>::max());
557 big_endian_writer.WriteU16(target_delay.InMilliseconds()); 591 big_endian_writer.WriteU16(target_delay.InMilliseconds());
558 592
559 size_t number_of_loss_fields = 0; 593 size_t number_of_loss_fields = 0;
560 size_t max_number_of_loss_fields = std::min<size_t>( 594 size_t max_number_of_loss_fields = std::min<size_t>(
561 kRtcpMaxCastLossFields, (kMaxIpPacketSize - packet->size()) / 4); 595 kRtcpMaxCastLossFields, (kMaxIpPacketSize - packet->size()) / 4);
562 596
563 MissingFramesAndPacketsMap::const_iterator frame_it = 597 MissingFramesAndPacketsMap::const_iterator frame_it =
564 cast->missing_frames_and_packets_.begin(); 598 cast->missing_frames_and_packets.begin();
565 599
566 NackStringBuilder nack_string_builder; 600 NackStringBuilder nack_string_builder;
567 for (; frame_it != cast->missing_frames_and_packets_.end() && 601 for (; frame_it != cast->missing_frames_and_packets.end() &&
568 number_of_loss_fields < max_number_of_loss_fields; 602 number_of_loss_fields < max_number_of_loss_fields;
569 ++frame_it) { 603 ++frame_it) {
570 nack_string_builder.PushFrame(frame_it->first); 604 nack_string_builder.PushFrame(frame_it->first);
571 // Iterate through all frames with missing packets. 605 // Iterate through all frames with missing packets.
572 if (frame_it->second.empty()) { 606 if (frame_it->second.empty()) {
573 // Special case all packets in a frame is missing. 607 // Special case all packets in a frame is missing.
574 start_size = packet->size(); 608 start_size = packet->size();
575 packet->resize(start_size + 4); 609 packet->resize(start_size + 4);
576 base::BigEndianWriter big_endian_nack_writer( 610 base::BigEndianWriter big_endian_nack_writer(
577 reinterpret_cast<char*>(&((*packet)[start_size])), 4); 611 reinterpret_cast<char*>(&((*packet)[start_size])), 4);
(...skipping 28 matching lines...) Expand all
606 } else { 640 } else {
607 break; 641 break;
608 } 642 }
609 } 643 }
610 big_endian_nack_writer.WriteU8(bitmask); 644 big_endian_nack_writer.WriteU8(bitmask);
611 ++number_of_loss_fields; 645 ++number_of_loss_fields;
612 } 646 }
613 } 647 }
614 } 648 }
615 VLOG_IF(1, !nack_string_builder.Empty()) 649 VLOG_IF(1, !nack_string_builder.Empty())
616 << "SSRC: " << cast->media_ssrc_ 650 << "SSRC: " << cast->media_ssrc
617 << ", ACK: " << cast->ack_frame_id_ 651 << ", ACK: " << cast->ack_frame_id
618 << ", NACK: " << nack_string_builder.GetString(); 652 << ", NACK: " << nack_string_builder.GetString();
619 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields); 653 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields);
620 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields); 654 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields);
621 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields); 655 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields);
622 } 656 }
623 657
658 void RtcpSender::BuildSR(const RtcpSenderInfo& sender_info,
659 Packet* packet) const {
660 // Sender report.
661 size_t start_size = packet->size();
662 if (start_size + 52 > kMaxIpPacketSize) {
663 DLOG(FATAL) << "Not enough buffer space";
664 return;
665 }
666
667 uint16 number_of_rows = 6;
668 packet->resize(start_size + 28);
669
670 base::BigEndianWriter big_endian_writer(
671 reinterpret_cast<char*>(&((*packet)[start_size])), 28);
672 big_endian_writer.WriteU8(0x80);
673 big_endian_writer.WriteU8(kPacketTypeSenderReport);
674 big_endian_writer.WriteU16(number_of_rows);
675 big_endian_writer.WriteU32(ssrc_);
676 big_endian_writer.WriteU32(sender_info.ntp_seconds);
677 big_endian_writer.WriteU32(sender_info.ntp_fraction);
678 big_endian_writer.WriteU32(sender_info.rtp_timestamp);
679 big_endian_writer.WriteU32(sender_info.send_packet_count);
680 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count));
681 return;
682 }
683
684 /*
685 0 1 2 3
686 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
687 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
688 |V=2|P|reserved | PT=XR=207 | length |
689 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
690 | SSRC |
691 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
692 | BT=5 | reserved | block length |
693 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
694 | SSRC1 (SSRC of first receiver) | sub-
695 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
696 | last RR (LRR) | 1
697 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
698 | delay since last RR (DLRR) |
699 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
700 */
701 void RtcpSender::BuildDlrrRb(const RtcpDlrrReportBlock& dlrr,
702 Packet* packet) const {
703 size_t start_size = packet->size();
704 if (start_size + 24 > kMaxIpPacketSize) {
705 DLOG(FATAL) << "Not enough buffer space";
706 return;
707 }
708
709 packet->resize(start_size + 24);
710
711 base::BigEndianWriter big_endian_writer(
712 reinterpret_cast<char*>(&((*packet)[start_size])), 24);
713 big_endian_writer.WriteU8(0x80);
714 big_endian_writer.WriteU8(kPacketTypeXr);
715 big_endian_writer.WriteU16(5); // Length.
716 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
717 big_endian_writer.WriteU8(5); // Add block type.
718 big_endian_writer.WriteU8(0); // Add reserved.
719 big_endian_writer.WriteU16(3); // Block length.
720 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC.
721 big_endian_writer.WriteU32(dlrr.last_rr);
722 big_endian_writer.WriteU32(dlrr.delay_since_last_rr);
723 return;
724 }
725
624 void RtcpSender::BuildReceiverLog( 726 void RtcpSender::BuildReceiverLog(
625 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events, 727 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events,
626 Packet* packet) { 728 Packet* packet) {
627 const size_t packet_start_size = packet->size(); 729 const size_t packet_start_size = packet->size();
628 size_t number_of_frames = 0; 730 size_t number_of_frames = 0;
629 size_t total_number_of_messages_to_send = 0; 731 size_t total_number_of_messages_to_send = 0;
630 size_t rtcp_log_size = 0; 732 size_t rtcp_log_size = 0;
631 RtcpReceiverLogMessage receiver_log_message; 733 RtcpReceiverLogMessage receiver_log_message;
632 734
633 if (!BuildRtcpReceiverLogMessage(rtcp_events, 735 if (!BuildRtcpReceiverLogMessage(rtcp_events,
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 << "Not enough buffer space."; 920 << "Not enough buffer space.";
819 921
820 VLOG(3) << "number of frames: " << *number_of_frames; 922 VLOG(3) << "number of frames: " << *number_of_frames;
821 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; 923 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send;
822 VLOG(3) << "rtcp log size: " << *rtcp_log_size; 924 VLOG(3) << "rtcp log size: " << *rtcp_log_size;
823 return *number_of_frames > 0; 925 return *number_of_frames > 0;
824 } 926 }
825 927
826 } // namespace cast 928 } // namespace cast
827 } // namespace media 929 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/net/rtcp/rtcp_sender.h ('k') | media/cast/net/rtcp/rtcp_sender_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698