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

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

Issue 427733002: Cast: Remove unused RTCP messages (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged Created 6 years, 4 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>
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 std::ostringstream stream_; 139 std::ostringstream stream_;
140 int frame_count_; 140 int frame_count_;
141 int packet_count_; 141 int packet_count_;
142 int last_frame_id_; 142 int last_frame_id_;
143 int last_packet_id_; 143 int last_packet_id_;
144 bool contiguous_sequence_; 144 bool contiguous_sequence_;
145 }; 145 };
146 } // namespace 146 } // namespace
147 147
148 RtcpSender::RtcpSender(PacedPacketSender* outgoing_transport, 148 RtcpSender::RtcpSender(PacedPacketSender* outgoing_transport,
149 uint32 sending_ssrc, 149 uint32 sending_ssrc)
150 const std::string& c_name)
151 : ssrc_(sending_ssrc), 150 : ssrc_(sending_ssrc),
152 c_name_(c_name),
153 transport_(outgoing_transport) { 151 transport_(outgoing_transport) {
154 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config";
155 } 152 }
156 153
157 RtcpSender::~RtcpSender() {} 154 RtcpSender::~RtcpSender() {}
158 155
159 void RtcpSender::SendRtcpFromRtpReceiver( 156 void RtcpSender::SendRtcpFromRtpReceiver(
160 uint32 packet_type_flags, 157 uint32 packet_type_flags,
161 const RtcpReportBlock* report_block, 158 const RtcpReportBlock* report_block,
162 const RtcpReceiverReferenceTimeReport* rrtr, 159 const RtcpReceiverReferenceTimeReport* rrtr,
163 const RtcpCastMessage* cast_message, 160 const RtcpCastMessage* cast_message,
164 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, 161 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events,
165 base::TimeDelta target_delay) { 162 base::TimeDelta target_delay) {
166 if (packet_type_flags & kRtcpSr || 163 if (packet_type_flags & kRtcpDlrr) {
167 packet_type_flags & kRtcpDlrr ||
168 packet_type_flags & kRtcpSenderLog) {
169 NOTREACHED() << "Invalid argument"; 164 NOTREACHED() << "Invalid argument";
170 } 165 }
171 if (packet_type_flags & kRtcpPli ||
172 packet_type_flags & kRtcpRpsi ||
173 packet_type_flags & kRtcpRemb ||
174 packet_type_flags & kRtcpNack) {
175 // Implement these for webrtc interop.
176 NOTIMPLEMENTED();
177 }
178 PacketRef packet(new base::RefCountedData<Packet>); 166 PacketRef packet(new base::RefCountedData<Packet>);
179 packet->data.reserve(kMaxIpPacketSize); 167 packet->data.reserve(kMaxIpPacketSize);
180 if (packet_type_flags & kRtcpRr) { 168 if (packet_type_flags & kRtcpRr) {
181 BuildRR(report_block, &packet->data); 169 BuildRR(report_block, &packet->data);
182 if (!c_name_.empty()) {
183 BuildSdec(&packet->data);
184 }
185 }
186 if (packet_type_flags & kRtcpBye) {
187 BuildBye(&packet->data);
188 } 170 }
189 if (packet_type_flags & kRtcpRrtr) { 171 if (packet_type_flags & kRtcpRrtr) {
190 DCHECK(rrtr) << "Invalid argument"; 172 DCHECK(rrtr) << "Invalid argument";
191 BuildRrtr(rrtr, &packet->data); 173 BuildRrtr(rrtr, &packet->data);
192 } 174 }
193 if (packet_type_flags & kRtcpCast) { 175 if (packet_type_flags & kRtcpCast) {
194 DCHECK(cast_message) << "Invalid argument"; 176 DCHECK(cast_message) << "Invalid argument";
195 BuildCast(cast_message, target_delay, &packet->data); 177 BuildCast(cast_message, target_delay, &packet->data);
196 } 178 }
197 if (packet_type_flags & kRtcpReceiverLog) { 179 if (packet_type_flags & kRtcpReceiverLog) {
198 DCHECK(rtcp_events) << "Invalid argument"; 180 DCHECK(rtcp_events) << "Invalid argument";
199 BuildReceiverLog(*rtcp_events, &packet->data); 181 BuildReceiverLog(*rtcp_events, &packet->data);
200 } 182 }
201 183
202 if (packet->data.empty()) { 184 if (packet->data.empty()) {
203 NOTREACHED() << "Empty packet."; 185 NOTREACHED() << "Empty packet.";
204 return; // Sanity don't send empty packets. 186 return; // Sanity don't send empty packets.
205 } 187 }
206 188
207 transport_->SendRtcpPacket(ssrc_, packet); 189 transport_->SendRtcpPacket(ssrc_, packet);
208 } 190 }
209 191
210 void RtcpSender::SendRtcpFromRtpSender( 192 void RtcpSender::SendRtcpFromRtpSender(
211 uint32 packet_type_flags, 193 uint32 packet_type_flags,
212 const RtcpSenderInfo& sender_info, 194 const RtcpSenderInfo& sender_info,
213 const RtcpDlrrReportBlock& dlrr) { 195 const RtcpDlrrReportBlock& dlrr) {
214 if (packet_type_flags & kRtcpRr || 196 if (packet_type_flags & kRtcpRr ||
215 packet_type_flags & kRtcpPli ||
216 packet_type_flags & kRtcpRrtr || 197 packet_type_flags & kRtcpRrtr ||
217 packet_type_flags & kRtcpCast || 198 packet_type_flags & kRtcpCast ||
218 packet_type_flags & kRtcpReceiverLog || 199 packet_type_flags & kRtcpReceiverLog) {
219 packet_type_flags & kRtcpRpsi ||
220 packet_type_flags & kRtcpRemb ||
221 packet_type_flags & kRtcpNack) {
222 NOTREACHED() << "Invalid argument"; 200 NOTREACHED() << "Invalid argument";
223 } 201 }
224 PacketRef packet(new base::RefCountedData<Packet>); 202 PacketRef packet(new base::RefCountedData<Packet>);
225 packet->data.reserve(kMaxIpPacketSize); 203 packet->data.reserve(kMaxIpPacketSize);
226 if (packet_type_flags & kRtcpSr) { 204 if (packet_type_flags & kRtcpSr) {
227 BuildSR(sender_info, &packet->data); 205 BuildSR(sender_info, &packet->data);
228 BuildSdec(&packet->data);
229 }
230 if (packet_type_flags & kRtcpBye) {
231 BuildBye(&packet->data);
232 } 206 }
233 if (packet_type_flags & kRtcpDlrr) { 207 if (packet_type_flags & kRtcpDlrr) {
234 BuildDlrrRb(dlrr, &packet->data); 208 BuildDlrrRb(dlrr, &packet->data);
235 } 209 }
236 if (packet->data.empty()) { 210 if (packet->data.empty()) {
237 NOTREACHED() << "Empty packet."; 211 NOTREACHED() << "Empty packet.";
238 return; // Sanity - don't send empty packets. 212 return; // Sanity - don't send empty packets.
239 } 213 }
240 214
241 transport_->SendRtcpPacket(ssrc_, packet); 215 transport_->SendRtcpPacket(ssrc_, packet);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 260
287 // Last SR timestamp; our NTP time when we received the last report. 261 // Last SR timestamp; our NTP time when we received the last report.
288 // This is the value that we read from the send report packet not when we 262 // This is the value that we read from the send report packet not when we
289 // received it. 263 // received it.
290 big_endian_writer.WriteU32(report_block.last_sr); 264 big_endian_writer.WriteU32(report_block.last_sr);
291 265
292 // Delay since last received report, time since we received the report. 266 // Delay since last received report, time since we received the report.
293 big_endian_writer.WriteU32(report_block.delay_since_last_sr); 267 big_endian_writer.WriteU32(report_block.delay_since_last_sr);
294 } 268 }
295 269
296 void RtcpSender::BuildSdec(Packet* packet) const {
297 size_t start_size = packet->size();
298 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize)
299 << "Not enough buffer space";
300 if (start_size + 12 > kMaxIpPacketSize)
301 return;
302
303 // SDES Source Description.
304 packet->resize(start_size + 10);
305
306 base::BigEndianWriter big_endian_writer(
307 reinterpret_cast<char*>(&((*packet)[start_size])), 10);
308 // We always need to add one SDES CNAME.
309 big_endian_writer.WriteU8(0x80 + 1);
310 big_endian_writer.WriteU8(kPacketTypeSdes);
311
312 // Handle SDES length later on.
313 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3;
314 big_endian_writer.WriteU16(0);
315 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
316 big_endian_writer.WriteU8(1); // CNAME = 1
317 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length()));
318
319 size_t sdes_length = 10 + c_name_.length();
320 packet->insert(
321 packet->end(), c_name_.c_str(), c_name_.c_str() + c_name_.length());
322
323 size_t padding = 0;
324
325 // We must have a zero field even if we have an even multiple of 4 bytes.
326 if ((packet->size() % 4) == 0) {
327 padding++;
328 packet->push_back(0);
329 }
330 while ((packet->size() % 4) != 0) {
331 padding++;
332 packet->push_back(0);
333 }
334 sdes_length += padding;
335
336 // In 32-bit words minus one and we don't count the header.
337 uint8 buffer_length = static_cast<uint8>((sdes_length / 4) - 1);
338 (*packet)[sdes_length_position] = buffer_length;
339 }
340
341 void RtcpSender::BuildPli(uint32 remote_ssrc, Packet* packet) const {
342 size_t start_size = packet->size();
343 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space";
344 if (start_size + 12 > kMaxIpPacketSize)
345 return;
346
347 packet->resize(start_size + 12);
348
349 base::BigEndianWriter big_endian_writer(
350 reinterpret_cast<char*>(&((*packet)[start_size])), 12);
351 uint8 FMT = 1; // Picture loss indicator.
352 big_endian_writer.WriteU8(0x80 + FMT);
353 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
354 big_endian_writer.WriteU16(2); // Used fixed length of 2.
355 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
356 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC.
357 }
358
359 /*
360 0 1 2 3
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
362 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363 | PB |0| Payload Type| Native Rpsi bit string |
364 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365 | defined per codec ... | Padding (0) |
366 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367 */
368 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi,
369 Packet* packet) const {
370 size_t start_size = packet->size();
371 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space";
372 if (start_size + 24 > kMaxIpPacketSize)
373 return;
374
375 packet->resize(start_size + 24);
376
377 base::BigEndianWriter big_endian_writer(
378 reinterpret_cast<char*>(&((*packet)[start_size])), 24);
379 uint8 FMT = 3; // Reference Picture Selection Indication.
380 big_endian_writer.WriteU8(0x80 + FMT);
381 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
382
383 // Calculate length.
384 uint32 bits_required = 7;
385 uint8 bytes_required = 1;
386 while ((rpsi->picture_id >> bits_required) > 0) {
387 bits_required += 7;
388 bytes_required++;
389 }
390 uint8 size = 3;
391 if (bytes_required > 6) {
392 size = 5;
393 } else if (bytes_required > 2) {
394 size = 4;
395 }
396 big_endian_writer.WriteU8(0);
397 big_endian_writer.WriteU8(size);
398 big_endian_writer.WriteU32(ssrc_);
399 big_endian_writer.WriteU32(rpsi->remote_ssrc);
400
401 uint8 padding_bytes = 4 - ((2 + bytes_required) % 4);
402 if (padding_bytes == 4) {
403 padding_bytes = 0;
404 }
405 // Add padding length in bits, padding can be 0, 8, 16 or 24.
406 big_endian_writer.WriteU8(padding_bytes * 8);
407 big_endian_writer.WriteU8(rpsi->payload_type);
408
409 // Add picture ID.
410 for (int i = bytes_required - 1; i > 0; i--) {
411 big_endian_writer.WriteU8(0x80 |
412 static_cast<uint8>(rpsi->picture_id >> (i * 7)));
413 }
414 // Add last byte of picture ID.
415 big_endian_writer.WriteU8(static_cast<uint8>(rpsi->picture_id & 0x7f));
416
417 // Add padding.
418 for (int j = 0; j < padding_bytes; ++j) {
419 big_endian_writer.WriteU8(0);
420 }
421 }
422
423 void RtcpSender::BuildRemb(const RtcpRembMessage* remb,
424 Packet* packet) const {
425 size_t start_size = packet->size();
426 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size();
427 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize)
428 << "Not enough buffer space";
429 if (start_size + remb_size > kMaxIpPacketSize)
430 return;
431
432 packet->resize(start_size + remb_size);
433
434 base::BigEndianWriter big_endian_writer(
435 reinterpret_cast<char*>(&((*packet)[start_size])), remb_size);
436
437 // Add application layer feedback.
438 uint8 FMT = 15;
439 big_endian_writer.WriteU8(0x80 + FMT);
440 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
441 big_endian_writer.WriteU8(0);
442 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4));
443 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
444 big_endian_writer.WriteU32(0); // Remote SSRC must be 0.
445 big_endian_writer.WriteU32(kRemb);
446 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size()));
447
448 // 6 bit exponent and a 18 bit mantissa.
449 uint8 bitrate_exponent;
450 uint32 bitrate_mantissa;
451 BitrateToRembExponentBitrate(
452 remb->remb_bitrate, &bitrate_exponent, &bitrate_mantissa);
453
454 big_endian_writer.WriteU8(static_cast<uint8>(
455 (bitrate_exponent << 2) + ((bitrate_mantissa >> 16) & 0x03)));
456 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa >> 8));
457 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa));
458
459 std::list<uint32>::const_iterator it = remb->remb_ssrcs.begin();
460 for (; it != remb->remb_ssrcs.end(); ++it) {
461 big_endian_writer.WriteU32(*it);
462 }
463 }
464
465 void RtcpSender::BuildNack(const RtcpNackMessage* nack,
466 Packet* packet) const {
467 size_t start_size = packet->size();
468 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space";
469 if (start_size + 16 > kMaxIpPacketSize)
470 return;
471
472 packet->resize(start_size + 16);
473
474 base::BigEndianWriter big_endian_writer(
475 reinterpret_cast<char*>(&((*packet)[start_size])), 16);
476
477 uint8 FMT = 1;
478 big_endian_writer.WriteU8(0x80 + FMT);
479 big_endian_writer.WriteU8(kPacketTypeGenericRtpFeedback);
480 big_endian_writer.WriteU8(0);
481 size_t nack_size_pos = start_size + 3;
482 big_endian_writer.WriteU8(3);
483 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
484 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC.
485
486 // Build NACK bitmasks and write them to the Rtcp message.
487 // The nack list should be sorted and not contain duplicates.
488 size_t number_of_nack_fields = 0;
489 size_t max_number_of_nack_fields = std::min<size_t>(
490 kRtcpMaxNackFields, (kMaxIpPacketSize - packet->size()) / 4);
491
492 std::list<uint16>::const_iterator it = nack->nack_list.begin();
493 while (it != nack->nack_list.end() &&
494 number_of_nack_fields < max_number_of_nack_fields) {
495 uint16 nack_sequence_number = *it;
496 uint16 bitmask = 0;
497 ++it;
498 while (it != nack->nack_list.end()) {
499 int shift = static_cast<uint16>(*it - nack_sequence_number) - 1;
500 if (shift >= 0 && shift <= 15) {
501 bitmask |= (1 << shift);
502 ++it;
503 } else {
504 break;
505 }
506 }
507 // Write the sequence number and the bitmask to the packet.
508 start_size = packet->size();
509 DCHECK_LT(start_size + 4, kMaxIpPacketSize) << "Not enough buffer space";
510 if (start_size + 4 > kMaxIpPacketSize)
511 return;
512
513 packet->resize(start_size + 4);
514 base::BigEndianWriter big_endian_nack_writer(
515 reinterpret_cast<char*>(&((*packet)[start_size])), 4);
516 big_endian_nack_writer.WriteU16(nack_sequence_number);
517 big_endian_nack_writer.WriteU16(bitmask);
518 number_of_nack_fields++;
519 }
520 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields);
521 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields);
522 }
523
524 void RtcpSender::BuildBye(Packet* packet) const {
525 size_t start_size = packet->size();
526 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space";
527 if (start_size + 8 > kMaxIpPacketSize)
528 return;
529
530 packet->resize(start_size + 8);
531
532 base::BigEndianWriter big_endian_writer(
533 reinterpret_cast<char*>(&((*packet)[start_size])), 8);
534 big_endian_writer.WriteU8(0x80 + 1);
535 big_endian_writer.WriteU8(kPacketTypeBye);
536 big_endian_writer.WriteU16(1); // Length.
537 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
538 }
539
540 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, 270 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr,
541 Packet* packet) const { 271 Packet* packet) const {
542 size_t start_size = packet->size(); 272 size_t start_size = packet->size();
543 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; 273 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space";
544 if (start_size + 20 > kMaxIpPacketSize) 274 if (start_size + 20 > kMaxIpPacketSize)
545 return; 275 return;
546 276
547 packet->resize(start_size + 20); 277 packet->resize(start_size + 20);
548 278
549 base::BigEndianWriter big_endian_writer( 279 base::BigEndianWriter big_endian_writer(
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 << "Not enough buffer space."; 650 << "Not enough buffer space.";
921 651
922 VLOG(3) << "number of frames: " << *number_of_frames; 652 VLOG(3) << "number of frames: " << *number_of_frames;
923 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; 653 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send;
924 VLOG(3) << "rtcp log size: " << *rtcp_log_size; 654 VLOG(3) << "rtcp log size: " << *rtcp_log_size;
925 return *number_of_frames > 0; 655 return *number_of_frames > 0;
926 } 656 }
927 657
928 } // namespace cast 658 } // namespace cast
929 } // namespace media 659 } // 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