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/net/rtcp/rtcp_sender.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/big_endian.h" | 12 #include "base/big_endian.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "media/cast/cast_environment.h" | 14 #include "media/cast/cast_environment.h" |
15 #include "media/cast/rtcp/rtcp_defines.h" | 15 #include "media/cast/net/cast_transport_defines.h" |
16 #include "media/cast/rtcp/rtcp_utility.h" | 16 #include "media/cast/net/pacing/paced_sender.h" |
17 #include "media/cast/transport/cast_transport_defines.h" | 17 #include "media/cast/net/rtcp/rtcp_defines.h" |
18 #include "media/cast/transport/pacing/paced_sender.h" | 18 #include "media/cast/net/rtcp/rtcp_utility.h" |
19 | 19 |
20 namespace media { | 20 namespace media { |
21 namespace cast { | 21 namespace cast { |
22 namespace { | 22 namespace { |
23 | 23 |
24 // Max delta is 4095 milliseconds because we need to be able to encode it in | 24 // Max delta is 4095 milliseconds because we need to be able to encode it in |
25 // 12 bits. | 25 // 12 bits. |
26 const int64 kMaxWireFormatTimeDeltaMs = INT64_C(0xfff); | 26 const int64 kMaxWireFormatTimeDeltaMs = INT64_C(0xfff); |
27 | 27 |
28 uint16 MergeEventTypeAndTimestampForWireFormat( | 28 uint16 MergeEventTypeAndTimestampForWireFormat( |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 int frame_count_; | 141 int frame_count_; |
142 int packet_count_; | 142 int packet_count_; |
143 int last_frame_id_; | 143 int last_frame_id_; |
144 int last_packet_id_; | 144 int last_packet_id_; |
145 bool contiguous_sequence_; | 145 bool contiguous_sequence_; |
146 }; | 146 }; |
147 } // namespace | 147 } // namespace |
148 | 148 |
149 // TODO(mikhal): This is only used by the receiver. Consider renaming. | 149 // TODO(mikhal): This is only used by the receiver. Consider renaming. |
150 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment, | 150 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment, |
151 transport::PacedPacketSender* outgoing_transport, | 151 PacedPacketSender* outgoing_transport, |
152 uint32 sending_ssrc, | 152 uint32 sending_ssrc, |
153 const std::string& c_name) | 153 const std::string& c_name) |
154 : ssrc_(sending_ssrc), | 154 : ssrc_(sending_ssrc), |
155 c_name_(c_name), | 155 c_name_(c_name), |
156 transport_(outgoing_transport), | 156 transport_(outgoing_transport), |
157 cast_environment_(cast_environment) { | 157 cast_environment_(cast_environment) { |
158 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; | 158 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; |
159 } | 159 } |
160 | 160 |
161 RtcpSender::~RtcpSender() {} | 161 RtcpSender::~RtcpSender() {} |
162 | 162 |
163 void RtcpSender::SendRtcpFromRtpReceiver( | 163 void RtcpSender::SendRtcpFromRtpReceiver( |
164 uint32 packet_type_flags, | 164 uint32 packet_type_flags, |
165 const transport::RtcpReportBlock* report_block, | 165 const RtcpReportBlock* report_block, |
166 const RtcpReceiverReferenceTimeReport* rrtr, | 166 const RtcpReceiverReferenceTimeReport* rrtr, |
167 const RtcpCastMessage* cast_message, | 167 const RtcpCastMessage* cast_message, |
168 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, | 168 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, |
169 base::TimeDelta target_delay) { | 169 base::TimeDelta target_delay) { |
170 if (packet_type_flags & transport::kRtcpSr || | 170 if (packet_type_flags & kRtcpSr || |
171 packet_type_flags & transport::kRtcpDlrr || | 171 packet_type_flags & kRtcpDlrr || |
172 packet_type_flags & transport::kRtcpSenderLog) { | 172 packet_type_flags & kRtcpSenderLog) { |
173 NOTREACHED() << "Invalid argument"; | 173 NOTREACHED() << "Invalid argument"; |
174 } | 174 } |
175 if (packet_type_flags & transport::kRtcpPli || | 175 if (packet_type_flags & kRtcpPli || |
176 packet_type_flags & transport::kRtcpRpsi || | 176 packet_type_flags & kRtcpRpsi || |
177 packet_type_flags & transport::kRtcpRemb || | 177 packet_type_flags & kRtcpRemb || |
178 packet_type_flags & transport::kRtcpNack) { | 178 packet_type_flags & kRtcpNack) { |
179 // Implement these for webrtc interop. | 179 // Implement these for webrtc interop. |
180 NOTIMPLEMENTED(); | 180 NOTIMPLEMENTED(); |
181 } | 181 } |
182 transport::PacketRef packet(new base::RefCountedData<Packet>); | 182 PacketRef packet(new base::RefCountedData<Packet>); |
183 packet->data.reserve(kMaxIpPacketSize); | 183 packet->data.reserve(kMaxIpPacketSize); |
184 | 184 |
185 if (packet_type_flags & transport::kRtcpRr) { | 185 if (packet_type_flags & kRtcpRr) { |
186 BuildRR(report_block, &packet->data); | 186 BuildRR(report_block, &packet->data); |
187 if (!c_name_.empty()) { | 187 if (!c_name_.empty()) { |
188 BuildSdec(&packet->data); | 188 BuildSdec(&packet->data); |
189 } | 189 } |
190 } | 190 } |
191 if (packet_type_flags & transport::kRtcpBye) { | 191 if (packet_type_flags & kRtcpBye) { |
192 BuildBye(&packet->data); | 192 BuildBye(&packet->data); |
193 } | 193 } |
194 if (packet_type_flags & transport::kRtcpRrtr) { | 194 if (packet_type_flags & kRtcpRrtr) { |
195 DCHECK(rrtr) << "Invalid argument"; | 195 DCHECK(rrtr) << "Invalid argument"; |
196 BuildRrtr(rrtr, &packet->data); | 196 BuildRrtr(rrtr, &packet->data); |
197 } | 197 } |
198 if (packet_type_flags & transport::kRtcpCast) { | 198 if (packet_type_flags & kRtcpCast) { |
199 DCHECK(cast_message) << "Invalid argument"; | 199 DCHECK(cast_message) << "Invalid argument"; |
200 BuildCast(cast_message, target_delay, &packet->data); | 200 BuildCast(cast_message, target_delay, &packet->data); |
201 } | 201 } |
202 if (packet_type_flags & transport::kRtcpReceiverLog) { | 202 if (packet_type_flags & kRtcpReceiverLog) { |
203 DCHECK(rtcp_events) << "Invalid argument"; | 203 DCHECK(rtcp_events) << "Invalid argument"; |
204 BuildReceiverLog(*rtcp_events, &packet->data); | 204 BuildReceiverLog(*rtcp_events, &packet->data); |
205 } | 205 } |
206 | 206 |
207 if (packet->data.empty()) | 207 if (packet->data.empty()) |
208 return; // Sanity don't send empty packets. | 208 return; // Sanity don't send empty packets. |
209 | 209 |
210 transport_->SendRtcpPacket(ssrc_, packet); | 210 transport_->SendRtcpPacket(ssrc_, packet); |
211 } | 211 } |
212 | 212 |
213 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, | 213 void RtcpSender::BuildRR(const RtcpReportBlock* report_block, |
214 Packet* packet) const { | 214 Packet* packet) const { |
215 size_t start_size = packet->size(); | 215 size_t start_size = packet->size(); |
216 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; | 216 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; |
217 if (start_size + 32 > kMaxIpPacketSize) | 217 if (start_size + 32 > kMaxIpPacketSize) |
218 return; | 218 return; |
219 | 219 |
220 uint16 number_of_rows = (report_block) ? 7 : 1; | 220 uint16 number_of_rows = (report_block) ? 7 : 1; |
221 packet->resize(start_size + 8); | 221 packet->resize(start_size + 8); |
222 | 222 |
223 base::BigEndianWriter big_endian_writer( | 223 base::BigEndianWriter big_endian_writer( |
224 reinterpret_cast<char*>(&((*packet)[start_size])), 8); | 224 reinterpret_cast<char*>(&((*packet)[start_size])), 8); |
225 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); | 225 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); |
226 big_endian_writer.WriteU8(transport::kPacketTypeReceiverReport); | 226 big_endian_writer.WriteU8(kPacketTypeReceiverReport); |
227 big_endian_writer.WriteU16(number_of_rows); | 227 big_endian_writer.WriteU16(number_of_rows); |
228 big_endian_writer.WriteU32(ssrc_); | 228 big_endian_writer.WriteU32(ssrc_); |
229 | 229 |
230 if (report_block) { | 230 if (report_block) { |
231 AddReportBlocks(*report_block, packet); // Adds 24 bytes. | 231 AddReportBlocks(*report_block, packet); // Adds 24 bytes. |
232 } | 232 } |
233 } | 233 } |
234 | 234 |
235 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, | 235 void RtcpSender::AddReportBlocks(const RtcpReportBlock& report_block, |
236 Packet* packet) const { | 236 Packet* packet) const { |
237 size_t start_size = packet->size(); | 237 size_t start_size = packet->size(); |
238 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 238 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
239 if (start_size + 24 > kMaxIpPacketSize) | 239 if (start_size + 24 > kMaxIpPacketSize) |
240 return; | 240 return; |
241 | 241 |
242 packet->resize(start_size + 24); | 242 packet->resize(start_size + 24); |
243 | 243 |
244 base::BigEndianWriter big_endian_writer( | 244 base::BigEndianWriter big_endian_writer( |
245 reinterpret_cast<char*>(&((*packet)[start_size])), 24); | 245 reinterpret_cast<char*>(&((*packet)[start_size])), 24); |
(...skipping 23 matching lines...) Expand all Loading... |
269 if (start_size + 12 > kMaxIpPacketSize) | 269 if (start_size + 12 > kMaxIpPacketSize) |
270 return; | 270 return; |
271 | 271 |
272 // SDES Source Description. | 272 // SDES Source Description. |
273 packet->resize(start_size + 10); | 273 packet->resize(start_size + 10); |
274 | 274 |
275 base::BigEndianWriter big_endian_writer( | 275 base::BigEndianWriter big_endian_writer( |
276 reinterpret_cast<char*>(&((*packet)[start_size])), 10); | 276 reinterpret_cast<char*>(&((*packet)[start_size])), 10); |
277 // We always need to add one SDES CNAME. | 277 // We always need to add one SDES CNAME. |
278 big_endian_writer.WriteU8(0x80 + 1); | 278 big_endian_writer.WriteU8(0x80 + 1); |
279 big_endian_writer.WriteU8(transport::kPacketTypeSdes); | 279 big_endian_writer.WriteU8(kPacketTypeSdes); |
280 | 280 |
281 // Handle SDES length later on. | 281 // Handle SDES length later on. |
282 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; | 282 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; |
283 big_endian_writer.WriteU16(0); | 283 big_endian_writer.WriteU16(0); |
284 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 284 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
285 big_endian_writer.WriteU8(1); // CNAME = 1 | 285 big_endian_writer.WriteU8(1); // CNAME = 1 |
286 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); | 286 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); |
287 | 287 |
288 size_t sdes_length = 10 + c_name_.length(); | 288 size_t sdes_length = 10 + c_name_.length(); |
289 packet->insert( | 289 packet->insert( |
(...skipping 22 matching lines...) Expand all Loading... |
312 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; | 312 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; |
313 if (start_size + 12 > kMaxIpPacketSize) | 313 if (start_size + 12 > kMaxIpPacketSize) |
314 return; | 314 return; |
315 | 315 |
316 packet->resize(start_size + 12); | 316 packet->resize(start_size + 12); |
317 | 317 |
318 base::BigEndianWriter big_endian_writer( | 318 base::BigEndianWriter big_endian_writer( |
319 reinterpret_cast<char*>(&((*packet)[start_size])), 12); | 319 reinterpret_cast<char*>(&((*packet)[start_size])), 12); |
320 uint8 FMT = 1; // Picture loss indicator. | 320 uint8 FMT = 1; // Picture loss indicator. |
321 big_endian_writer.WriteU8(0x80 + FMT); | 321 big_endian_writer.WriteU8(0x80 + FMT); |
322 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 322 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); |
323 big_endian_writer.WriteU16(2); // Used fixed length of 2. | 323 big_endian_writer.WriteU16(2); // Used fixed length of 2. |
324 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 324 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
325 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. | 325 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. |
326 } | 326 } |
327 | 327 |
328 /* | 328 /* |
329 0 1 2 3 | 329 0 1 2 3 |
330 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 330 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
331 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 331 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
332 | PB |0| Payload Type| Native Rpsi bit string | | 332 | PB |0| Payload Type| Native Rpsi bit string | |
333 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 333 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
334 | defined per codec ... | Padding (0) | | 334 | defined per codec ... | Padding (0) | |
335 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 335 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
336 */ | 336 */ |
337 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { | 337 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { |
338 size_t start_size = packet->size(); | 338 size_t start_size = packet->size(); |
339 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 339 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
340 if (start_size + 24 > kMaxIpPacketSize) | 340 if (start_size + 24 > kMaxIpPacketSize) |
341 return; | 341 return; |
342 | 342 |
343 packet->resize(start_size + 24); | 343 packet->resize(start_size + 24); |
344 | 344 |
345 base::BigEndianWriter big_endian_writer( | 345 base::BigEndianWriter big_endian_writer( |
346 reinterpret_cast<char*>(&((*packet)[start_size])), 24); | 346 reinterpret_cast<char*>(&((*packet)[start_size])), 24); |
347 uint8 FMT = 3; // Reference Picture Selection Indication. | 347 uint8 FMT = 3; // Reference Picture Selection Indication. |
348 big_endian_writer.WriteU8(0x80 + FMT); | 348 big_endian_writer.WriteU8(0x80 + FMT); |
349 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 349 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); |
350 | 350 |
351 // Calculate length. | 351 // Calculate length. |
352 uint32 bits_required = 7; | 352 uint32 bits_required = 7; |
353 uint8 bytes_required = 1; | 353 uint8 bytes_required = 1; |
354 while ((rpsi->picture_id >> bits_required) > 0) { | 354 while ((rpsi->picture_id >> bits_required) > 0) { |
355 bits_required += 7; | 355 bits_required += 7; |
356 bytes_required++; | 356 bytes_required++; |
357 } | 357 } |
358 uint8 size = 3; | 358 uint8 size = 3; |
359 if (bytes_required > 6) { | 359 if (bytes_required > 6) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 return; | 397 return; |
398 | 398 |
399 packet->resize(start_size + remb_size); | 399 packet->resize(start_size + remb_size); |
400 | 400 |
401 base::BigEndianWriter big_endian_writer( | 401 base::BigEndianWriter big_endian_writer( |
402 reinterpret_cast<char*>(&((*packet)[start_size])), remb_size); | 402 reinterpret_cast<char*>(&((*packet)[start_size])), remb_size); |
403 | 403 |
404 // Add application layer feedback. | 404 // Add application layer feedback. |
405 uint8 FMT = 15; | 405 uint8 FMT = 15; |
406 big_endian_writer.WriteU8(0x80 + FMT); | 406 big_endian_writer.WriteU8(0x80 + FMT); |
407 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 407 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); |
408 big_endian_writer.WriteU8(0); | 408 big_endian_writer.WriteU8(0); |
409 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); | 409 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); |
410 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 410 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
411 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. | 411 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. |
412 big_endian_writer.WriteU32(kRemb); | 412 big_endian_writer.WriteU32(kRemb); |
413 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); | 413 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); |
414 | 414 |
415 // 6 bit exponent and a 18 bit mantissa. | 415 // 6 bit exponent and a 18 bit mantissa. |
416 uint8 bitrate_exponent; | 416 uint8 bitrate_exponent; |
417 uint32 bitrate_mantissa; | 417 uint32 bitrate_mantissa; |
(...skipping 17 matching lines...) Expand all Loading... |
435 if (start_size + 16 > kMaxIpPacketSize) | 435 if (start_size + 16 > kMaxIpPacketSize) |
436 return; | 436 return; |
437 | 437 |
438 packet->resize(start_size + 16); | 438 packet->resize(start_size + 16); |
439 | 439 |
440 base::BigEndianWriter big_endian_writer( | 440 base::BigEndianWriter big_endian_writer( |
441 reinterpret_cast<char*>(&((*packet)[start_size])), 16); | 441 reinterpret_cast<char*>(&((*packet)[start_size])), 16); |
442 | 442 |
443 uint8 FMT = 1; | 443 uint8 FMT = 1; |
444 big_endian_writer.WriteU8(0x80 + FMT); | 444 big_endian_writer.WriteU8(0x80 + FMT); |
445 big_endian_writer.WriteU8(transport::kPacketTypeGenericRtpFeedback); | 445 big_endian_writer.WriteU8(kPacketTypeGenericRtpFeedback); |
446 big_endian_writer.WriteU8(0); | 446 big_endian_writer.WriteU8(0); |
447 size_t nack_size_pos = start_size + 3; | 447 size_t nack_size_pos = start_size + 3; |
448 big_endian_writer.WriteU8(3); | 448 big_endian_writer.WriteU8(3); |
449 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 449 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
450 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. | 450 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. |
451 | 451 |
452 // Build NACK bitmasks and write them to the Rtcp message. | 452 // Build NACK bitmasks and write them to the Rtcp message. |
453 // The nack list should be sorted and not contain duplicates. | 453 // The nack list should be sorted and not contain duplicates. |
454 size_t number_of_nack_fields = 0; | 454 size_t number_of_nack_fields = 0; |
455 size_t max_number_of_nack_fields = std::min<size_t>( | 455 size_t max_number_of_nack_fields = std::min<size_t>( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 size_t start_size = packet->size(); | 491 size_t start_size = packet->size(); |
492 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; | 492 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; |
493 if (start_size + 8 > kMaxIpPacketSize) | 493 if (start_size + 8 > kMaxIpPacketSize) |
494 return; | 494 return; |
495 | 495 |
496 packet->resize(start_size + 8); | 496 packet->resize(start_size + 8); |
497 | 497 |
498 base::BigEndianWriter big_endian_writer( | 498 base::BigEndianWriter big_endian_writer( |
499 reinterpret_cast<char*>(&((*packet)[start_size])), 8); | 499 reinterpret_cast<char*>(&((*packet)[start_size])), 8); |
500 big_endian_writer.WriteU8(0x80 + 1); | 500 big_endian_writer.WriteU8(0x80 + 1); |
501 big_endian_writer.WriteU8(transport::kPacketTypeBye); | 501 big_endian_writer.WriteU8(kPacketTypeBye); |
502 big_endian_writer.WriteU16(1); // Length. | 502 big_endian_writer.WriteU16(1); // Length. |
503 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 503 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
504 } | 504 } |
505 | 505 |
506 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, | 506 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, |
507 Packet* packet) const { | 507 Packet* packet) const { |
508 size_t start_size = packet->size(); | 508 size_t start_size = packet->size(); |
509 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 509 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
510 if (start_size + 20 > kMaxIpPacketSize) | 510 if (start_size + 20 > kMaxIpPacketSize) |
511 return; | 511 return; |
512 | 512 |
513 packet->resize(start_size + 20); | 513 packet->resize(start_size + 20); |
514 | 514 |
515 base::BigEndianWriter big_endian_writer( | 515 base::BigEndianWriter big_endian_writer( |
516 reinterpret_cast<char*>(&((*packet)[start_size])), 20); | 516 reinterpret_cast<char*>(&((*packet)[start_size])), 20); |
517 | 517 |
518 big_endian_writer.WriteU8(0x80); | 518 big_endian_writer.WriteU8(0x80); |
519 big_endian_writer.WriteU8(transport::kPacketTypeXr); | 519 big_endian_writer.WriteU8(kPacketTypeXr); |
520 big_endian_writer.WriteU16(4); // Length. | 520 big_endian_writer.WriteU16(4); // Length. |
521 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 521 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
522 big_endian_writer.WriteU8(4); // Add block type. | 522 big_endian_writer.WriteU8(4); // Add block type. |
523 big_endian_writer.WriteU8(0); // Add reserved. | 523 big_endian_writer.WriteU8(0); // Add reserved. |
524 big_endian_writer.WriteU16(2); // Block length. | 524 big_endian_writer.WriteU16(2); // Block length. |
525 | 525 |
526 // Add the media (received RTP) SSRC. | 526 // Add the media (received RTP) SSRC. |
527 big_endian_writer.WriteU32(rrtr->ntp_seconds); | 527 big_endian_writer.WriteU32(rrtr->ntp_seconds); |
528 big_endian_writer.WriteU32(rrtr->ntp_fraction); | 528 big_endian_writer.WriteU32(rrtr->ntp_fraction); |
529 } | 529 } |
530 | 530 |
531 void RtcpSender::BuildCast(const RtcpCastMessage* cast, | 531 void RtcpSender::BuildCast(const RtcpCastMessage* cast, |
532 base::TimeDelta target_delay, | 532 base::TimeDelta target_delay, |
533 Packet* packet) const { | 533 Packet* packet) const { |
534 size_t start_size = packet->size(); | 534 size_t start_size = packet->size(); |
535 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 535 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
536 if (start_size + 20 > kMaxIpPacketSize) | 536 if (start_size + 20 > kMaxIpPacketSize) |
537 return; | 537 return; |
538 | 538 |
539 packet->resize(start_size + 20); | 539 packet->resize(start_size + 20); |
540 | 540 |
541 base::BigEndianWriter big_endian_writer( | 541 base::BigEndianWriter big_endian_writer( |
542 reinterpret_cast<char*>(&((*packet)[start_size])), 20); | 542 reinterpret_cast<char*>(&((*packet)[start_size])), 20); |
543 uint8 FMT = 15; // Application layer feedback. | 543 uint8 FMT = 15; // Application layer feedback. |
544 big_endian_writer.WriteU8(0x80 + FMT); | 544 big_endian_writer.WriteU8(0x80 + FMT); |
545 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 545 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); |
546 big_endian_writer.WriteU8(0); | 546 big_endian_writer.WriteU8(0); |
547 size_t cast_size_pos = start_size + 3; // Save length position. | 547 size_t cast_size_pos = start_size + 3; // Save length position. |
548 big_endian_writer.WriteU8(4); | 548 big_endian_writer.WriteU8(4); |
549 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 549 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
550 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. | 550 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. |
551 big_endian_writer.WriteU32(kCast); | 551 big_endian_writer.WriteU32(kCast); |
552 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); | 552 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); |
553 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. | 553 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. |
554 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. | 554 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. |
555 DCHECK_LE(target_delay.InMilliseconds(), | 555 DCHECK_LE(target_delay.InMilliseconds(), |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 &number_of_frames, | 636 &number_of_frames, |
637 &total_number_of_messages_to_send, | 637 &total_number_of_messages_to_send, |
638 &rtcp_log_size)) { | 638 &rtcp_log_size)) { |
639 return; | 639 return; |
640 } | 640 } |
641 packet->resize(packet_start_size + rtcp_log_size); | 641 packet->resize(packet_start_size + rtcp_log_size); |
642 | 642 |
643 base::BigEndianWriter big_endian_writer( | 643 base::BigEndianWriter big_endian_writer( |
644 reinterpret_cast<char*>(&((*packet)[packet_start_size])), rtcp_log_size); | 644 reinterpret_cast<char*>(&((*packet)[packet_start_size])), rtcp_log_size); |
645 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); | 645 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); |
646 big_endian_writer.WriteU8(transport::kPacketTypeApplicationDefined); | 646 big_endian_writer.WriteU8(kPacketTypeApplicationDefined); |
647 big_endian_writer.WriteU16(static_cast<uint16>( | 647 big_endian_writer.WriteU16(static_cast<uint16>( |
648 2 + 2 * number_of_frames + total_number_of_messages_to_send)); | 648 2 + 2 * number_of_frames + total_number_of_messages_to_send)); |
649 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 649 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
650 big_endian_writer.WriteU32(kCast); | 650 big_endian_writer.WriteU32(kCast); |
651 | 651 |
652 while (!receiver_log_message.empty() && | 652 while (!receiver_log_message.empty() && |
653 total_number_of_messages_to_send > 0) { | 653 total_number_of_messages_to_send > 0) { |
654 RtcpReceiverFrameLogMessage& frame_log_messages( | 654 RtcpReceiverFrameLogMessage& frame_log_messages( |
655 receiver_log_message.front()); | 655 receiver_log_message.front()); |
656 | 656 |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 << "Not enough buffer space."; | 818 << "Not enough buffer space."; |
819 | 819 |
820 VLOG(3) << "number of frames: " << *number_of_frames; | 820 VLOG(3) << "number of frames: " << *number_of_frames; |
821 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; | 821 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; |
822 VLOG(3) << "rtcp log size: " << *rtcp_log_size; | 822 VLOG(3) << "rtcp log size: " << *rtcp_log_size; |
823 return *number_of_frames > 0; | 823 return *number_of_frames > 0; |
824 } | 824 } |
825 | 825 |
826 } // namespace cast | 826 } // namespace cast |
827 } // namespace media | 827 } // namespace media |
OLD | NEW |