OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/cast/rtcp/rtcp_sender.h" | 5 #include "media/cast/rtcp/rtcp_sender.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/big_endian.h" | 10 #include "base/big_endian.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 VLOG(3) << "number of frames: " << *number_of_frames; | 156 VLOG(3) << "number of frames: " << *number_of_frames; |
157 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; | 157 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; |
158 VLOG(3) << "rtcp log size: " << *rtcp_log_size; | 158 VLOG(3) << "rtcp log size: " << *rtcp_log_size; |
159 return *number_of_frames > 0; | 159 return *number_of_frames > 0; |
160 } | 160 } |
161 } // namespace | 161 } // namespace |
162 | 162 |
163 // TODO(mikhal): This is only used by the receiver. Consider renaming. | 163 // TODO(mikhal): This is only used by the receiver. Consider renaming. |
164 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment, | 164 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment, |
165 transport::PacedPacketSender* outgoing_transport, | 165 transport::PacedPacketSender* outgoing_transport, |
166 uint32 sending_ssrc, const std::string& c_name) | 166 uint32 sending_ssrc, |
| 167 const std::string& c_name) |
167 : ssrc_(sending_ssrc), | 168 : ssrc_(sending_ssrc), |
168 c_name_(c_name), | 169 c_name_(c_name), |
169 transport_(outgoing_transport), | 170 transport_(outgoing_transport), |
170 cast_environment_(cast_environment) { | 171 cast_environment_(cast_environment) { |
171 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; | 172 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; |
172 } | 173 } |
173 | 174 |
174 RtcpSender::~RtcpSender() {} | 175 RtcpSender::~RtcpSender() {} |
175 | 176 |
176 // static | 177 // static |
177 bool RtcpSender::IsReceiverEvent(const CastLoggingEvent& event) { | 178 bool RtcpSender::IsReceiverEvent(const CastLoggingEvent& event) { |
178 return ConvertEventTypeToWireFormat(event) != 0; | 179 return ConvertEventTypeToWireFormat(event) != 0; |
179 } | 180 } |
180 | 181 |
181 void RtcpSender::SendRtcpFromRtpReceiver( | 182 void RtcpSender::SendRtcpFromRtpReceiver( |
182 uint32 packet_type_flags, | 183 uint32 packet_type_flags, |
183 const transport::RtcpReportBlock* report_block, | 184 const transport::RtcpReportBlock* report_block, |
184 const RtcpReceiverReferenceTimeReport* rrtr, | 185 const RtcpReceiverReferenceTimeReport* rrtr, |
185 const RtcpCastMessage* cast_message, | 186 const RtcpCastMessage* cast_message, |
186 const ReceiverRtcpEventSubscriber* event_subscriber) { | 187 const ReceiverRtcpEventSubscriber* event_subscriber, |
187 if (packet_type_flags & kRtcpSr || packet_type_flags & kRtcpDlrr || | 188 uint16 target_delay_ms) { |
188 packet_type_flags & kRtcpSenderLog) { | 189 if (packet_type_flags & transport::kRtcpSr || |
| 190 packet_type_flags & transport::kRtcpDlrr || |
| 191 packet_type_flags & transport::kRtcpSenderLog) { |
189 NOTREACHED() << "Invalid argument"; | 192 NOTREACHED() << "Invalid argument"; |
190 } | 193 } |
191 if (packet_type_flags & kRtcpPli || packet_type_flags & kRtcpRpsi || | 194 if (packet_type_flags & transport::kRtcpPli || |
192 packet_type_flags & kRtcpRemb || packet_type_flags & kRtcpNack) { | 195 packet_type_flags & transport::kRtcpRpsi || |
| 196 packet_type_flags & transport::kRtcpRemb || |
| 197 packet_type_flags & transport::kRtcpNack) { |
193 // Implement these for webrtc interop. | 198 // Implement these for webrtc interop. |
194 NOTIMPLEMENTED(); | 199 NOTIMPLEMENTED(); |
195 } | 200 } |
196 Packet packet; | 201 Packet packet; |
197 packet.reserve(kMaxIpPacketSize); | 202 packet.reserve(kMaxIpPacketSize); |
198 | 203 |
199 if (packet_type_flags & kRtcpRr) { | 204 if (packet_type_flags & transport::kRtcpRr) { |
200 BuildRR(report_block, &packet); | 205 BuildRR(report_block, &packet); |
201 if (!c_name_.empty()) { | 206 if (!c_name_.empty()) { |
202 BuildSdec(&packet); | 207 BuildSdec(&packet); |
203 } | 208 } |
204 } | 209 } |
205 if (packet_type_flags & kRtcpBye) { | 210 if (packet_type_flags & transport::kRtcpBye) { |
206 BuildBye(&packet); | 211 BuildBye(&packet); |
207 } | 212 } |
208 if (packet_type_flags & kRtcpRrtr) { | 213 if (packet_type_flags & transport::kRtcpRrtr) { |
209 DCHECK(rrtr) << "Invalid argument"; | 214 DCHECK(rrtr) << "Invalid argument"; |
210 BuildRrtr(rrtr, &packet); | 215 BuildRrtr(rrtr, &packet); |
211 } | 216 } |
212 if (packet_type_flags & kRtcpCast) { | 217 if (packet_type_flags & transport::kRtcpCast) { |
213 DCHECK(cast_message) << "Invalid argument"; | 218 DCHECK(cast_message) << "Invalid argument"; |
214 BuildCast(cast_message, &packet); | 219 BuildCast(cast_message, target_delay_ms, &packet); |
215 } | 220 } |
216 if (packet_type_flags & kRtcpReceiverLog) { | 221 if (packet_type_flags & transport::kRtcpReceiverLog) { |
217 DCHECK(event_subscriber) << "Invalid argument"; | 222 DCHECK(event_subscriber) << "Invalid argument"; |
218 BuildReceiverLog(event_subscriber->get_rtcp_events(), &packet); | 223 BuildReceiverLog(event_subscriber->get_rtcp_events(), &packet); |
219 } | 224 } |
220 if (packet.empty()) return; // Sanity don't send empty packets. | 225 |
| 226 if (packet.empty()) |
| 227 return; // Sanity don't send empty packets. |
221 | 228 |
222 transport_->SendRtcpPacket(packet); | 229 transport_->SendRtcpPacket(packet); |
223 } | 230 } |
224 | 231 |
225 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, | 232 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, |
226 Packet* packet) const { | 233 Packet* packet) const { |
227 size_t start_size = packet->size(); | 234 size_t start_size = packet->size(); |
228 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; | 235 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; |
229 if (start_size + 32 > kMaxIpPacketSize) return; | 236 if (start_size + 32 > kMaxIpPacketSize) |
| 237 return; |
230 | 238 |
231 uint16 number_of_rows = (report_block) ? 7 : 1; | 239 uint16 number_of_rows = (report_block) ? 7 : 1; |
232 packet->resize(start_size + 8); | 240 packet->resize(start_size + 8); |
233 | 241 |
234 base::BigEndianWriter big_endian_writer( | 242 base::BigEndianWriter big_endian_writer( |
235 reinterpret_cast<char*>(&((*packet)[start_size])), 8); | 243 reinterpret_cast<char*>(&((*packet)[start_size])), 8); |
236 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); | 244 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); |
237 big_endian_writer.WriteU8(transport::kPacketTypeReceiverReport); | 245 big_endian_writer.WriteU8(transport::kPacketTypeReceiverReport); |
238 big_endian_writer.WriteU16(number_of_rows); | 246 big_endian_writer.WriteU16(number_of_rows); |
239 big_endian_writer.WriteU32(ssrc_); | 247 big_endian_writer.WriteU32(ssrc_); |
240 | 248 |
241 if (report_block) { | 249 if (report_block) { |
242 AddReportBlocks(*report_block, packet); // Adds 24 bytes. | 250 AddReportBlocks(*report_block, packet); // Adds 24 bytes. |
243 } | 251 } |
244 } | 252 } |
245 | 253 |
246 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, | 254 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, |
247 Packet* packet) const { | 255 Packet* packet) const { |
248 size_t start_size = packet->size(); | 256 size_t start_size = packet->size(); |
249 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 257 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
250 if (start_size + 24 > kMaxIpPacketSize) return; | 258 if (start_size + 24 > kMaxIpPacketSize) |
| 259 return; |
251 | 260 |
252 packet->resize(start_size + 24); | 261 packet->resize(start_size + 24); |
253 | 262 |
254 base::BigEndianWriter big_endian_writer( | 263 base::BigEndianWriter big_endian_writer( |
255 reinterpret_cast<char*>(&((*packet)[start_size])), 24); | 264 reinterpret_cast<char*>(&((*packet)[start_size])), 24); |
256 big_endian_writer.WriteU32(report_block.media_ssrc); | 265 big_endian_writer.WriteU32(report_block.media_ssrc); |
257 big_endian_writer.WriteU8(report_block.fraction_lost); | 266 big_endian_writer.WriteU8(report_block.fraction_lost); |
258 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); | 267 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16); |
259 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); | 268 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8); |
260 big_endian_writer.WriteU8(report_block.cumulative_lost); | 269 big_endian_writer.WriteU8(report_block.cumulative_lost); |
261 | 270 |
262 // Extended highest seq_no, contain the highest sequence number received. | 271 // Extended highest seq_no, contain the highest sequence number received. |
263 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); | 272 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); |
264 big_endian_writer.WriteU32(report_block.jitter); | 273 big_endian_writer.WriteU32(report_block.jitter); |
265 | 274 |
266 // Last SR timestamp; our NTP time when we received the last report. | 275 // Last SR timestamp; our NTP time when we received the last report. |
267 // This is the value that we read from the send report packet not when we | 276 // This is the value that we read from the send report packet not when we |
268 // received it. | 277 // received it. |
269 big_endian_writer.WriteU32(report_block.last_sr); | 278 big_endian_writer.WriteU32(report_block.last_sr); |
270 | 279 |
271 // Delay since last received report, time since we received the report. | 280 // Delay since last received report, time since we received the report. |
272 big_endian_writer.WriteU32(report_block.delay_since_last_sr); | 281 big_endian_writer.WriteU32(report_block.delay_since_last_sr); |
273 } | 282 } |
274 | 283 |
275 void RtcpSender::BuildSdec(Packet* packet) const { | 284 void RtcpSender::BuildSdec(Packet* packet) const { |
276 size_t start_size = packet->size(); | 285 size_t start_size = packet->size(); |
277 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize) | 286 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize) |
278 << "Not enough buffer space"; | 287 << "Not enough buffer space"; |
279 if (start_size + 12 > kMaxIpPacketSize) return; | 288 if (start_size + 12 > kMaxIpPacketSize) |
| 289 return; |
280 | 290 |
281 // SDES Source Description. | 291 // SDES Source Description. |
282 packet->resize(start_size + 10); | 292 packet->resize(start_size + 10); |
283 | 293 |
284 base::BigEndianWriter big_endian_writer( | 294 base::BigEndianWriter big_endian_writer( |
285 reinterpret_cast<char*>(&((*packet)[start_size])), 10); | 295 reinterpret_cast<char*>(&((*packet)[start_size])), 10); |
286 // We always need to add one SDES CNAME. | 296 // We always need to add one SDES CNAME. |
287 big_endian_writer.WriteU8(0x80 + 1); | 297 big_endian_writer.WriteU8(0x80 + 1); |
288 big_endian_writer.WriteU8(transport::kPacketTypeSdes); | 298 big_endian_writer.WriteU8(transport::kPacketTypeSdes); |
289 | 299 |
290 // Handle SDES length later on. | 300 // Handle SDES length later on. |
291 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; | 301 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; |
292 big_endian_writer.WriteU16(0); | 302 big_endian_writer.WriteU16(0); |
293 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 303 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
294 big_endian_writer.WriteU8(1); // CNAME = 1 | 304 big_endian_writer.WriteU8(1); // CNAME = 1 |
295 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); | 305 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); |
296 | 306 |
297 size_t sdes_length = 10 + c_name_.length(); | 307 size_t sdes_length = 10 + c_name_.length(); |
298 packet->insert(packet->end(), c_name_.c_str(), | 308 packet->insert( |
299 c_name_.c_str() + c_name_.length()); | 309 packet->end(), c_name_.c_str(), c_name_.c_str() + c_name_.length()); |
300 | 310 |
301 size_t padding = 0; | 311 size_t padding = 0; |
302 | 312 |
303 // We must have a zero field even if we have an even multiple of 4 bytes. | 313 // We must have a zero field even if we have an even multiple of 4 bytes. |
304 if ((packet->size() % 4) == 0) { | 314 if ((packet->size() % 4) == 0) { |
305 padding++; | 315 padding++; |
306 packet->push_back(0); | 316 packet->push_back(0); |
307 } | 317 } |
308 while ((packet->size() % 4) != 0) { | 318 while ((packet->size() % 4) != 0) { |
309 padding++; | 319 padding++; |
310 packet->push_back(0); | 320 packet->push_back(0); |
311 } | 321 } |
312 sdes_length += padding; | 322 sdes_length += padding; |
313 | 323 |
314 // In 32-bit words minus one and we don't count the header. | 324 // In 32-bit words minus one and we don't count the header. |
315 uint8 buffer_length = static_cast<uint8>((sdes_length / 4) - 1); | 325 uint8 buffer_length = static_cast<uint8>((sdes_length / 4) - 1); |
316 (*packet)[sdes_length_position] = buffer_length; | 326 (*packet)[sdes_length_position] = buffer_length; |
317 } | 327 } |
318 | 328 |
319 void RtcpSender::BuildPli(uint32 remote_ssrc, Packet* packet) const { | 329 void RtcpSender::BuildPli(uint32 remote_ssrc, Packet* packet) const { |
320 size_t start_size = packet->size(); | 330 size_t start_size = packet->size(); |
321 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; | 331 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; |
322 if (start_size + 12 > kMaxIpPacketSize) return; | 332 if (start_size + 12 > kMaxIpPacketSize) |
| 333 return; |
323 | 334 |
324 packet->resize(start_size + 12); | 335 packet->resize(start_size + 12); |
325 | 336 |
326 base::BigEndianWriter big_endian_writer( | 337 base::BigEndianWriter big_endian_writer( |
327 reinterpret_cast<char*>(&((*packet)[start_size])), 12); | 338 reinterpret_cast<char*>(&((*packet)[start_size])), 12); |
328 uint8 FMT = 1; // Picture loss indicator. | 339 uint8 FMT = 1; // Picture loss indicator. |
329 big_endian_writer.WriteU8(0x80 + FMT); | 340 big_endian_writer.WriteU8(0x80 + FMT); |
330 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 341 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
331 big_endian_writer.WriteU16(2); // Used fixed length of 2. | 342 big_endian_writer.WriteU16(2); // Used fixed length of 2. |
332 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 343 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
333 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. | 344 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. |
334 } | 345 } |
335 | 346 |
336 /* | 347 /* |
337 0 1 2 3 | 348 0 1 2 3 |
338 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 | 349 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 |
339 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 350 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
340 | PB |0| Payload Type| Native Rpsi bit string | | 351 | PB |0| Payload Type| Native Rpsi bit string | |
341 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 352 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
342 | defined per codec ... | Padding (0) | | 353 | defined per codec ... | Padding (0) | |
343 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 354 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
344 */ | 355 */ |
345 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { | 356 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { |
346 size_t start_size = packet->size(); | 357 size_t start_size = packet->size(); |
347 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 358 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
348 if (start_size + 24 > kMaxIpPacketSize) return; | 359 if (start_size + 24 > kMaxIpPacketSize) |
| 360 return; |
349 | 361 |
350 packet->resize(start_size + 24); | 362 packet->resize(start_size + 24); |
351 | 363 |
352 base::BigEndianWriter big_endian_writer( | 364 base::BigEndianWriter big_endian_writer( |
353 reinterpret_cast<char*>(&((*packet)[start_size])), 24); | 365 reinterpret_cast<char*>(&((*packet)[start_size])), 24); |
354 uint8 FMT = 3; // Reference Picture Selection Indication. | 366 uint8 FMT = 3; // Reference Picture Selection Indication. |
355 big_endian_writer.WriteU8(0x80 + FMT); | 367 big_endian_writer.WriteU8(0x80 + FMT); |
356 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 368 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
357 | 369 |
358 // Calculate length. | 370 // Calculate length. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 for (int j = 0; j < padding_bytes; ++j) { | 405 for (int j = 0; j < padding_bytes; ++j) { |
394 big_endian_writer.WriteU8(0); | 406 big_endian_writer.WriteU8(0); |
395 } | 407 } |
396 } | 408 } |
397 | 409 |
398 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, Packet* packet) const { | 410 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, Packet* packet) const { |
399 size_t start_size = packet->size(); | 411 size_t start_size = packet->size(); |
400 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); | 412 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); |
401 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize) | 413 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize) |
402 << "Not enough buffer space"; | 414 << "Not enough buffer space"; |
403 if (start_size + remb_size > kMaxIpPacketSize) return; | 415 if (start_size + remb_size > kMaxIpPacketSize) |
| 416 return; |
404 | 417 |
405 packet->resize(start_size + remb_size); | 418 packet->resize(start_size + remb_size); |
406 | 419 |
407 base::BigEndianWriter big_endian_writer( | 420 base::BigEndianWriter big_endian_writer( |
408 reinterpret_cast<char*>(&((*packet)[start_size])), remb_size); | 421 reinterpret_cast<char*>(&((*packet)[start_size])), remb_size); |
409 | 422 |
410 // Add application layer feedback. | 423 // Add application layer feedback. |
411 uint8 FMT = 15; | 424 uint8 FMT = 15; |
412 big_endian_writer.WriteU8(0x80 + FMT); | 425 big_endian_writer.WriteU8(0x80 + FMT); |
413 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 426 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
414 big_endian_writer.WriteU8(0); | 427 big_endian_writer.WriteU8(0); |
415 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); | 428 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); |
416 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 429 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
417 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. | 430 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. |
418 big_endian_writer.WriteU32(kRemb); | 431 big_endian_writer.WriteU32(kRemb); |
419 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); | 432 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); |
420 | 433 |
421 // 6 bit exponent and a 18 bit mantissa. | 434 // 6 bit exponent and a 18 bit mantissa. |
422 uint8 bitrate_exponent; | 435 uint8 bitrate_exponent; |
423 uint32 bitrate_mantissa; | 436 uint32 bitrate_mantissa; |
424 BitrateToRembExponentBitrate(remb->remb_bitrate, &bitrate_exponent, | 437 BitrateToRembExponentBitrate( |
425 &bitrate_mantissa); | 438 remb->remb_bitrate, &bitrate_exponent, &bitrate_mantissa); |
426 | 439 |
427 big_endian_writer.WriteU8(static_cast<uint8>( | 440 big_endian_writer.WriteU8(static_cast<uint8>( |
428 (bitrate_exponent << 2) + ((bitrate_mantissa >> 16) & 0x03))); | 441 (bitrate_exponent << 2) + ((bitrate_mantissa >> 16) & 0x03))); |
429 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa >> 8)); | 442 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa >> 8)); |
430 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa)); | 443 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa)); |
431 | 444 |
432 std::list<uint32>::const_iterator it = remb->remb_ssrcs.begin(); | 445 std::list<uint32>::const_iterator it = remb->remb_ssrcs.begin(); |
433 for (; it != remb->remb_ssrcs.end(); ++it) { | 446 for (; it != remb->remb_ssrcs.end(); ++it) { |
434 big_endian_writer.WriteU32(*it); | 447 big_endian_writer.WriteU32(*it); |
435 } | 448 } |
436 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); | 449 base::TimeTicks now = cast_environment_->Clock()->NowTicks(); |
437 cast_environment_->Logging()->InsertGenericEvent(now, kRembBitrate, | 450 cast_environment_->Logging()->InsertGenericEvent( |
438 remb->remb_bitrate); | 451 now, kRembBitrate, remb->remb_bitrate); |
439 } | 452 } |
440 | 453 |
441 void RtcpSender::BuildNack(const RtcpNackMessage* nack, Packet* packet) const { | 454 void RtcpSender::BuildNack(const RtcpNackMessage* nack, Packet* packet) const { |
442 size_t start_size = packet->size(); | 455 size_t start_size = packet->size(); |
443 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space"; | 456 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space"; |
444 if (start_size + 16 > kMaxIpPacketSize) return; | 457 if (start_size + 16 > kMaxIpPacketSize) |
| 458 return; |
445 | 459 |
446 packet->resize(start_size + 16); | 460 packet->resize(start_size + 16); |
447 | 461 |
448 base::BigEndianWriter big_endian_writer( | 462 base::BigEndianWriter big_endian_writer( |
449 reinterpret_cast<char*>(&((*packet)[start_size])), 16); | 463 reinterpret_cast<char*>(&((*packet)[start_size])), 16); |
450 | 464 |
451 uint8 FMT = 1; | 465 uint8 FMT = 1; |
452 big_endian_writer.WriteU8(0x80 + FMT); | 466 big_endian_writer.WriteU8(0x80 + FMT); |
453 big_endian_writer.WriteU8(transport::kPacketTypeGenericRtpFeedback); | 467 big_endian_writer.WriteU8(transport::kPacketTypeGenericRtpFeedback); |
454 big_endian_writer.WriteU8(0); | 468 big_endian_writer.WriteU8(0); |
(...skipping 19 matching lines...) Expand all Loading... |
474 if (shift >= 0 && shift <= 15) { | 488 if (shift >= 0 && shift <= 15) { |
475 bitmask |= (1 << shift); | 489 bitmask |= (1 << shift); |
476 ++it; | 490 ++it; |
477 } else { | 491 } else { |
478 break; | 492 break; |
479 } | 493 } |
480 } | 494 } |
481 // Write the sequence number and the bitmask to the packet. | 495 // Write the sequence number and the bitmask to the packet. |
482 start_size = packet->size(); | 496 start_size = packet->size(); |
483 DCHECK_LT(start_size + 4, kMaxIpPacketSize) << "Not enough buffer space"; | 497 DCHECK_LT(start_size + 4, kMaxIpPacketSize) << "Not enough buffer space"; |
484 if (start_size + 4 > kMaxIpPacketSize) return; | 498 if (start_size + 4 > kMaxIpPacketSize) |
| 499 return; |
485 | 500 |
486 packet->resize(start_size + 4); | 501 packet->resize(start_size + 4); |
487 base::BigEndianWriter big_endian_nack_writer( | 502 base::BigEndianWriter big_endian_nack_writer( |
488 reinterpret_cast<char*>(&((*packet)[start_size])), 4); | 503 reinterpret_cast<char*>(&((*packet)[start_size])), 4); |
489 big_endian_nack_writer.WriteU16(nack_sequence_number); | 504 big_endian_nack_writer.WriteU16(nack_sequence_number); |
490 big_endian_nack_writer.WriteU16(bitmask); | 505 big_endian_nack_writer.WriteU16(bitmask); |
491 number_of_nack_fields++; | 506 number_of_nack_fields++; |
492 } | 507 } |
493 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); | 508 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); |
494 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); | 509 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); |
495 } | 510 } |
496 | 511 |
497 void RtcpSender::BuildBye(Packet* packet) const { | 512 void RtcpSender::BuildBye(Packet* packet) const { |
498 size_t start_size = packet->size(); | 513 size_t start_size = packet->size(); |
499 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; | 514 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; |
500 if (start_size + 8 > kMaxIpPacketSize) return; | 515 if (start_size + 8 > kMaxIpPacketSize) |
| 516 return; |
501 | 517 |
502 packet->resize(start_size + 8); | 518 packet->resize(start_size + 8); |
503 | 519 |
504 base::BigEndianWriter big_endian_writer( | 520 base::BigEndianWriter big_endian_writer( |
505 reinterpret_cast<char*>(&((*packet)[start_size])), 8); | 521 reinterpret_cast<char*>(&((*packet)[start_size])), 8); |
506 big_endian_writer.WriteU8(0x80 + 1); | 522 big_endian_writer.WriteU8(0x80 + 1); |
507 big_endian_writer.WriteU8(transport::kPacketTypeBye); | 523 big_endian_writer.WriteU8(transport::kPacketTypeBye); |
508 big_endian_writer.WriteU16(1); // Length. | 524 big_endian_writer.WriteU16(1); // Length. |
509 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 525 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
510 } | 526 } |
511 | 527 |
512 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, | 528 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, |
513 Packet* packet) const { | 529 Packet* packet) const { |
514 size_t start_size = packet->size(); | 530 size_t start_size = packet->size(); |
515 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 531 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
516 if (start_size + 20 > kMaxIpPacketSize) return; | 532 if (start_size + 20 > kMaxIpPacketSize) |
| 533 return; |
517 | 534 |
518 packet->resize(start_size + 20); | 535 packet->resize(start_size + 20); |
519 | 536 |
520 base::BigEndianWriter big_endian_writer( | 537 base::BigEndianWriter big_endian_writer( |
521 reinterpret_cast<char*>(&((*packet)[start_size])), 20); | 538 reinterpret_cast<char*>(&((*packet)[start_size])), 20); |
522 | 539 |
523 big_endian_writer.WriteU8(0x80); | 540 big_endian_writer.WriteU8(0x80); |
524 big_endian_writer.WriteU8(transport::kPacketTypeXr); | 541 big_endian_writer.WriteU8(transport::kPacketTypeXr); |
525 big_endian_writer.WriteU16(4); // Length. | 542 big_endian_writer.WriteU16(4); // Length. |
526 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 543 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
527 big_endian_writer.WriteU8(4); // Add block type. | 544 big_endian_writer.WriteU8(4); // Add block type. |
528 big_endian_writer.WriteU8(0); // Add reserved. | 545 big_endian_writer.WriteU8(0); // Add reserved. |
529 big_endian_writer.WriteU16(2); // Block length. | 546 big_endian_writer.WriteU16(2); // Block length. |
530 | 547 |
531 // Add the media (received RTP) SSRC. | 548 // Add the media (received RTP) SSRC. |
532 big_endian_writer.WriteU32(rrtr->ntp_seconds); | 549 big_endian_writer.WriteU32(rrtr->ntp_seconds); |
533 big_endian_writer.WriteU32(rrtr->ntp_fraction); | 550 big_endian_writer.WriteU32(rrtr->ntp_fraction); |
534 } | 551 } |
535 | 552 |
536 void RtcpSender::BuildCast(const RtcpCastMessage* cast, Packet* packet) const { | 553 void RtcpSender::BuildCast(const RtcpCastMessage* cast, |
| 554 uint16 target_delay_ms, |
| 555 Packet* packet) const { |
537 size_t start_size = packet->size(); | 556 size_t start_size = packet->size(); |
538 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 557 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
539 if (start_size + 20 > kMaxIpPacketSize) return; | 558 if (start_size + 20 > kMaxIpPacketSize) |
| 559 return; |
540 | 560 |
541 packet->resize(start_size + 20); | 561 packet->resize(start_size + 20); |
542 | 562 |
543 base::BigEndianWriter big_endian_writer( | 563 base::BigEndianWriter big_endian_writer( |
544 reinterpret_cast<char*>(&((*packet)[start_size])), 20); | 564 reinterpret_cast<char*>(&((*packet)[start_size])), 20); |
545 uint8 FMT = 15; // Application layer feedback. | 565 uint8 FMT = 15; // Application layer feedback. |
546 big_endian_writer.WriteU8(0x80 + FMT); | 566 big_endian_writer.WriteU8(0x80 + FMT); |
547 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 567 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); |
548 big_endian_writer.WriteU8(0); | 568 big_endian_writer.WriteU8(0); |
549 size_t cast_size_pos = start_size + 3; // Save length position. | 569 size_t cast_size_pos = start_size + 3; // Save length position. |
550 big_endian_writer.WriteU8(4); | 570 big_endian_writer.WriteU8(4); |
551 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 571 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
552 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. | 572 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. |
553 big_endian_writer.WriteU32(kCast); | 573 big_endian_writer.WriteU32(kCast); |
554 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); | 574 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); |
555 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. | 575 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. |
556 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. | 576 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. |
557 big_endian_writer.WriteU8(0); // Reserved. | 577 big_endian_writer.WriteU16(target_delay_ms); |
558 big_endian_writer.WriteU8(0); // Reserved. | |
559 | 578 |
560 size_t number_of_loss_fields = 0; | 579 size_t number_of_loss_fields = 0; |
561 size_t max_number_of_loss_fields = std::min<size_t>( | 580 size_t max_number_of_loss_fields = std::min<size_t>( |
562 kRtcpMaxCastLossFields, (kMaxIpPacketSize - packet->size()) / 4); | 581 kRtcpMaxCastLossFields, (kMaxIpPacketSize - packet->size()) / 4); |
563 | 582 |
564 MissingFramesAndPacketsMap::const_iterator frame_it = | 583 MissingFramesAndPacketsMap::const_iterator frame_it = |
565 cast->missing_frames_and_packets_.begin(); | 584 cast->missing_frames_and_packets_.begin(); |
566 | 585 |
567 for (; frame_it != cast->missing_frames_and_packets_.end() && | 586 for (; frame_it != cast->missing_frames_and_packets_.end() && |
568 number_of_loss_fields < max_number_of_loss_fields; | 587 number_of_loss_fields < max_number_of_loss_fields; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 if (frame_log_messages.event_log_messages_.empty()) { | 721 if (frame_log_messages.event_log_messages_.empty()) { |
703 // We sent all messages on this frame; pop the frame header. | 722 // We sent all messages on this frame; pop the frame header. |
704 receiver_log_message.pop_front(); | 723 receiver_log_message.pop_front(); |
705 } | 724 } |
706 } | 725 } |
707 DCHECK_EQ(total_number_of_messages_to_send, 0); | 726 DCHECK_EQ(total_number_of_messages_to_send, 0); |
708 } | 727 } |
709 | 728 |
710 } // namespace cast | 729 } // namespace cast |
711 } // namespace media | 730 } // namespace media |
OLD | NEW |