| 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/rtcp_defines.h" | 13 #include "media/cast/rtcp/rtcp_defines.h" |
| 13 #include "media/cast/rtcp/rtcp_utility.h" | 14 #include "media/cast/rtcp/rtcp_utility.h" |
| 14 #include "media/cast/transport/cast_transport_defines.h" | 15 #include "media/cast/transport/cast_transport_defines.h" |
| 15 #include "media/cast/transport/pacing/paced_sender.h" | 16 #include "media/cast/transport/pacing/paced_sender.h" |
| 16 #include "net/base/big_endian.h" | |
| 17 | 17 |
| 18 namespace media { | 18 namespace media { |
| 19 namespace cast { | 19 namespace cast { |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 // Converts a log event type to an integer value. | 22 // Converts a log event type to an integer value. |
| 23 int ConvertEventTypeToWireFormat(const CastLoggingEvent& event) { | 23 int ConvertEventTypeToWireFormat(const CastLoggingEvent& event) { |
| 24 switch (event) { | 24 switch (event) { |
| 25 case kAudioAckSent: | 25 case kAudioAckSent: |
| 26 return 1; | 26 return 1; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 | 186 |
| 187 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, | 187 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, |
| 188 Packet* packet) const { | 188 Packet* packet) const { |
| 189 size_t start_size = packet->size(); | 189 size_t start_size = packet->size(); |
| 190 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; | 190 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; |
| 191 if (start_size + 32 > kMaxIpPacketSize) return; | 191 if (start_size + 32 > kMaxIpPacketSize) return; |
| 192 | 192 |
| 193 uint16 number_of_rows = (report_block) ? 7 : 1; | 193 uint16 number_of_rows = (report_block) ? 7 : 1; |
| 194 packet->resize(start_size + 8); | 194 packet->resize(start_size + 8); |
| 195 | 195 |
| 196 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); | 196 base::BigEndianWriter big_endian_writer( |
| 197 reinterpret_cast<char*>(&((*packet)[start_size])), 8); |
| 197 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); | 198 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); |
| 198 big_endian_writer.WriteU8(transport::kPacketTypeReceiverReport); | 199 big_endian_writer.WriteU8(transport::kPacketTypeReceiverReport); |
| 199 big_endian_writer.WriteU16(number_of_rows); | 200 big_endian_writer.WriteU16(number_of_rows); |
| 200 big_endian_writer.WriteU32(ssrc_); | 201 big_endian_writer.WriteU32(ssrc_); |
| 201 | 202 |
| 202 if (report_block) { | 203 if (report_block) { |
| 203 AddReportBlocks(*report_block, packet); // Adds 24 bytes. | 204 AddReportBlocks(*report_block, packet); // Adds 24 bytes. |
| 204 } | 205 } |
| 205 } | 206 } |
| 206 | 207 |
| 207 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, | 208 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, |
| 208 Packet* packet) const { | 209 Packet* packet) const { |
| 209 size_t start_size = packet->size(); | 210 size_t start_size = packet->size(); |
| 210 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 211 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
| 211 if (start_size + 24 > kMaxIpPacketSize) return; | 212 if (start_size + 24 > kMaxIpPacketSize) return; |
| 212 | 213 |
| 213 packet->resize(start_size + 24); | 214 packet->resize(start_size + 24); |
| 214 | 215 |
| 215 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); | 216 base::BigEndianWriter big_endian_writer( |
| 217 reinterpret_cast<char*>(&((*packet)[start_size])), 24); |
| 216 big_endian_writer.WriteU32(report_block.media_ssrc); | 218 big_endian_writer.WriteU32(report_block.media_ssrc); |
| 217 big_endian_writer.WriteU8(report_block.fraction_lost); | 219 big_endian_writer.WriteU8(report_block.fraction_lost); |
| 218 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); | 220 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); |
| 219 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); | 221 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); |
| 220 big_endian_writer.WriteU8(report_block.cumulative_lost); | 222 big_endian_writer.WriteU8(report_block.cumulative_lost); |
| 221 | 223 |
| 222 // Extended highest seq_no, contain the highest sequence number received. | 224 // Extended highest seq_no, contain the highest sequence number received. |
| 223 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); | 225 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); |
| 224 big_endian_writer.WriteU32(report_block.jitter); | 226 big_endian_writer.WriteU32(report_block.jitter); |
| 225 | 227 |
| 226 // Last SR timestamp; our NTP time when we received the last report. | 228 // Last SR timestamp; our NTP time when we received the last report. |
| 227 // This is the value that we read from the send report packet not when we | 229 // This is the value that we read from the send report packet not when we |
| 228 // received it. | 230 // received it. |
| 229 big_endian_writer.WriteU32(report_block.last_sr); | 231 big_endian_writer.WriteU32(report_block.last_sr); |
| 230 | 232 |
| 231 // Delay since last received report, time since we received the report. | 233 // Delay since last received report, time since we received the report. |
| 232 big_endian_writer.WriteU32(report_block.delay_since_last_sr); | 234 big_endian_writer.WriteU32(report_block.delay_since_last_sr); |
| 233 } | 235 } |
| 234 | 236 |
| 235 void RtcpSender::BuildSdec(Packet* packet) const { | 237 void RtcpSender::BuildSdec(Packet* packet) const { |
| 236 size_t start_size = packet->size(); | 238 size_t start_size = packet->size(); |
| 237 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize) | 239 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize) |
| 238 << "Not enough buffer space"; | 240 << "Not enough buffer space"; |
| 239 if (start_size + 12 > kMaxIpPacketSize) return; | 241 if (start_size + 12 > kMaxIpPacketSize) return; |
| 240 | 242 |
| 241 // SDES Source Description. | 243 // SDES Source Description. |
| 242 packet->resize(start_size + 10); | 244 packet->resize(start_size + 10); |
| 243 | 245 |
| 244 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10); | 246 base::BigEndianWriter big_endian_writer( |
| 247 reinterpret_cast<char*>(&((*packet)[start_size])), 10); |
| 245 // We always need to add one SDES CNAME. | 248 // We always need to add one SDES CNAME. |
| 246 big_endian_writer.WriteU8(0x80 + 1); | 249 big_endian_writer.WriteU8(0x80 + 1); |
| 247 big_endian_writer.WriteU8(transport::kPacketTypeSdes); | 250 big_endian_writer.WriteU8(transport::kPacketTypeSdes); |
| 248 | 251 |
| 249 // Handle SDES length later on. | 252 // Handle SDES length later on. |
| 250 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; | 253 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; |
| 251 big_endian_writer.WriteU16(0); | 254 big_endian_writer.WriteU16(0); |
| 252 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 255 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 253 big_endian_writer.WriteU8(1); // CNAME = 1 | 256 big_endian_writer.WriteU8(1); // CNAME = 1 |
| 254 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); | 257 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 275 (*packet)[sdes_length_position] = buffer_length; | 278 (*packet)[sdes_length_position] = buffer_length; |
| 276 } | 279 } |
| 277 | 280 |
| 278 void RtcpSender::BuildPli(uint32 remote_ssrc, Packet* packet) const { | 281 void RtcpSender::BuildPli(uint32 remote_ssrc, Packet* packet) const { |
| 279 size_t start_size = packet->size(); | 282 size_t start_size = packet->size(); |
| 280 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; | 283 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; |
| 281 if (start_size + 12 > kMaxIpPacketSize) return; | 284 if (start_size + 12 > kMaxIpPacketSize) return; |
| 282 | 285 |
| 283 packet->resize(start_size + 12); | 286 packet->resize(start_size + 12); |
| 284 | 287 |
| 285 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12); | 288 base::BigEndianWriter big_endian_writer( |
| 289 reinterpret_cast<char*>(&((*packet)[start_size])), 12); |
| 286 uint8 FMT = 1; // Picture loss indicator. | 290 uint8 FMT = 1; // Picture loss indicator. |
| 287 big_endian_writer.WriteU8(0x80 + FMT); | 291 big_endian_writer.WriteU8(0x80 + FMT); |
| 288 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 292 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
| 289 big_endian_writer.WriteU16(2); // Used fixed length of 2. | 293 big_endian_writer.WriteU16(2); // Used fixed length of 2. |
| 290 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 294 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 291 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. | 295 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. |
| 292 } | 296 } |
| 293 | 297 |
| 294 /* | 298 /* |
| 295 0 1 2 3 | 299 0 1 2 3 |
| 296 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 | 300 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 |
| 297 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 301 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 298 | PB |0| Payload Type| Native Rpsi bit string | | 302 | PB |0| Payload Type| Native Rpsi bit string | |
| 299 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 303 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 300 | defined per codec ... | Padding (0) | | 304 | defined per codec ... | Padding (0) | |
| 301 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 305 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 302 */ | 306 */ |
| 303 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { | 307 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { |
| 304 size_t start_size = packet->size(); | 308 size_t start_size = packet->size(); |
| 305 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 309 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
| 306 if (start_size + 24 > kMaxIpPacketSize) return; | 310 if (start_size + 24 > kMaxIpPacketSize) return; |
| 307 | 311 |
| 308 packet->resize(start_size + 24); | 312 packet->resize(start_size + 24); |
| 309 | 313 |
| 310 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); | 314 base::BigEndianWriter big_endian_writer( |
| 315 reinterpret_cast<char*>(&((*packet)[start_size])), 24); |
| 311 uint8 FMT = 3; // Reference Picture Selection Indication. | 316 uint8 FMT = 3; // Reference Picture Selection Indication. |
| 312 big_endian_writer.WriteU8(0x80 + FMT); | 317 big_endian_writer.WriteU8(0x80 + FMT); |
| 313 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 318 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
| 314 | 319 |
| 315 // Calculate length. | 320 // Calculate length. |
| 316 uint32 bits_required = 7; | 321 uint32 bits_required = 7; |
| 317 uint8 bytes_required = 1; | 322 uint8 bytes_required = 1; |
| 318 while ((rpsi->picture_id >> bits_required) > 0) { | 323 while ((rpsi->picture_id >> bits_required) > 0) { |
| 319 bits_required += 7; | 324 bits_required += 7; |
| 320 bytes_required++; | 325 bytes_required++; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 | 359 |
| 355 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, Packet* packet) const { | 360 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, Packet* packet) const { |
| 356 size_t start_size = packet->size(); | 361 size_t start_size = packet->size(); |
| 357 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); | 362 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); |
| 358 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize) | 363 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize) |
| 359 << "Not enough buffer space"; | 364 << "Not enough buffer space"; |
| 360 if (start_size + remb_size > kMaxIpPacketSize) return; | 365 if (start_size + remb_size > kMaxIpPacketSize) return; |
| 361 | 366 |
| 362 packet->resize(start_size + remb_size); | 367 packet->resize(start_size + remb_size); |
| 363 | 368 |
| 364 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size); | 369 base::BigEndianWriter big_endian_writer( |
| 370 reinterpret_cast<char*>(&((*packet)[start_size])), remb_size); |
| 365 | 371 |
| 366 // Add application layer feedback. | 372 // Add application layer feedback. |
| 367 uint8 FMT = 15; | 373 uint8 FMT = 15; |
| 368 big_endian_writer.WriteU8(0x80 + FMT); | 374 big_endian_writer.WriteU8(0x80 + FMT); |
| 369 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 375 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
| 370 big_endian_writer.WriteU8(0); | 376 big_endian_writer.WriteU8(0); |
| 371 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); | 377 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); |
| 372 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 378 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 373 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. | 379 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. |
| 374 big_endian_writer.WriteU32(kRemb); | 380 big_endian_writer.WriteU32(kRemb); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 394 remb->remb_bitrate); | 400 remb->remb_bitrate); |
| 395 } | 401 } |
| 396 | 402 |
| 397 void RtcpSender::BuildNack(const RtcpNackMessage* nack, Packet* packet) const { | 403 void RtcpSender::BuildNack(const RtcpNackMessage* nack, Packet* packet) const { |
| 398 size_t start_size = packet->size(); | 404 size_t start_size = packet->size(); |
| 399 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space"; | 405 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space"; |
| 400 if (start_size + 16 > kMaxIpPacketSize) return; | 406 if (start_size + 16 > kMaxIpPacketSize) return; |
| 401 | 407 |
| 402 packet->resize(start_size + 16); | 408 packet->resize(start_size + 16); |
| 403 | 409 |
| 404 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16); | 410 base::BigEndianWriter big_endian_writer( |
| 411 reinterpret_cast<char*>(&((*packet)[start_size])), 16); |
| 405 | 412 |
| 406 uint8 FMT = 1; | 413 uint8 FMT = 1; |
| 407 big_endian_writer.WriteU8(0x80 + FMT); | 414 big_endian_writer.WriteU8(0x80 + FMT); |
| 408 big_endian_writer.WriteU8(transport::kPacketTypeGenericRtpFeedback); | 415 big_endian_writer.WriteU8(transport::kPacketTypeGenericRtpFeedback); |
| 409 big_endian_writer.WriteU8(0); | 416 big_endian_writer.WriteU8(0); |
| 410 size_t nack_size_pos = start_size + 3; | 417 size_t nack_size_pos = start_size + 3; |
| 411 big_endian_writer.WriteU8(3); | 418 big_endian_writer.WriteU8(3); |
| 412 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 419 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 413 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. | 420 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. |
| 414 | 421 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 432 } else { | 439 } else { |
| 433 break; | 440 break; |
| 434 } | 441 } |
| 435 } | 442 } |
| 436 // Write the sequence number and the bitmask to the packet. | 443 // Write the sequence number and the bitmask to the packet. |
| 437 start_size = packet->size(); | 444 start_size = packet->size(); |
| 438 DCHECK_LT(start_size + 4, kMaxIpPacketSize) << "Not enough buffer space"; | 445 DCHECK_LT(start_size + 4, kMaxIpPacketSize) << "Not enough buffer space"; |
| 439 if (start_size + 4 > kMaxIpPacketSize) return; | 446 if (start_size + 4 > kMaxIpPacketSize) return; |
| 440 | 447 |
| 441 packet->resize(start_size + 4); | 448 packet->resize(start_size + 4); |
| 442 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); | 449 base::BigEndianWriter big_endian_nack_writer( |
| 450 reinterpret_cast<char*>(&((*packet)[start_size])), 4); |
| 443 big_endian_nack_writer.WriteU16(nack_sequence_number); | 451 big_endian_nack_writer.WriteU16(nack_sequence_number); |
| 444 big_endian_nack_writer.WriteU16(bitmask); | 452 big_endian_nack_writer.WriteU16(bitmask); |
| 445 number_of_nack_fields++; | 453 number_of_nack_fields++; |
| 446 } | 454 } |
| 447 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); | 455 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); |
| 448 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); | 456 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); |
| 449 } | 457 } |
| 450 | 458 |
| 451 void RtcpSender::BuildBye(Packet* packet) const { | 459 void RtcpSender::BuildBye(Packet* packet) const { |
| 452 size_t start_size = packet->size(); | 460 size_t start_size = packet->size(); |
| 453 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; | 461 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; |
| 454 if (start_size + 8 > kMaxIpPacketSize) return; | 462 if (start_size + 8 > kMaxIpPacketSize) return; |
| 455 | 463 |
| 456 packet->resize(start_size + 8); | 464 packet->resize(start_size + 8); |
| 457 | 465 |
| 458 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); | 466 base::BigEndianWriter big_endian_writer( |
| 467 reinterpret_cast<char*>(&((*packet)[start_size])), 8); |
| 459 big_endian_writer.WriteU8(0x80 + 1); | 468 big_endian_writer.WriteU8(0x80 + 1); |
| 460 big_endian_writer.WriteU8(transport::kPacketTypeBye); | 469 big_endian_writer.WriteU8(transport::kPacketTypeBye); |
| 461 big_endian_writer.WriteU16(1); // Length. | 470 big_endian_writer.WriteU16(1); // Length. |
| 462 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 471 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 463 } | 472 } |
| 464 | 473 |
| 465 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, | 474 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, |
| 466 Packet* packet) const { | 475 Packet* packet) const { |
| 467 size_t start_size = packet->size(); | 476 size_t start_size = packet->size(); |
| 468 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 477 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
| 469 if (start_size + 20 > kMaxIpPacketSize) return; | 478 if (start_size + 20 > kMaxIpPacketSize) return; |
| 470 | 479 |
| 471 packet->resize(start_size + 20); | 480 packet->resize(start_size + 20); |
| 472 | 481 |
| 473 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); | 482 base::BigEndianWriter big_endian_writer( |
| 483 reinterpret_cast<char*>(&((*packet)[start_size])), 20); |
| 474 | 484 |
| 475 big_endian_writer.WriteU8(0x80); | 485 big_endian_writer.WriteU8(0x80); |
| 476 big_endian_writer.WriteU8(transport::kPacketTypeXr); | 486 big_endian_writer.WriteU8(transport::kPacketTypeXr); |
| 477 big_endian_writer.WriteU16(4); // Length. | 487 big_endian_writer.WriteU16(4); // Length. |
| 478 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 488 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 479 big_endian_writer.WriteU8(4); // Add block type. | 489 big_endian_writer.WriteU8(4); // Add block type. |
| 480 big_endian_writer.WriteU8(0); // Add reserved. | 490 big_endian_writer.WriteU8(0); // Add reserved. |
| 481 big_endian_writer.WriteU16(2); // Block length. | 491 big_endian_writer.WriteU16(2); // Block length. |
| 482 | 492 |
| 483 // Add the media (received RTP) SSRC. | 493 // Add the media (received RTP) SSRC. |
| 484 big_endian_writer.WriteU32(rrtr->ntp_seconds); | 494 big_endian_writer.WriteU32(rrtr->ntp_seconds); |
| 485 big_endian_writer.WriteU32(rrtr->ntp_fraction); | 495 big_endian_writer.WriteU32(rrtr->ntp_fraction); |
| 486 } | 496 } |
| 487 | 497 |
| 488 void RtcpSender::BuildCast(const RtcpCastMessage* cast, Packet* packet) const { | 498 void RtcpSender::BuildCast(const RtcpCastMessage* cast, Packet* packet) const { |
| 489 size_t start_size = packet->size(); | 499 size_t start_size = packet->size(); |
| 490 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 500 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
| 491 if (start_size + 20 > kMaxIpPacketSize) return; | 501 if (start_size + 20 > kMaxIpPacketSize) return; |
| 492 | 502 |
| 493 packet->resize(start_size + 20); | 503 packet->resize(start_size + 20); |
| 494 | 504 |
| 495 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); | 505 base::BigEndianWriter big_endian_writer( |
| 506 reinterpret_cast<char*>(&((*packet)[start_size])), 20); |
| 496 uint8 FMT = 15; // Application layer feedback. | 507 uint8 FMT = 15; // Application layer feedback. |
| 497 big_endian_writer.WriteU8(0x80 + FMT); | 508 big_endian_writer.WriteU8(0x80 + FMT); |
| 498 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 509 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
| 499 big_endian_writer.WriteU8(0); | 510 big_endian_writer.WriteU8(0); |
| 500 size_t cast_size_pos = start_size + 3; // Save length position. | 511 size_t cast_size_pos = start_size + 3; // Save length position. |
| 501 big_endian_writer.WriteU8(4); | 512 big_endian_writer.WriteU8(4); |
| 502 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 513 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 503 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. | 514 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. |
| 504 big_endian_writer.WriteU32(kCast); | 515 big_endian_writer.WriteU32(kCast); |
| 505 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); | 516 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 516 cast->missing_frames_and_packets_.begin(); | 527 cast->missing_frames_and_packets_.begin(); |
| 517 | 528 |
| 518 for (; frame_it != cast->missing_frames_and_packets_.end() && | 529 for (; frame_it != cast->missing_frames_and_packets_.end() && |
| 519 number_of_loss_fields < max_number_of_loss_fields; | 530 number_of_loss_fields < max_number_of_loss_fields; |
| 520 ++frame_it) { | 531 ++frame_it) { |
| 521 // Iterate through all frames with missing packets. | 532 // Iterate through all frames with missing packets. |
| 522 if (frame_it->second.empty()) { | 533 if (frame_it->second.empty()) { |
| 523 // Special case all packets in a frame is missing. | 534 // Special case all packets in a frame is missing. |
| 524 start_size = packet->size(); | 535 start_size = packet->size(); |
| 525 packet->resize(start_size + 4); | 536 packet->resize(start_size + 4); |
| 526 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); | 537 base::BigEndianWriter big_endian_nack_writer( |
| 538 reinterpret_cast<char*>(&((*packet)[start_size])), 4); |
| 527 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); | 539 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); |
| 528 big_endian_nack_writer.WriteU16(kRtcpCastAllPacketsLost); | 540 big_endian_nack_writer.WriteU16(kRtcpCastAllPacketsLost); |
| 529 big_endian_nack_writer.WriteU8(0); | 541 big_endian_nack_writer.WriteU8(0); |
| 530 ++number_of_loss_fields; | 542 ++number_of_loss_fields; |
| 531 } else { | 543 } else { |
| 532 PacketIdSet::const_iterator packet_it = frame_it->second.begin(); | 544 PacketIdSet::const_iterator packet_it = frame_it->second.begin(); |
| 533 while (packet_it != frame_it->second.end()) { | 545 while (packet_it != frame_it->second.end()) { |
| 534 uint16 packet_id = *packet_it; | 546 uint16 packet_id = *packet_it; |
| 535 | 547 |
| 536 start_size = packet->size(); | 548 start_size = packet->size(); |
| 537 packet->resize(start_size + 4); | 549 packet->resize(start_size + 4); |
| 538 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), | 550 base::BigEndianWriter big_endian_nack_writer( |
| 539 4); | 551 reinterpret_cast<char*>(&((*packet)[start_size])), 4); |
| 540 | 552 |
| 541 // Write frame and packet id to buffer before calculating bitmask. | 553 // Write frame and packet id to buffer before calculating bitmask. |
| 542 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); | 554 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); |
| 543 big_endian_nack_writer.WriteU16(packet_id); | 555 big_endian_nack_writer.WriteU16(packet_id); |
| 544 | 556 |
| 545 uint8 bitmask = 0; | 557 uint8 bitmask = 0; |
| 546 ++packet_it; | 558 ++packet_it; |
| 547 while (packet_it != frame_it->second.end()) { | 559 while (packet_it != frame_it->second.end()) { |
| 548 int shift = static_cast<uint8>(*packet_it - packet_id) - 1; | 560 int shift = static_cast<uint8>(*packet_it - packet_id) - 1; |
| 549 if (shift >= 0 && shift <= 7) { | 561 if (shift >= 0 && shift <= 7) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 575 if (!BuildRtcpReceiverLogMessage(rtcp_events, | 587 if (!BuildRtcpReceiverLogMessage(rtcp_events, |
| 576 packet_start_size, | 588 packet_start_size, |
| 577 &receiver_log_message, | 589 &receiver_log_message, |
| 578 &number_of_frames, | 590 &number_of_frames, |
| 579 &total_number_of_messages_to_send, | 591 &total_number_of_messages_to_send, |
| 580 &rtcp_log_size)) { | 592 &rtcp_log_size)) { |
| 581 return; | 593 return; |
| 582 } | 594 } |
| 583 packet->resize(packet_start_size + rtcp_log_size); | 595 packet->resize(packet_start_size + rtcp_log_size); |
| 584 | 596 |
| 585 net::BigEndianWriter big_endian_writer(&((*packet)[packet_start_size]), | 597 base::BigEndianWriter big_endian_writer( |
| 586 rtcp_log_size); | 598 reinterpret_cast<char*>(&((*packet)[packet_start_size])), rtcp_log_size); |
| 587 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); | 599 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); |
| 588 big_endian_writer.WriteU8(transport::kPacketTypeApplicationDefined); | 600 big_endian_writer.WriteU8(transport::kPacketTypeApplicationDefined); |
| 589 big_endian_writer.WriteU16(static_cast<uint16>( | 601 big_endian_writer.WriteU16(static_cast<uint16>( |
| 590 2 + 2 * number_of_frames + total_number_of_messages_to_send)); | 602 2 + 2 * number_of_frames + total_number_of_messages_to_send)); |
| 591 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 603 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 592 big_endian_writer.WriteU32(kCast); | 604 big_endian_writer.WriteU32(kCast); |
| 593 | 605 |
| 594 while (!receiver_log_message.empty() && | 606 while (!receiver_log_message.empty() && |
| 595 total_number_of_messages_to_send > 0) { | 607 total_number_of_messages_to_send > 0) { |
| 596 RtcpReceiverFrameLogMessage& frame_log_messages( | 608 RtcpReceiverFrameLogMessage& frame_log_messages( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 if (frame_log_messages.event_log_messages_.empty()) { | 664 if (frame_log_messages.event_log_messages_.empty()) { |
| 653 // We sent all messages on this frame; pop the frame header. | 665 // We sent all messages on this frame; pop the frame header. |
| 654 receiver_log_message.pop_front(); | 666 receiver_log_message.pop_front(); |
| 655 } | 667 } |
| 656 } | 668 } |
| 657 DCHECK_EQ(total_number_of_messages_to_send, 0); | 669 DCHECK_EQ(total_number_of_messages_to_send, 0); |
| 658 } | 670 } |
| 659 | 671 |
| 660 } // namespace cast | 672 } // namespace cast |
| 661 } // namespace media | 673 } // namespace media |
| OLD | NEW |