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 |