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/logging.h" | 10 #include "base/logging.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 } | 58 } |
59 | 59 |
60 bool ScanRtcpReceiverLogMessage( | 60 bool ScanRtcpReceiverLogMessage( |
61 const media::cast::RtcpReceiverLogMessage& receiver_log_message, | 61 const media::cast::RtcpReceiverLogMessage& receiver_log_message, |
62 size_t start_size, | 62 size_t start_size, |
63 size_t* number_of_frames, | 63 size_t* number_of_frames, |
64 size_t* total_number_of_messages_to_send, | 64 size_t* total_number_of_messages_to_send, |
65 size_t* rtcp_log_size) { | 65 size_t* rtcp_log_size) { |
66 if (receiver_log_message.empty()) return false; | 66 if (receiver_log_message.empty()) return false; |
67 | 67 |
68 size_t remaining_space = media::cast::kIpPacketSize - start_size; | 68 size_t remaining_space = media::cast::kMaxIpPacketSize - start_size; |
69 | 69 |
70 // We must have space for at least one message | 70 // We must have space for at least one message |
71 DCHECK_GE(remaining_space, kRtcpCastLogHeaderSize + | 71 DCHECK_GE(remaining_space, kRtcpCastLogHeaderSize + |
72 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) | 72 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) |
73 << "Not enough buffer space"; | 73 << "Not enough buffer space"; |
74 | 74 |
75 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize + | 75 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize + |
76 kRtcpReceiverEventLogSize) { | 76 kRtcpReceiverEventLogSize) { |
77 return false; | 77 return false; |
78 } | 78 } |
(...skipping 25 matching lines...) Expand all Loading... |
104 | 104 |
105 if (remaining_space < | 105 if (remaining_space < |
106 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) { | 106 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) { |
107 // Make sure that we have room for at least one more message. | 107 // Make sure that we have room for at least one more message. |
108 break; | 108 break; |
109 } | 109 } |
110 } | 110 } |
111 *rtcp_log_size = kRtcpCastLogHeaderSize + | 111 *rtcp_log_size = kRtcpCastLogHeaderSize + |
112 *number_of_frames * kRtcpReceiverFrameLogSize + | 112 *number_of_frames * kRtcpReceiverFrameLogSize + |
113 *total_number_of_messages_to_send * kRtcpReceiverEventLogSize; | 113 *total_number_of_messages_to_send * kRtcpReceiverEventLogSize; |
114 DCHECK_GE(media::cast::kIpPacketSize, | 114 DCHECK_GE(media::cast::kMaxIpPacketSize, |
115 start_size + *rtcp_log_size) << "Not enough buffer space"; | 115 start_size + *rtcp_log_size) << "Not enough buffer space"; |
116 | 116 |
117 VLOG(1) << "number of frames " << *number_of_frames; | 117 VLOG(1) << "number of frames " << *number_of_frames; |
118 VLOG(1) << "total messages to send " << *total_number_of_messages_to_send; | 118 VLOG(1) << "total messages to send " << *total_number_of_messages_to_send; |
119 VLOG(1) << "rtcp log size " << *rtcp_log_size; | 119 VLOG(1) << "rtcp log size " << *rtcp_log_size; |
120 return true; | 120 return true; |
121 } | 121 } |
122 } // namespace | 122 } // namespace |
123 | 123 |
124 namespace media { | 124 namespace media { |
(...skipping 24 matching lines...) Expand all Loading... |
149 NOTREACHED() << "Invalid argument"; | 149 NOTREACHED() << "Invalid argument"; |
150 } | 150 } |
151 if (packet_type_flags & kRtcpPli || | 151 if (packet_type_flags & kRtcpPli || |
152 packet_type_flags & kRtcpRpsi || | 152 packet_type_flags & kRtcpRpsi || |
153 packet_type_flags & kRtcpRemb || | 153 packet_type_flags & kRtcpRemb || |
154 packet_type_flags & kRtcpNack) { | 154 packet_type_flags & kRtcpNack) { |
155 // Implement these for webrtc interop. | 155 // Implement these for webrtc interop. |
156 NOTIMPLEMENTED(); | 156 NOTIMPLEMENTED(); |
157 } | 157 } |
158 std::vector<uint8> packet; | 158 std::vector<uint8> packet; |
159 packet.reserve(kIpPacketSize); | 159 packet.reserve(kMaxIpPacketSize); |
160 | 160 |
161 if (packet_type_flags & kRtcpRr) { | 161 if (packet_type_flags & kRtcpRr) { |
162 BuildRR(report_block, &packet); | 162 BuildRR(report_block, &packet); |
163 if (!c_name_.empty()) { | 163 if (!c_name_.empty()) { |
164 BuildSdec(&packet); | 164 BuildSdec(&packet); |
165 } | 165 } |
166 } | 166 } |
167 if (packet_type_flags & kRtcpBye) { | 167 if (packet_type_flags & kRtcpBye) { |
168 BuildBye(&packet); | 168 BuildBye(&packet); |
169 } | 169 } |
(...skipping 10 matching lines...) Expand all Loading... |
180 BuildReceiverLog(receiver_log, &packet); | 180 BuildReceiverLog(receiver_log, &packet); |
181 } | 181 } |
182 if (packet.empty()) return; // Sanity don't send empty packets. | 182 if (packet.empty()) return; // Sanity don't send empty packets. |
183 | 183 |
184 transport_->SendRtcpPacket(packet); | 184 transport_->SendRtcpPacket(packet); |
185 } | 185 } |
186 | 186 |
187 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, | 187 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, |
188 std::vector<uint8>* packet) const { | 188 std::vector<uint8>* packet) const { |
189 size_t start_size = packet->size(); | 189 size_t start_size = packet->size(); |
190 DCHECK_LT(start_size + 32, kIpPacketSize) << "Not enough buffer space"; | 190 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; |
191 if (start_size + 32 > kIpPacketSize) 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 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); |
197 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); | 197 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); |
198 big_endian_writer.WriteU8(kPacketTypeReceiverReport); | 198 big_endian_writer.WriteU8(transport::kPacketTypeReceiverReport); |
199 big_endian_writer.WriteU16(number_of_rows); | 199 big_endian_writer.WriteU16(number_of_rows); |
200 big_endian_writer.WriteU32(ssrc_); | 200 big_endian_writer.WriteU32(ssrc_); |
201 | 201 |
202 if (report_block) { | 202 if (report_block) { |
203 AddReportBlocks(*report_block, packet); // Adds 24 bytes. | 203 AddReportBlocks(*report_block, packet); // Adds 24 bytes. |
204 } | 204 } |
205 } | 205 } |
206 | 206 |
207 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, | 207 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, |
208 std::vector<uint8>* packet) const { | 208 std::vector<uint8>* packet) const { |
209 size_t start_size = packet->size(); | 209 size_t start_size = packet->size(); |
210 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; | 210 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
211 if (start_size + 24 > kIpPacketSize) return; | 211 if (start_size + 24 > kMaxIpPacketSize) return; |
212 | 212 |
213 packet->resize(start_size + 24); | 213 packet->resize(start_size + 24); |
214 | 214 |
215 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); | 215 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); |
216 big_endian_writer.WriteU32(report_block.media_ssrc); | 216 big_endian_writer.WriteU32(report_block.media_ssrc); |
217 big_endian_writer.WriteU8(report_block.fraction_lost); | 217 big_endian_writer.WriteU8(report_block.fraction_lost); |
218 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); | 218 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); |
219 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); | 219 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); |
220 big_endian_writer.WriteU8(report_block.cumulative_lost); | 220 big_endian_writer.WriteU8(report_block.cumulative_lost); |
221 | 221 |
222 // Extended highest seq_no, contain the highest sequence number received. | 222 // Extended highest seq_no, contain the highest sequence number received. |
223 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); | 223 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); |
224 big_endian_writer.WriteU32(report_block.jitter); | 224 big_endian_writer.WriteU32(report_block.jitter); |
225 | 225 |
226 // Last SR timestamp; our NTP time when we received the last report. | 226 // 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 | 227 // This is the value that we read from the send report packet not when we |
228 // received it. | 228 // received it. |
229 big_endian_writer.WriteU32(report_block.last_sr); | 229 big_endian_writer.WriteU32(report_block.last_sr); |
230 | 230 |
231 // Delay since last received report, time since we received the report. | 231 // Delay since last received report, time since we received the report. |
232 big_endian_writer.WriteU32(report_block.delay_since_last_sr); | 232 big_endian_writer.WriteU32(report_block.delay_since_last_sr); |
233 } | 233 } |
234 | 234 |
235 void RtcpSender::BuildSdec(std::vector<uint8>* packet) const { | 235 void RtcpSender::BuildSdec(std::vector<uint8>* packet) const { |
236 size_t start_size = packet->size(); | 236 size_t start_size = packet->size(); |
237 DCHECK_LT(start_size + 12 + c_name_.length(), kIpPacketSize) | 237 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize) |
238 << "Not enough buffer space"; | 238 << "Not enough buffer space"; |
239 if (start_size + 12 > kIpPacketSize) return; | 239 if (start_size + 12 > kMaxIpPacketSize) return; |
240 | 240 |
241 // SDES Source Description. | 241 // SDES Source Description. |
242 packet->resize(start_size + 10); | 242 packet->resize(start_size + 10); |
243 | 243 |
244 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10); | 244 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 10); |
245 // We always need to add one SDES CNAME. | 245 // We always need to add one SDES CNAME. |
246 big_endian_writer.WriteU8(0x80 + 1); | 246 big_endian_writer.WriteU8(0x80 + 1); |
247 big_endian_writer.WriteU8(kPacketTypeSdes); | 247 big_endian_writer.WriteU8(transport::kPacketTypeSdes); |
248 | 248 |
249 // Handle SDES length later on. | 249 // Handle SDES length later on. |
250 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; | 250 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; |
251 big_endian_writer.WriteU16(0); | 251 big_endian_writer.WriteU16(0); |
252 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 252 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
253 big_endian_writer.WriteU8(1); // CNAME = 1 | 253 big_endian_writer.WriteU8(1); // CNAME = 1 |
254 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); | 254 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); |
255 | 255 |
256 size_t sdes_length = 10 + c_name_.length(); | 256 size_t sdes_length = 10 + c_name_.length(); |
257 packet->insert(packet->end(), c_name_.c_str(), | 257 packet->insert(packet->end(), c_name_.c_str(), |
(...skipping 13 matching lines...) Expand all Loading... |
271 sdes_length += padding; | 271 sdes_length += padding; |
272 | 272 |
273 // In 32-bit words minus one and we don't count the header. | 273 // In 32-bit words minus one and we don't count the header. |
274 uint8 buffer_length = static_cast<uint8>((sdes_length / 4) - 1); | 274 uint8 buffer_length = static_cast<uint8>((sdes_length / 4) - 1); |
275 (*packet)[sdes_length_position] = buffer_length; | 275 (*packet)[sdes_length_position] = buffer_length; |
276 } | 276 } |
277 | 277 |
278 void RtcpSender::BuildPli(uint32 remote_ssrc, | 278 void RtcpSender::BuildPli(uint32 remote_ssrc, |
279 std::vector<uint8>* packet) const { | 279 std::vector<uint8>* packet) const { |
280 size_t start_size = packet->size(); | 280 size_t start_size = packet->size(); |
281 DCHECK_LT(start_size + 12, kIpPacketSize) << "Not enough buffer space"; | 281 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; |
282 if (start_size + 12 > kIpPacketSize) return; | 282 if (start_size + 12 > kMaxIpPacketSize) return; |
283 | 283 |
284 packet->resize(start_size + 12); | 284 packet->resize(start_size + 12); |
285 | 285 |
286 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12); | 286 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 12); |
287 uint8 FMT = 1; // Picture loss indicator. | 287 uint8 FMT = 1; // Picture loss indicator. |
288 big_endian_writer.WriteU8(0x80 + FMT); | 288 big_endian_writer.WriteU8(0x80 + FMT); |
289 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); | 289 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
290 big_endian_writer.WriteU16(2); // Used fixed length of 2. | 290 big_endian_writer.WriteU16(2); // Used fixed length of 2. |
291 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 291 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
292 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. | 292 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. |
293 } | 293 } |
294 | 294 |
295 /* | 295 /* |
296 0 1 2 3 | 296 0 1 2 3 |
297 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 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 |
298 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 298 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
299 | PB |0| Payload Type| Native Rpsi bit string | | 299 | PB |0| Payload Type| Native Rpsi bit string | |
300 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 300 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
301 | defined per codec ... | Padding (0) | | 301 | defined per codec ... | Padding (0) | |
302 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 302 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
303 */ | 303 */ |
304 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, | 304 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, |
305 std::vector<uint8>* packet) const { | 305 std::vector<uint8>* packet) const { |
306 size_t start_size = packet->size(); | 306 size_t start_size = packet->size(); |
307 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; | 307 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
308 if (start_size + 24 > kIpPacketSize) return; | 308 if (start_size + 24 > kMaxIpPacketSize) return; |
309 | 309 |
310 packet->resize(start_size + 24); | 310 packet->resize(start_size + 24); |
311 | 311 |
312 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); | 312 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 24); |
313 uint8 FMT = 3; // Reference Picture Selection Indication. | 313 uint8 FMT = 3; // Reference Picture Selection Indication. |
314 big_endian_writer.WriteU8(0x80 + FMT); | 314 big_endian_writer.WriteU8(0x80 + FMT); |
315 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); | 315 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
316 | 316 |
317 // Calculate length. | 317 // Calculate length. |
318 uint32 bits_required = 7; | 318 uint32 bits_required = 7; |
319 uint8 bytes_required = 1; | 319 uint8 bytes_required = 1; |
320 while ((rpsi->picture_id >> bits_required) > 0) { | 320 while ((rpsi->picture_id >> bits_required) > 0) { |
321 bits_required += 7; | 321 bits_required += 7; |
322 bytes_required++; | 322 bytes_required++; |
323 } | 323 } |
324 uint8 size = 3; | 324 uint8 size = 3; |
325 if (bytes_required > 6) { | 325 if (bytes_required > 6) { |
(...skipping 25 matching lines...) Expand all Loading... |
351 // Add padding. | 351 // Add padding. |
352 for (int j = 0; j < padding_bytes; ++j) { | 352 for (int j = 0; j < padding_bytes; ++j) { |
353 big_endian_writer.WriteU8(0); | 353 big_endian_writer.WriteU8(0); |
354 } | 354 } |
355 } | 355 } |
356 | 356 |
357 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, | 357 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, |
358 std::vector<uint8>* packet) const { | 358 std::vector<uint8>* packet) const { |
359 size_t start_size = packet->size(); | 359 size_t start_size = packet->size(); |
360 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); | 360 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); |
361 DCHECK_LT(start_size + remb_size, kIpPacketSize) | 361 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize) |
362 << "Not enough buffer space"; | 362 << "Not enough buffer space"; |
363 if (start_size + remb_size > kIpPacketSize) return; | 363 if (start_size + remb_size > kMaxIpPacketSize) return; |
364 | 364 |
365 packet->resize(start_size + remb_size); | 365 packet->resize(start_size + remb_size); |
366 | 366 |
367 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size); | 367 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), remb_size); |
368 | 368 |
369 // Add application layer feedback. | 369 // Add application layer feedback. |
370 uint8 FMT = 15; | 370 uint8 FMT = 15; |
371 big_endian_writer.WriteU8(0x80 + FMT); | 371 big_endian_writer.WriteU8(0x80 + FMT); |
372 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); | 372 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
373 big_endian_writer.WriteU8(0); | 373 big_endian_writer.WriteU8(0); |
374 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); | 374 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); |
375 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 375 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
376 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. | 376 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. |
377 big_endian_writer.WriteU32(kRemb); | 377 big_endian_writer.WriteU32(kRemb); |
378 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); | 378 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); |
379 | 379 |
380 // 6 bit exponent and a 18 bit mantissa. | 380 // 6 bit exponent and a 18 bit mantissa. |
381 uint8 bitrate_exponent; | 381 uint8 bitrate_exponent; |
382 uint32 bitrate_mantissa; | 382 uint32 bitrate_mantissa; |
(...skipping 11 matching lines...) Expand all Loading... |
394 big_endian_writer.WriteU32(*it); | 394 big_endian_writer.WriteU32(*it); |
395 } | 395 } |
396 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 396 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
397 cast_environment_->Logging()->InsertGenericEvent(now, kRembBitrate, | 397 cast_environment_->Logging()->InsertGenericEvent(now, kRembBitrate, |
398 remb->remb_bitrate); | 398 remb->remb_bitrate); |
399 } | 399 } |
400 | 400 |
401 void RtcpSender::BuildNack(const RtcpNackMessage* nack, | 401 void RtcpSender::BuildNack(const RtcpNackMessage* nack, |
402 std::vector<uint8>* packet) const { | 402 std::vector<uint8>* packet) const { |
403 size_t start_size = packet->size(); | 403 size_t start_size = packet->size(); |
404 DCHECK_LT(start_size + 16, kIpPacketSize) << "Not enough buffer space"; | 404 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space"; |
405 if (start_size + 16 > kIpPacketSize) return; | 405 if (start_size + 16 > kMaxIpPacketSize) return; |
406 | 406 |
407 packet->resize(start_size + 16); | 407 packet->resize(start_size + 16); |
408 | 408 |
409 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16); | 409 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 16); |
410 | 410 |
411 uint8 FMT = 1; | 411 uint8 FMT = 1; |
412 big_endian_writer.WriteU8(0x80 + FMT); | 412 big_endian_writer.WriteU8(0x80 + FMT); |
413 big_endian_writer.WriteU8(kPacketTypeGenericRtpFeedback); | 413 big_endian_writer.WriteU8(transport::kPacketTypeGenericRtpFeedback); |
414 big_endian_writer.WriteU8(0); | 414 big_endian_writer.WriteU8(0); |
415 size_t nack_size_pos = start_size + 3; | 415 size_t nack_size_pos = start_size + 3; |
416 big_endian_writer.WriteU8(3); | 416 big_endian_writer.WriteU8(3); |
417 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 417 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
418 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. | 418 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. |
419 | 419 |
420 // Build NACK bitmasks and write them to the Rtcp message. | 420 // Build NACK bitmasks and write them to the Rtcp message. |
421 // The nack list should be sorted and not contain duplicates. | 421 // The nack list should be sorted and not contain duplicates. |
422 size_t number_of_nack_fields = 0; | 422 size_t number_of_nack_fields = 0; |
423 size_t max_number_of_nack_fields = std::min<size_t>(kRtcpMaxNackFields, | 423 size_t max_number_of_nack_fields = std::min<size_t>(kRtcpMaxNackFields, |
424 (kIpPacketSize - packet->size()) / 4); | 424 (kMaxIpPacketSize - packet->size()) / 4); |
425 | 425 |
426 std::list<uint16>::const_iterator it = nack->nack_list.begin(); | 426 std::list<uint16>::const_iterator it = nack->nack_list.begin(); |
427 while (it != nack->nack_list.end() && | 427 while (it != nack->nack_list.end() && |
428 number_of_nack_fields < max_number_of_nack_fields) { | 428 number_of_nack_fields < max_number_of_nack_fields) { |
429 uint16 nack_sequence_number = *it; | 429 uint16 nack_sequence_number = *it; |
430 uint16 bitmask = 0; | 430 uint16 bitmask = 0; |
431 ++it; | 431 ++it; |
432 while (it != nack->nack_list.end()) { | 432 while (it != nack->nack_list.end()) { |
433 int shift = static_cast<uint16>(*it - nack_sequence_number) - 1; | 433 int shift = static_cast<uint16>(*it - nack_sequence_number) - 1; |
434 if (shift >= 0 && shift <= 15) { | 434 if (shift >= 0 && shift <= 15) { |
435 bitmask |= (1 << shift); | 435 bitmask |= (1 << shift); |
436 ++it; | 436 ++it; |
437 } else { | 437 } else { |
438 break; | 438 break; |
439 } | 439 } |
440 } | 440 } |
441 // Write the sequence number and the bitmask to the packet. | 441 // Write the sequence number and the bitmask to the packet. |
442 start_size = packet->size(); | 442 start_size = packet->size(); |
443 DCHECK_LT(start_size + 4, kIpPacketSize) << "Not enough buffer space"; | 443 DCHECK_LT(start_size + 4, kMaxIpPacketSize) << "Not enough buffer space"; |
444 if (start_size + 4 > kIpPacketSize) return; | 444 if (start_size + 4 > kMaxIpPacketSize) return; |
445 | 445 |
446 packet->resize(start_size + 4); | 446 packet->resize(start_size + 4); |
447 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); | 447 net::BigEndianWriter big_endian_nack_writer(&((*packet)[start_size]), 4); |
448 big_endian_nack_writer.WriteU16(nack_sequence_number); | 448 big_endian_nack_writer.WriteU16(nack_sequence_number); |
449 big_endian_nack_writer.WriteU16(bitmask); | 449 big_endian_nack_writer.WriteU16(bitmask); |
450 number_of_nack_fields++; | 450 number_of_nack_fields++; |
451 } | 451 } |
452 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); | 452 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); |
453 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); | 453 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); |
454 } | 454 } |
455 | 455 |
456 void RtcpSender::BuildBye(std::vector<uint8>* packet) const { | 456 void RtcpSender::BuildBye(std::vector<uint8>* packet) const { |
457 size_t start_size = packet->size(); | 457 size_t start_size = packet->size(); |
458 DCHECK_LT(start_size + 8, kIpPacketSize) << "Not enough buffer space"; | 458 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; |
459 if (start_size + 8 > kIpPacketSize) return; | 459 if (start_size + 8 > kMaxIpPacketSize) return; |
460 | 460 |
461 packet->resize(start_size + 8); | 461 packet->resize(start_size + 8); |
462 | 462 |
463 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); | 463 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 8); |
464 big_endian_writer.WriteU8(0x80 + 1); | 464 big_endian_writer.WriteU8(0x80 + 1); |
465 big_endian_writer.WriteU8(kPacketTypeBye); | 465 big_endian_writer.WriteU8(transport::kPacketTypeBye); |
466 big_endian_writer.WriteU16(1); // Length. | 466 big_endian_writer.WriteU16(1); // Length. |
467 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 467 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
468 } | 468 } |
469 | 469 |
470 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, | 470 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, |
471 std::vector<uint8>* packet) const { | 471 std::vector<uint8>* packet) const { |
472 size_t start_size = packet->size(); | 472 size_t start_size = packet->size(); |
473 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; | 473 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
474 if (start_size + 20 > kIpPacketSize) return; | 474 if (start_size + 20 > kMaxIpPacketSize) return; |
475 | 475 |
476 packet->resize(start_size + 20); | 476 packet->resize(start_size + 20); |
477 | 477 |
478 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); | 478 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); |
479 | 479 |
480 big_endian_writer.WriteU8(0x80); | 480 big_endian_writer.WriteU8(0x80); |
481 big_endian_writer.WriteU8(kPacketTypeXr); | 481 big_endian_writer.WriteU8(transport::kPacketTypeXr); |
482 big_endian_writer.WriteU16(4); // Length. | 482 big_endian_writer.WriteU16(4); // Length. |
483 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 483 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
484 big_endian_writer.WriteU8(4); // Add block type. | 484 big_endian_writer.WriteU8(4); // Add block type. |
485 big_endian_writer.WriteU8(0); // Add reserved. | 485 big_endian_writer.WriteU8(0); // Add reserved. |
486 big_endian_writer.WriteU16(2); // Block length. | 486 big_endian_writer.WriteU16(2); // Block length. |
487 | 487 |
488 // Add the media (received RTP) SSRC. | 488 // Add the media (received RTP) SSRC. |
489 big_endian_writer.WriteU32(rrtr->ntp_seconds); | 489 big_endian_writer.WriteU32(rrtr->ntp_seconds); |
490 big_endian_writer.WriteU32(rrtr->ntp_fraction); | 490 big_endian_writer.WriteU32(rrtr->ntp_fraction); |
491 } | 491 } |
492 | 492 |
493 void RtcpSender::BuildCast(const RtcpCastMessage* cast, | 493 void RtcpSender::BuildCast(const RtcpCastMessage* cast, |
494 std::vector<uint8>* packet) const { | 494 std::vector<uint8>* packet) const { |
495 size_t start_size = packet->size(); | 495 size_t start_size = packet->size(); |
496 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; | 496 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
497 if (start_size + 20 > kIpPacketSize) return; | 497 if (start_size + 20 > kMaxIpPacketSize) return; |
498 | 498 |
499 packet->resize(start_size + 20); | 499 packet->resize(start_size + 20); |
500 | 500 |
501 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); | 501 net::BigEndianWriter big_endian_writer(&((*packet)[start_size]), 20); |
502 uint8 FMT = 15; // Application layer feedback. | 502 uint8 FMT = 15; // Application layer feedback. |
503 big_endian_writer.WriteU8(0x80 + FMT); | 503 big_endian_writer.WriteU8(0x80 + FMT); |
504 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); | 504 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
505 big_endian_writer.WriteU8(0); | 505 big_endian_writer.WriteU8(0); |
506 size_t cast_size_pos = start_size + 3; // Save length position. | 506 size_t cast_size_pos = start_size + 3; // Save length position. |
507 big_endian_writer.WriteU8(4); | 507 big_endian_writer.WriteU8(4); |
508 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 508 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
509 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. | 509 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. |
510 big_endian_writer.WriteU32(kCast); | 510 big_endian_writer.WriteU32(kCast); |
511 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); | 511 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); |
512 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. | 512 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. |
513 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. | 513 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. |
514 big_endian_writer.WriteU8(0); // Reserved. | 514 big_endian_writer.WriteU8(0); // Reserved. |
515 big_endian_writer.WriteU8(0); // Reserved. | 515 big_endian_writer.WriteU8(0); // Reserved. |
516 | 516 |
517 size_t number_of_loss_fields = 0; | 517 size_t number_of_loss_fields = 0; |
518 size_t max_number_of_loss_fields = std::min<size_t>(kRtcpMaxCastLossFields, | 518 size_t max_number_of_loss_fields = std::min<size_t>(kRtcpMaxCastLossFields, |
519 (kIpPacketSize - packet->size()) / 4); | 519 (kMaxIpPacketSize - packet->size()) / 4); |
520 | 520 |
521 MissingFramesAndPacketsMap::const_iterator frame_it = | 521 MissingFramesAndPacketsMap::const_iterator frame_it = |
522 cast->missing_frames_and_packets_.begin(); | 522 cast->missing_frames_and_packets_.begin(); |
523 | 523 |
524 for (; frame_it != cast->missing_frames_and_packets_.end() && | 524 for (; frame_it != cast->missing_frames_and_packets_.end() && |
525 number_of_loss_fields < max_number_of_loss_fields; ++frame_it) { | 525 number_of_loss_fields < max_number_of_loss_fields; ++frame_it) { |
526 // Iterate through all frames with missing packets. | 526 // Iterate through all frames with missing packets. |
527 if (frame_it->second.empty()) { | 527 if (frame_it->second.empty()) { |
528 // Special case all packets in a frame is missing. | 528 // Special case all packets in a frame is missing. |
529 start_size = packet->size(); | 529 start_size = packet->size(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 &number_of_frames, | 581 &number_of_frames, |
582 &total_number_of_messages_to_send, | 582 &total_number_of_messages_to_send, |
583 &rtcp_log_size)) { | 583 &rtcp_log_size)) { |
584 return; | 584 return; |
585 } | 585 } |
586 packet->resize(packet_start_size + rtcp_log_size); | 586 packet->resize(packet_start_size + rtcp_log_size); |
587 | 587 |
588 net::BigEndianWriter big_endian_writer(&((*packet)[packet_start_size]), | 588 net::BigEndianWriter big_endian_writer(&((*packet)[packet_start_size]), |
589 rtcp_log_size); | 589 rtcp_log_size); |
590 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); | 590 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); |
591 big_endian_writer.WriteU8(kPacketTypeApplicationDefined); | 591 big_endian_writer.WriteU8(transport::kPacketTypeApplicationDefined); |
592 big_endian_writer.WriteU16(static_cast<uint16>(2 + 2 * number_of_frames + | 592 big_endian_writer.WriteU16(static_cast<uint16>(2 + 2 * number_of_frames + |
593 total_number_of_messages_to_send)); | 593 total_number_of_messages_to_send)); |
594 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 594 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
595 big_endian_writer.WriteU32(kCast); | 595 big_endian_writer.WriteU32(kCast); |
596 | 596 |
597 while (!receiver_log_message->empty() && | 597 while (!receiver_log_message->empty() && |
598 total_number_of_messages_to_send > 0) { | 598 total_number_of_messages_to_send > 0) { |
599 RtcpReceiverFrameLogMessage& frame_log_messages = | 599 RtcpReceiverFrameLogMessage& frame_log_messages = |
600 receiver_log_message->front(); | 600 receiver_log_message->front(); |
601 // Add our frame header. | 601 // Add our frame header. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 if (frame_log_messages.event_log_messages_.empty()) { | 649 if (frame_log_messages.event_log_messages_.empty()) { |
650 // We sent all messages on this frame; pop the frame header. | 650 // We sent all messages on this frame; pop the frame header. |
651 receiver_log_message->pop_front(); | 651 receiver_log_message->pop_front(); |
652 } | 652 } |
653 } | 653 } |
654 DCHECK_EQ(total_number_of_messages_to_send, 0); | 654 DCHECK_EQ(total_number_of_messages_to_send, 0); |
655 } | 655 } |
656 | 656 |
657 } // namespace cast | 657 } // namespace cast |
658 } // namespace media | 658 } // namespace media |
OLD | NEW |