OLD | NEW |
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/big_endian.h" |
10 #include "base/logging.h" | 11 #include "base/logging.h" |
11 #include "media/cast/cast_environment.h" | 12 #include "media/cast/cast_environment.h" |
12 #include "media/cast/rtcp/receiver_rtcp_event_subscriber.h" | 13 #include "media/cast/rtcp/receiver_rtcp_event_subscriber.h" |
13 #include "media/cast/rtcp/rtcp_defines.h" | 14 #include "media/cast/rtcp/rtcp_defines.h" |
14 #include "media/cast/rtcp/rtcp_utility.h" | 15 #include "media/cast/rtcp/rtcp_utility.h" |
15 #include "media/cast/transport/cast_transport_defines.h" | 16 #include "media/cast/transport/cast_transport_defines.h" |
16 #include "media/cast/transport/pacing/paced_sender.h" | 17 #include "media/cast/transport/pacing/paced_sender.h" |
17 #include "net/base/big_endian.h" | |
18 | 18 |
19 namespace { | 19 namespace { |
20 | 20 |
21 using media::cast::kRtcpCastLogHeaderSize; | 21 using media::cast::kRtcpCastLogHeaderSize; |
22 using media::cast::kRtcpSenderFrameLogSize; | 22 using media::cast::kRtcpSenderFrameLogSize; |
23 using media::cast::kRtcpReceiverFrameLogSize; | 23 using media::cast::kRtcpReceiverFrameLogSize; |
24 using media::cast::kRtcpReceiverEventLogSize; | 24 using media::cast::kRtcpReceiverEventLogSize; |
25 | 25 |
26 // Converts a log event type to an integer value. | 26 // Converts a log event type to an integer value. |
27 int ConvertEventTypeToWireFormat(const media::cast::CastLoggingEvent& event) { | 27 int ConvertEventTypeToWireFormat(const media::cast::CastLoggingEvent& event) { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 | 199 |
200 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, | 200 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, |
201 Packet* packet) const { | 201 Packet* packet) const { |
202 size_t start_size = packet->size(); | 202 size_t start_size = packet->size(); |
203 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; | 203 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; |
204 if (start_size + 32 > kMaxIpPacketSize) return; | 204 if (start_size + 32 > kMaxIpPacketSize) return; |
205 | 205 |
206 uint16 number_of_rows = (report_block) ? 7 : 1; | 206 uint16 number_of_rows = (report_block) ? 7 : 1; |
207 packet->resize(start_size + 8); | 207 packet->resize(start_size + 8); |
208 | 208 |
209 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); | 209 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); |
210 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); | 210 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); |
211 big_endian_writer.WriteU8(transport::kPacketTypeReceiverReport); | 211 big_endian_writer.WriteU8(transport::kPacketTypeReceiverReport); |
212 big_endian_writer.WriteU16(number_of_rows); | 212 big_endian_writer.WriteU16(number_of_rows); |
213 big_endian_writer.WriteU32(ssrc_); | 213 big_endian_writer.WriteU32(ssrc_); |
214 | 214 |
215 if (report_block) { | 215 if (report_block) { |
216 AddReportBlocks(*report_block, packet); // Adds 24 bytes. | 216 AddReportBlocks(*report_block, packet); // Adds 24 bytes. |
217 } | 217 } |
218 } | 218 } |
219 | 219 |
220 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, | 220 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, |
221 Packet* packet) const { | 221 Packet* packet) const { |
222 size_t start_size = packet->size(); | 222 size_t start_size = packet->size(); |
223 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 223 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
224 if (start_size + 24 > kMaxIpPacketSize) return; | 224 if (start_size + 24 > kMaxIpPacketSize) return; |
225 | 225 |
226 packet->resize(start_size + 24); | 226 packet->resize(start_size + 24); |
227 | 227 |
228 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); | 228 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); |
229 big_endian_writer.WriteU32(report_block.media_ssrc); | 229 big_endian_writer.WriteU32(report_block.media_ssrc); |
230 big_endian_writer.WriteU8(report_block.fraction_lost); | 230 big_endian_writer.WriteU8(report_block.fraction_lost); |
231 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); | 231 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); |
232 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); | 232 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); |
233 big_endian_writer.WriteU8(report_block.cumulative_lost); | 233 big_endian_writer.WriteU8(report_block.cumulative_lost); |
234 | 234 |
235 // Extended highest seq_no, contain the highest sequence number received. | 235 // Extended highest seq_no, contain the highest sequence number received. |
236 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); | 236 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); |
237 big_endian_writer.WriteU32(report_block.jitter); | 237 big_endian_writer.WriteU32(report_block.jitter); |
238 | 238 |
239 // Last SR timestamp; our NTP time when we received the last report. | 239 // Last SR timestamp; our NTP time when we received the last report. |
240 // This is the value that we read from the send report packet not when we | 240 // This is the value that we read from the send report packet not when we |
241 // received it. | 241 // received it. |
242 big_endian_writer.WriteU32(report_block.last_sr); | 242 big_endian_writer.WriteU32(report_block.last_sr); |
243 | 243 |
244 // Delay since last received report, time since we received the report. | 244 // Delay since last received report, time since we received the report. |
245 big_endian_writer.WriteU32(report_block.delay_since_last_sr); | 245 big_endian_writer.WriteU32(report_block.delay_since_last_sr); |
246 } | 246 } |
247 | 247 |
248 void RtcpSender::BuildSdec(Packet* packet) const { | 248 void RtcpSender::BuildSdec(Packet* packet) const { |
249 size_t start_size = packet->size(); | 249 size_t start_size = packet->size(); |
250 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize) | 250 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize) |
251 << "Not enough buffer space"; | 251 << "Not enough buffer space"; |
252 if (start_size + 12 > kMaxIpPacketSize) return; | 252 if (start_size + 12 > kMaxIpPacketSize) return; |
253 | 253 |
254 // SDES Source Description. | 254 // SDES Source Description. |
255 packet->resize(start_size + 10); | 255 packet->resize(start_size + 10); |
256 | 256 |
257 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10); | 257 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10); |
258 // We always need to add one SDES CNAME. | 258 // We always need to add one SDES CNAME. |
259 big_endian_writer.WriteU8(0x80 + 1); | 259 big_endian_writer.WriteU8(0x80 + 1); |
260 big_endian_writer.WriteU8(transport::kPacketTypeSdes); | 260 big_endian_writer.WriteU8(transport::kPacketTypeSdes); |
261 | 261 |
262 // Handle SDES length later on. | 262 // Handle SDES length later on. |
263 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; | 263 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; |
264 big_endian_writer.WriteU16(0); | 264 big_endian_writer.WriteU16(0); |
265 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 265 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
266 big_endian_writer.WriteU8(1); // CNAME = 1 | 266 big_endian_writer.WriteU8(1); // CNAME = 1 |
267 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); | 267 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); |
(...skipping 20 matching lines...) Expand all Loading... |
288 (*packet)[sdes_length_position] = buffer_length; | 288 (*packet)[sdes_length_position] = buffer_length; |
289 } | 289 } |
290 | 290 |
291 void RtcpSender::BuildPli(uint32 remote_ssrc, Packet* packet) const { | 291 void RtcpSender::BuildPli(uint32 remote_ssrc, Packet* packet) const { |
292 size_t start_size = packet->size(); | 292 size_t start_size = packet->size(); |
293 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; | 293 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; |
294 if (start_size + 12 > kMaxIpPacketSize) return; | 294 if (start_size + 12 > kMaxIpPacketSize) return; |
295 | 295 |
296 packet->resize(start_size + 12); | 296 packet->resize(start_size + 12); |
297 | 297 |
298 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12); | 298 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12); |
299 uint8 FMT = 1; // Picture loss indicator. | 299 uint8 FMT = 1; // Picture loss indicator. |
300 big_endian_writer.WriteU8(0x80 + FMT); | 300 big_endian_writer.WriteU8(0x80 + FMT); |
301 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 301 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
302 big_endian_writer.WriteU16(2); // Used fixed length of 2. | 302 big_endian_writer.WriteU16(2); // Used fixed length of 2. |
303 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 303 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
304 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. | 304 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. |
305 } | 305 } |
306 | 306 |
307 /* | 307 /* |
308 0 1 2 3 | 308 0 1 2 3 |
309 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 | 309 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 |
310 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 310 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
311 | PB |0| Payload Type| Native Rpsi bit string | | 311 | PB |0| Payload Type| Native Rpsi bit string | |
312 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 312 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
313 | defined per codec ... | Padding (0) | | 313 | defined per codec ... | Padding (0) | |
314 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 314 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
315 */ | 315 */ |
316 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { | 316 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { |
317 size_t start_size = packet->size(); | 317 size_t start_size = packet->size(); |
318 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 318 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
319 if (start_size + 24 > kMaxIpPacketSize) return; | 319 if (start_size + 24 > kMaxIpPacketSize) return; |
320 | 320 |
321 packet->resize(start_size + 24); | 321 packet->resize(start_size + 24); |
322 | 322 |
323 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); | 323 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); |
324 uint8 FMT = 3; // Reference Picture Selection Indication. | 324 uint8 FMT = 3; // Reference Picture Selection Indication. |
325 big_endian_writer.WriteU8(0x80 + FMT); | 325 big_endian_writer.WriteU8(0x80 + FMT); |
326 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 326 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
327 | 327 |
328 // Calculate length. | 328 // Calculate length. |
329 uint32 bits_required = 7; | 329 uint32 bits_required = 7; |
330 uint8 bytes_required = 1; | 330 uint8 bytes_required = 1; |
331 while ((rpsi->picture_id >> bits_required) > 0) { | 331 while ((rpsi->picture_id >> bits_required) > 0) { |
332 bits_required += 7; | 332 bits_required += 7; |
333 bytes_required++; | 333 bytes_required++; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 | 367 |
368 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, Packet* packet) const { | 368 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, Packet* packet) const { |
369 size_t start_size = packet->size(); | 369 size_t start_size = packet->size(); |
370 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); | 370 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); |
371 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize) | 371 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize) |
372 << "Not enough buffer space"; | 372 << "Not enough buffer space"; |
373 if (start_size + remb_size > kMaxIpPacketSize) return; | 373 if (start_size + remb_size > kMaxIpPacketSize) return; |
374 | 374 |
375 packet->resize(start_size + remb_size); | 375 packet->resize(start_size + remb_size); |
376 | 376 |
377 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size); | 377 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size); |
378 | 378 |
379 // Add application layer feedback. | 379 // Add application layer feedback. |
380 uint8 FMT = 15; | 380 uint8 FMT = 15; |
381 big_endian_writer.WriteU8(0x80 + FMT); | 381 big_endian_writer.WriteU8(0x80 + FMT); |
382 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 382 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
383 big_endian_writer.WriteU8(0); | 383 big_endian_writer.WriteU8(0); |
384 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); | 384 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); |
385 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 385 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
386 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. | 386 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. |
387 big_endian_writer.WriteU32(kRemb); | 387 big_endian_writer.WriteU32(kRemb); |
(...skipping 19 matching lines...) Expand all Loading... |
407 remb->remb_bitrate); | 407 remb->remb_bitrate); |
408 } | 408 } |
409 | 409 |
410 void RtcpSender::BuildNack(const RtcpNackMessage* nack, Packet* packet) const { | 410 void RtcpSender::BuildNack(const RtcpNackMessage* nack, Packet* packet) const { |
411 size_t start_size = packet->size(); | 411 size_t start_size = packet->size(); |
412 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space"; | 412 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space"; |
413 if (start_size + 16 > kMaxIpPacketSize) return; | 413 if (start_size + 16 > kMaxIpPacketSize) return; |
414 | 414 |
415 packet->resize(start_size + 16); | 415 packet->resize(start_size + 16); |
416 | 416 |
417 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16); | 417 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16); |
418 | 418 |
419 uint8 FMT = 1; | 419 uint8 FMT = 1; |
420 big_endian_writer.WriteU8(0x80 + FMT); | 420 big_endian_writer.WriteU8(0x80 + FMT); |
421 big_endian_writer.WriteU8(transport::kPacketTypeGenericRtpFeedback); | 421 big_endian_writer.WriteU8(transport::kPacketTypeGenericRtpFeedback); |
422 big_endian_writer.WriteU8(0); | 422 big_endian_writer.WriteU8(0); |
423 size_t nack_size_pos = start_size + 3; | 423 size_t nack_size_pos = start_size + 3; |
424 big_endian_writer.WriteU8(3); | 424 big_endian_writer.WriteU8(3); |
425 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 425 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
426 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. | 426 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. |
427 | 427 |
(...skipping 17 matching lines...) Expand all Loading... |
445 } else { | 445 } else { |
446 break; | 446 break; |
447 } | 447 } |
448 } | 448 } |
449 // Write the sequence number and the bitmask to the packet. | 449 // Write the sequence number and the bitmask to the packet. |
450 start_size = packet->size(); | 450 start_size = packet->size(); |
451 DCHECK_LT(start_size + 4, kMaxIpPacketSize) << "Not enough buffer space"; | 451 DCHECK_LT(start_size + 4, kMaxIpPacketSize) << "Not enough buffer space"; |
452 if (start_size + 4 > kMaxIpPacketSize) return; | 452 if (start_size + 4 > kMaxIpPacketSize) return; |
453 | 453 |
454 packet->resize(start_size + 4); | 454 packet->resize(start_size + 4); |
455 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); | 455 base::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); |
456 big_endian_nack_writer.WriteU16(nack_sequence_number); | 456 big_endian_nack_writer.WriteU16(nack_sequence_number); |
457 big_endian_nack_writer.WriteU16(bitmask); | 457 big_endian_nack_writer.WriteU16(bitmask); |
458 number_of_nack_fields++; | 458 number_of_nack_fields++; |
459 } | 459 } |
460 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); | 460 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); |
461 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); | 461 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); |
462 } | 462 } |
463 | 463 |
464 void RtcpSender::BuildBye(Packet* packet) const { | 464 void RtcpSender::BuildBye(Packet* packet) const { |
465 size_t start_size = packet->size(); | 465 size_t start_size = packet->size(); |
466 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; | 466 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; |
467 if (start_size + 8 > kMaxIpPacketSize) return; | 467 if (start_size + 8 > kMaxIpPacketSize) return; |
468 | 468 |
469 packet->resize(start_size + 8); | 469 packet->resize(start_size + 8); |
470 | 470 |
471 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); | 471 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); |
472 big_endian_writer.WriteU8(0x80 + 1); | 472 big_endian_writer.WriteU8(0x80 + 1); |
473 big_endian_writer.WriteU8(transport::kPacketTypeBye); | 473 big_endian_writer.WriteU8(transport::kPacketTypeBye); |
474 big_endian_writer.WriteU16(1); // Length. | 474 big_endian_writer.WriteU16(1); // Length. |
475 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 475 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
476 } | 476 } |
477 | 477 |
478 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, | 478 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, |
479 Packet* packet) const { | 479 Packet* packet) const { |
480 size_t start_size = packet->size(); | 480 size_t start_size = packet->size(); |
481 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 481 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
482 if (start_size + 20 > kMaxIpPacketSize) return; | 482 if (start_size + 20 > kMaxIpPacketSize) return; |
483 | 483 |
484 packet->resize(start_size + 20); | 484 packet->resize(start_size + 20); |
485 | 485 |
486 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); | 486 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); |
487 | 487 |
488 big_endian_writer.WriteU8(0x80); | 488 big_endian_writer.WriteU8(0x80); |
489 big_endian_writer.WriteU8(transport::kPacketTypeXr); | 489 big_endian_writer.WriteU8(transport::kPacketTypeXr); |
490 big_endian_writer.WriteU16(4); // Length. | 490 big_endian_writer.WriteU16(4); // Length. |
491 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 491 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
492 big_endian_writer.WriteU8(4); // Add block type. | 492 big_endian_writer.WriteU8(4); // Add block type. |
493 big_endian_writer.WriteU8(0); // Add reserved. | 493 big_endian_writer.WriteU8(0); // Add reserved. |
494 big_endian_writer.WriteU16(2); // Block length. | 494 big_endian_writer.WriteU16(2); // Block length. |
495 | 495 |
496 // Add the media (received RTP) SSRC. | 496 // Add the media (received RTP) SSRC. |
497 big_endian_writer.WriteU32(rrtr->ntp_seconds); | 497 big_endian_writer.WriteU32(rrtr->ntp_seconds); |
498 big_endian_writer.WriteU32(rrtr->ntp_fraction); | 498 big_endian_writer.WriteU32(rrtr->ntp_fraction); |
499 } | 499 } |
500 | 500 |
501 void RtcpSender::BuildCast(const RtcpCastMessage* cast, Packet* packet) const { | 501 void RtcpSender::BuildCast(const RtcpCastMessage* cast, Packet* packet) const { |
502 size_t start_size = packet->size(); | 502 size_t start_size = packet->size(); |
503 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 503 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
504 if (start_size + 20 > kMaxIpPacketSize) return; | 504 if (start_size + 20 > kMaxIpPacketSize) return; |
505 | 505 |
506 packet->resize(start_size + 20); | 506 packet->resize(start_size + 20); |
507 | 507 |
508 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); | 508 base::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); |
509 uint8 FMT = 15; // Application layer feedback. | 509 uint8 FMT = 15; // Application layer feedback. |
510 big_endian_writer.WriteU8(0x80 + FMT); | 510 big_endian_writer.WriteU8(0x80 + FMT); |
511 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 511 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
512 big_endian_writer.WriteU8(0); | 512 big_endian_writer.WriteU8(0); |
513 size_t cast_size_pos = start_size + 3; // Save length position. | 513 size_t cast_size_pos = start_size + 3; // Save length position. |
514 big_endian_writer.WriteU8(4); | 514 big_endian_writer.WriteU8(4); |
515 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 515 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
516 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. | 516 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. |
517 big_endian_writer.WriteU32(kCast); | 517 big_endian_writer.WriteU32(kCast); |
518 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); | 518 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); |
(...skipping 10 matching lines...) Expand all Loading... |
529 cast->missing_frames_and_packets_.begin(); | 529 cast->missing_frames_and_packets_.begin(); |
530 | 530 |
531 for (; frame_it != cast->missing_frames_and_packets_.end() && | 531 for (; frame_it != cast->missing_frames_and_packets_.end() && |
532 number_of_loss_fields < max_number_of_loss_fields; | 532 number_of_loss_fields < max_number_of_loss_fields; |
533 ++frame_it) { | 533 ++frame_it) { |
534 // Iterate through all frames with missing packets. | 534 // Iterate through all frames with missing packets. |
535 if (frame_it->second.empty()) { | 535 if (frame_it->second.empty()) { |
536 // Special case all packets in a frame is missing. | 536 // Special case all packets in a frame is missing. |
537 start_size = packet->size(); | 537 start_size = packet->size(); |
538 packet->resize(start_size + 4); | 538 packet->resize(start_size + 4); |
539 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); | 539 base::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); |
540 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); | 540 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); |
541 big_endian_nack_writer.WriteU16(kRtcpCastAllPacketsLost); | 541 big_endian_nack_writer.WriteU16(kRtcpCastAllPacketsLost); |
542 big_endian_nack_writer.WriteU8(0); | 542 big_endian_nack_writer.WriteU8(0); |
543 ++number_of_loss_fields; | 543 ++number_of_loss_fields; |
544 } else { | 544 } else { |
545 PacketIdSet::const_iterator packet_it = frame_it->second.begin(); | 545 PacketIdSet::const_iterator packet_it = frame_it->second.begin(); |
546 while (packet_it != frame_it->second.end()) { | 546 while (packet_it != frame_it->second.end()) { |
547 uint16 packet_id = *packet_it; | 547 uint16 packet_id = *packet_it; |
548 | 548 |
549 start_size = packet->size(); | 549 start_size = packet->size(); |
550 packet->resize(start_size + 4); | 550 packet->resize(start_size + 4); |
551 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), | 551 base::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), |
552 4); | 552 4); |
553 | 553 |
554 // Write frame and packet id to buffer before calculating bitmask. | 554 // Write frame and packet id to buffer before calculating bitmask. |
555 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); | 555 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); |
556 big_endian_nack_writer.WriteU16(packet_id); | 556 big_endian_nack_writer.WriteU16(packet_id); |
557 | 557 |
558 uint8 bitmask = 0; | 558 uint8 bitmask = 0; |
559 ++packet_it; | 559 ++packet_it; |
560 while (packet_it != frame_it->second.end()) { | 560 while (packet_it != frame_it->second.end()) { |
561 int shift = static_cast<uint8>(*packet_it - packet_id) - 1; | 561 int shift = static_cast<uint8>(*packet_it - packet_id) - 1; |
562 if (shift >= 0 && shift <= 7) { | 562 if (shift >= 0 && shift <= 7) { |
(...skipping 21 matching lines...) Expand all Loading... |
584 size_t total_number_of_messages_to_send = 0; | 584 size_t total_number_of_messages_to_send = 0; |
585 size_t rtcp_log_size = 0; | 585 size_t rtcp_log_size = 0; |
586 | 586 |
587 if (!ScanRtcpReceiverLogMessage( | 587 if (!ScanRtcpReceiverLogMessage( |
588 *receiver_log_message, packet_start_size, &number_of_frames, | 588 *receiver_log_message, packet_start_size, &number_of_frames, |
589 &total_number_of_messages_to_send, &rtcp_log_size)) { | 589 &total_number_of_messages_to_send, &rtcp_log_size)) { |
590 return; | 590 return; |
591 } | 591 } |
592 packet->resize(packet_start_size + rtcp_log_size); | 592 packet->resize(packet_start_size + rtcp_log_size); |
593 | 593 |
594 net::BigEndianWriter big_endian_writer(&((*packet)[packet_start_size]), | 594 base::BigEndianWriter big_endian_writer(&((*packet)[packet_start_size]), |
595 rtcp_log_size); | 595 rtcp_log_size); |
596 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); | 596 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); |
597 big_endian_writer.WriteU8(transport::kPacketTypeApplicationDefined); | 597 big_endian_writer.WriteU8(transport::kPacketTypeApplicationDefined); |
598 big_endian_writer.WriteU16(static_cast<uint16>( | 598 big_endian_writer.WriteU16(static_cast<uint16>( |
599 2 + 2 * number_of_frames + total_number_of_messages_to_send)); | 599 2 + 2 * number_of_frames + total_number_of_messages_to_send)); |
600 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 600 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
601 big_endian_writer.WriteU32(kCast); | 601 big_endian_writer.WriteU32(kCast); |
602 | 602 |
603 while (!receiver_log_message->empty() && | 603 while (!receiver_log_message->empty() && |
604 total_number_of_messages_to_send > 0) { | 604 total_number_of_messages_to_send > 0) { |
605 RtcpReceiverFrameLogMessage& frame_log_messages( | 605 RtcpReceiverFrameLogMessage& frame_log_messages( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 if (frame_log_messages.event_log_messages_.empty()) { | 661 if (frame_log_messages.event_log_messages_.empty()) { |
662 // We sent all messages on this frame; pop the frame header. | 662 // We sent all messages on this frame; pop the frame header. |
663 receiver_log_message->pop_front(); | 663 receiver_log_message->pop_front(); |
664 } | 664 } |
665 } | 665 } |
666 DCHECK_EQ(total_number_of_messages_to_send, 0); | 666 DCHECK_EQ(total_number_of_messages_to_send, 0); |
667 } | 667 } |
668 | 668 |
669 } // namespace cast | 669 } // namespace cast |
670 } // namespace media | 670 } // namespace media |
OLD | NEW |