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