| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/net/rtcp/rtcp_sender.h" | 5 #include "media/cast/net/rtcp/rtcp_sender.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 std::ostringstream stream_; | 139 std::ostringstream stream_; |
| 140 int frame_count_; | 140 int frame_count_; |
| 141 int packet_count_; | 141 int packet_count_; |
| 142 int last_frame_id_; | 142 int last_frame_id_; |
| 143 int last_packet_id_; | 143 int last_packet_id_; |
| 144 bool contiguous_sequence_; | 144 bool contiguous_sequence_; |
| 145 }; | 145 }; |
| 146 } // namespace | 146 } // namespace |
| 147 | 147 |
| 148 RtcpSender::RtcpSender(PacedPacketSender* outgoing_transport, | 148 RtcpSender::RtcpSender(PacedPacketSender* outgoing_transport, |
| 149 uint32 sending_ssrc, | 149 uint32 sending_ssrc) |
| 150 const std::string& c_name) | |
| 151 : ssrc_(sending_ssrc), | 150 : ssrc_(sending_ssrc), |
| 152 c_name_(c_name), | |
| 153 transport_(outgoing_transport) { | 151 transport_(outgoing_transport) { |
| 154 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; | |
| 155 } | 152 } |
| 156 | 153 |
| 157 RtcpSender::~RtcpSender() {} | 154 RtcpSender::~RtcpSender() {} |
| 158 | 155 |
| 159 void RtcpSender::SendRtcpFromRtpReceiver( | 156 void RtcpSender::SendRtcpFromRtpReceiver( |
| 160 uint32 packet_type_flags, | 157 uint32 packet_type_flags, |
| 161 const RtcpReportBlock* report_block, | 158 const RtcpReportBlock* report_block, |
| 162 const RtcpReceiverReferenceTimeReport* rrtr, | 159 const RtcpReceiverReferenceTimeReport* rrtr, |
| 163 const RtcpCastMessage* cast_message, | 160 const RtcpCastMessage* cast_message, |
| 164 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, | 161 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, |
| 165 base::TimeDelta target_delay) { | 162 base::TimeDelta target_delay) { |
| 166 if (packet_type_flags & kRtcpSr || | 163 if (packet_type_flags & kRtcpDlrr) { |
| 167 packet_type_flags & kRtcpDlrr || | |
| 168 packet_type_flags & kRtcpSenderLog) { | |
| 169 NOTREACHED() << "Invalid argument"; | 164 NOTREACHED() << "Invalid argument"; |
| 170 } | 165 } |
| 171 if (packet_type_flags & kRtcpPli || | |
| 172 packet_type_flags & kRtcpRpsi || | |
| 173 packet_type_flags & kRtcpRemb || | |
| 174 packet_type_flags & kRtcpNack) { | |
| 175 // Implement these for webrtc interop. | |
| 176 NOTIMPLEMENTED(); | |
| 177 } | |
| 178 PacketRef packet(new base::RefCountedData<Packet>); | 166 PacketRef packet(new base::RefCountedData<Packet>); |
| 179 packet->data.reserve(kMaxIpPacketSize); | 167 packet->data.reserve(kMaxIpPacketSize); |
| 180 if (packet_type_flags & kRtcpRr) { | 168 if (packet_type_flags & kRtcpRr) { |
| 181 BuildRR(report_block, &packet->data); | 169 BuildRR(report_block, &packet->data); |
| 182 if (!c_name_.empty()) { | |
| 183 BuildSdec(&packet->data); | |
| 184 } | |
| 185 } | |
| 186 if (packet_type_flags & kRtcpBye) { | |
| 187 BuildBye(&packet->data); | |
| 188 } | 170 } |
| 189 if (packet_type_flags & kRtcpRrtr) { | 171 if (packet_type_flags & kRtcpRrtr) { |
| 190 DCHECK(rrtr) << "Invalid argument"; | 172 DCHECK(rrtr) << "Invalid argument"; |
| 191 BuildRrtr(rrtr, &packet->data); | 173 BuildRrtr(rrtr, &packet->data); |
| 192 } | 174 } |
| 193 if (packet_type_flags & kRtcpCast) { | 175 if (packet_type_flags & kRtcpCast) { |
| 194 DCHECK(cast_message) << "Invalid argument"; | 176 DCHECK(cast_message) << "Invalid argument"; |
| 195 BuildCast(cast_message, target_delay, &packet->data); | 177 BuildCast(cast_message, target_delay, &packet->data); |
| 196 } | 178 } |
| 197 if (packet_type_flags & kRtcpReceiverLog) { | 179 if (packet_type_flags & kRtcpReceiverLog) { |
| 198 DCHECK(rtcp_events) << "Invalid argument"; | 180 DCHECK(rtcp_events) << "Invalid argument"; |
| 199 BuildReceiverLog(*rtcp_events, &packet->data); | 181 BuildReceiverLog(*rtcp_events, &packet->data); |
| 200 } | 182 } |
| 201 | 183 |
| 202 if (packet->data.empty()) { | 184 if (packet->data.empty()) { |
| 203 NOTREACHED() << "Empty packet."; | 185 NOTREACHED() << "Empty packet."; |
| 204 return; // Sanity don't send empty packets. | 186 return; // Sanity don't send empty packets. |
| 205 } | 187 } |
| 206 | 188 |
| 207 transport_->SendRtcpPacket(ssrc_, packet); | 189 transport_->SendRtcpPacket(ssrc_, packet); |
| 208 } | 190 } |
| 209 | 191 |
| 210 void RtcpSender::SendRtcpFromRtpSender( | 192 void RtcpSender::SendRtcpFromRtpSender( |
| 211 uint32 packet_type_flags, | 193 uint32 packet_type_flags, |
| 212 const RtcpSenderInfo& sender_info, | 194 const RtcpSenderInfo& sender_info, |
| 213 const RtcpDlrrReportBlock& dlrr) { | 195 const RtcpDlrrReportBlock& dlrr) { |
| 214 if (packet_type_flags & kRtcpRr || | 196 if (packet_type_flags & kRtcpRr || |
| 215 packet_type_flags & kRtcpPli || | |
| 216 packet_type_flags & kRtcpRrtr || | 197 packet_type_flags & kRtcpRrtr || |
| 217 packet_type_flags & kRtcpCast || | 198 packet_type_flags & kRtcpCast || |
| 218 packet_type_flags & kRtcpReceiverLog || | 199 packet_type_flags & kRtcpReceiverLog) { |
| 219 packet_type_flags & kRtcpRpsi || | |
| 220 packet_type_flags & kRtcpRemb || | |
| 221 packet_type_flags & kRtcpNack) { | |
| 222 NOTREACHED() << "Invalid argument"; | 200 NOTREACHED() << "Invalid argument"; |
| 223 } | 201 } |
| 224 PacketRef packet(new base::RefCountedData<Packet>); | 202 PacketRef packet(new base::RefCountedData<Packet>); |
| 225 packet->data.reserve(kMaxIpPacketSize); | 203 packet->data.reserve(kMaxIpPacketSize); |
| 226 if (packet_type_flags & kRtcpSr) { | 204 if (packet_type_flags & kRtcpSr) { |
| 227 BuildSR(sender_info, &packet->data); | 205 BuildSR(sender_info, &packet->data); |
| 228 BuildSdec(&packet->data); | |
| 229 } | |
| 230 if (packet_type_flags & kRtcpBye) { | |
| 231 BuildBye(&packet->data); | |
| 232 } | 206 } |
| 233 if (packet_type_flags & kRtcpDlrr) { | 207 if (packet_type_flags & kRtcpDlrr) { |
| 234 BuildDlrrRb(dlrr, &packet->data); | 208 BuildDlrrRb(dlrr, &packet->data); |
| 235 } | 209 } |
| 236 if (packet->data.empty()) { | 210 if (packet->data.empty()) { |
| 237 NOTREACHED() << "Empty packet."; | 211 NOTREACHED() << "Empty packet."; |
| 238 return; // Sanity - don't send empty packets. | 212 return; // Sanity - don't send empty packets. |
| 239 } | 213 } |
| 240 | 214 |
| 241 transport_->SendRtcpPacket(ssrc_, packet); | 215 transport_->SendRtcpPacket(ssrc_, packet); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 | 260 |
| 287 // Last SR timestamp; our NTP time when we received the last report. | 261 // Last SR timestamp; our NTP time when we received the last report. |
| 288 // This is the value that we read from the send report packet not when we | 262 // This is the value that we read from the send report packet not when we |
| 289 // received it. | 263 // received it. |
| 290 big_endian_writer.WriteU32(report_block.last_sr); | 264 big_endian_writer.WriteU32(report_block.last_sr); |
| 291 | 265 |
| 292 // Delay since last received report, time since we received the report. | 266 // Delay since last received report, time since we received the report. |
| 293 big_endian_writer.WriteU32(report_block.delay_since_last_sr); | 267 big_endian_writer.WriteU32(report_block.delay_since_last_sr); |
| 294 } | 268 } |
| 295 | 269 |
| 296 void RtcpSender::BuildSdec(Packet* packet) const { | |
| 297 size_t start_size = packet->size(); | |
| 298 DCHECK_LT(start_size + 12 + c_name_.length(), kMaxIpPacketSize) | |
| 299 << "Not enough buffer space"; | |
| 300 if (start_size + 12 > kMaxIpPacketSize) | |
| 301 return; | |
| 302 | |
| 303 // SDES Source Description. | |
| 304 packet->resize(start_size + 10); | |
| 305 | |
| 306 base::BigEndianWriter big_endian_writer( | |
| 307 reinterpret_cast<char*>(&((*packet)[start_size])), 10); | |
| 308 // We always need to add one SDES CNAME. | |
| 309 big_endian_writer.WriteU8(0x80 + 1); | |
| 310 big_endian_writer.WriteU8(kPacketTypeSdes); | |
| 311 | |
| 312 // Handle SDES length later on. | |
| 313 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; | |
| 314 big_endian_writer.WriteU16(0); | |
| 315 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | |
| 316 big_endian_writer.WriteU8(1); // CNAME = 1 | |
| 317 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); | |
| 318 | |
| 319 size_t sdes_length = 10 + c_name_.length(); | |
| 320 packet->insert( | |
| 321 packet->end(), c_name_.c_str(), c_name_.c_str() + c_name_.length()); | |
| 322 | |
| 323 size_t padding = 0; | |
| 324 | |
| 325 // We must have a zero field even if we have an even multiple of 4 bytes. | |
| 326 if ((packet->size() % 4) == 0) { | |
| 327 padding++; | |
| 328 packet->push_back(0); | |
| 329 } | |
| 330 while ((packet->size() % 4) != 0) { | |
| 331 padding++; | |
| 332 packet->push_back(0); | |
| 333 } | |
| 334 sdes_length += padding; | |
| 335 | |
| 336 // In 32-bit words minus one and we don't count the header. | |
| 337 uint8 buffer_length = static_cast<uint8>((sdes_length / 4) - 1); | |
| 338 (*packet)[sdes_length_position] = buffer_length; | |
| 339 } | |
| 340 | |
| 341 void RtcpSender::BuildPli(uint32 remote_ssrc, Packet* packet) const { | |
| 342 size_t start_size = packet->size(); | |
| 343 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; | |
| 344 if (start_size + 12 > kMaxIpPacketSize) | |
| 345 return; | |
| 346 | |
| 347 packet->resize(start_size + 12); | |
| 348 | |
| 349 base::BigEndianWriter big_endian_writer( | |
| 350 reinterpret_cast<char*>(&((*packet)[start_size])), 12); | |
| 351 uint8 FMT = 1; // Picture loss indicator. | |
| 352 big_endian_writer.WriteU8(0x80 + FMT); | |
| 353 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); | |
| 354 big_endian_writer.WriteU16(2); // Used fixed length of 2. | |
| 355 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | |
| 356 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. | |
| 357 } | |
| 358 | |
| 359 /* | |
| 360 0 1 2 3 | |
| 361 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 | |
| 362 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 363 | PB |0| Payload Type| Native Rpsi bit string | | |
| 364 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 365 | defined per codec ... | Padding (0) | | |
| 366 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 367 */ | |
| 368 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, | |
| 369 Packet* packet) const { | |
| 370 size_t start_size = packet->size(); | |
| 371 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | |
| 372 if (start_size + 24 > kMaxIpPacketSize) | |
| 373 return; | |
| 374 | |
| 375 packet->resize(start_size + 24); | |
| 376 | |
| 377 base::BigEndianWriter big_endian_writer( | |
| 378 reinterpret_cast<char*>(&((*packet)[start_size])), 24); | |
| 379 uint8 FMT = 3; // Reference Picture Selection Indication. | |
| 380 big_endian_writer.WriteU8(0x80 + FMT); | |
| 381 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); | |
| 382 | |
| 383 // Calculate length. | |
| 384 uint32 bits_required = 7; | |
| 385 uint8 bytes_required = 1; | |
| 386 while ((rpsi->picture_id >> bits_required) > 0) { | |
| 387 bits_required += 7; | |
| 388 bytes_required++; | |
| 389 } | |
| 390 uint8 size = 3; | |
| 391 if (bytes_required > 6) { | |
| 392 size = 5; | |
| 393 } else if (bytes_required > 2) { | |
| 394 size = 4; | |
| 395 } | |
| 396 big_endian_writer.WriteU8(0); | |
| 397 big_endian_writer.WriteU8(size); | |
| 398 big_endian_writer.WriteU32(ssrc_); | |
| 399 big_endian_writer.WriteU32(rpsi->remote_ssrc); | |
| 400 | |
| 401 uint8 padding_bytes = 4 - ((2 + bytes_required) % 4); | |
| 402 if (padding_bytes == 4) { | |
| 403 padding_bytes = 0; | |
| 404 } | |
| 405 // Add padding length in bits, padding can be 0, 8, 16 or 24. | |
| 406 big_endian_writer.WriteU8(padding_bytes * 8); | |
| 407 big_endian_writer.WriteU8(rpsi->payload_type); | |
| 408 | |
| 409 // Add picture ID. | |
| 410 for (int i = bytes_required - 1; i > 0; i--) { | |
| 411 big_endian_writer.WriteU8(0x80 | | |
| 412 static_cast<uint8>(rpsi->picture_id >> (i * 7))); | |
| 413 } | |
| 414 // Add last byte of picture ID. | |
| 415 big_endian_writer.WriteU8(static_cast<uint8>(rpsi->picture_id & 0x7f)); | |
| 416 | |
| 417 // Add padding. | |
| 418 for (int j = 0; j < padding_bytes; ++j) { | |
| 419 big_endian_writer.WriteU8(0); | |
| 420 } | |
| 421 } | |
| 422 | |
| 423 void RtcpSender::BuildRemb(const RtcpRembMessage* remb, | |
| 424 Packet* packet) const { | |
| 425 size_t start_size = packet->size(); | |
| 426 size_t remb_size = 20 + 4 * remb->remb_ssrcs.size(); | |
| 427 DCHECK_LT(start_size + remb_size, kMaxIpPacketSize) | |
| 428 << "Not enough buffer space"; | |
| 429 if (start_size + remb_size > kMaxIpPacketSize) | |
| 430 return; | |
| 431 | |
| 432 packet->resize(start_size + remb_size); | |
| 433 | |
| 434 base::BigEndianWriter big_endian_writer( | |
| 435 reinterpret_cast<char*>(&((*packet)[start_size])), remb_size); | |
| 436 | |
| 437 // Add application layer feedback. | |
| 438 uint8 FMT = 15; | |
| 439 big_endian_writer.WriteU8(0x80 + FMT); | |
| 440 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); | |
| 441 big_endian_writer.WriteU8(0); | |
| 442 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); | |
| 443 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | |
| 444 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. | |
| 445 big_endian_writer.WriteU32(kRemb); | |
| 446 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); | |
| 447 | |
| 448 // 6 bit exponent and a 18 bit mantissa. | |
| 449 uint8 bitrate_exponent; | |
| 450 uint32 bitrate_mantissa; | |
| 451 BitrateToRembExponentBitrate( | |
| 452 remb->remb_bitrate, &bitrate_exponent, &bitrate_mantissa); | |
| 453 | |
| 454 big_endian_writer.WriteU8(static_cast<uint8>( | |
| 455 (bitrate_exponent << 2) + ((bitrate_mantissa >> 16) & 0x03))); | |
| 456 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa >> 8)); | |
| 457 big_endian_writer.WriteU8(static_cast<uint8>(bitrate_mantissa)); | |
| 458 | |
| 459 std::list<uint32>::const_iterator it = remb->remb_ssrcs.begin(); | |
| 460 for (; it != remb->remb_ssrcs.end(); ++it) { | |
| 461 big_endian_writer.WriteU32(*it); | |
| 462 } | |
| 463 } | |
| 464 | |
| 465 void RtcpSender::BuildNack(const RtcpNackMessage* nack, | |
| 466 Packet* packet) const { | |
| 467 size_t start_size = packet->size(); | |
| 468 DCHECK_LT(start_size + 16, kMaxIpPacketSize) << "Not enough buffer space"; | |
| 469 if (start_size + 16 > kMaxIpPacketSize) | |
| 470 return; | |
| 471 | |
| 472 packet->resize(start_size + 16); | |
| 473 | |
| 474 base::BigEndianWriter big_endian_writer( | |
| 475 reinterpret_cast<char*>(&((*packet)[start_size])), 16); | |
| 476 | |
| 477 uint8 FMT = 1; | |
| 478 big_endian_writer.WriteU8(0x80 + FMT); | |
| 479 big_endian_writer.WriteU8(kPacketTypeGenericRtpFeedback); | |
| 480 big_endian_writer.WriteU8(0); | |
| 481 size_t nack_size_pos = start_size + 3; | |
| 482 big_endian_writer.WriteU8(3); | |
| 483 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | |
| 484 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. | |
| 485 | |
| 486 // Build NACK bitmasks and write them to the Rtcp message. | |
| 487 // The nack list should be sorted and not contain duplicates. | |
| 488 size_t number_of_nack_fields = 0; | |
| 489 size_t max_number_of_nack_fields = std::min<size_t>( | |
| 490 kRtcpMaxNackFields, (kMaxIpPacketSize - packet->size()) / 4); | |
| 491 | |
| 492 std::list<uint16>::const_iterator it = nack->nack_list.begin(); | |
| 493 while (it != nack->nack_list.end() && | |
| 494 number_of_nack_fields < max_number_of_nack_fields) { | |
| 495 uint16 nack_sequence_number = *it; | |
| 496 uint16 bitmask = 0; | |
| 497 ++it; | |
| 498 while (it != nack->nack_list.end()) { | |
| 499 int shift = static_cast<uint16>(*it - nack_sequence_number) - 1; | |
| 500 if (shift >= 0 && shift <= 15) { | |
| 501 bitmask |= (1 << shift); | |
| 502 ++it; | |
| 503 } else { | |
| 504 break; | |
| 505 } | |
| 506 } | |
| 507 // Write the sequence number and the bitmask to the packet. | |
| 508 start_size = packet->size(); | |
| 509 DCHECK_LT(start_size + 4, kMaxIpPacketSize) << "Not enough buffer space"; | |
| 510 if (start_size + 4 > kMaxIpPacketSize) | |
| 511 return; | |
| 512 | |
| 513 packet->resize(start_size + 4); | |
| 514 base::BigEndianWriter big_endian_nack_writer( | |
| 515 reinterpret_cast<char*>(&((*packet)[start_size])), 4); | |
| 516 big_endian_nack_writer.WriteU16(nack_sequence_number); | |
| 517 big_endian_nack_writer.WriteU16(bitmask); | |
| 518 number_of_nack_fields++; | |
| 519 } | |
| 520 DCHECK_GE(kRtcpMaxNackFields, number_of_nack_fields); | |
| 521 (*packet)[nack_size_pos] = static_cast<uint8>(2 + number_of_nack_fields); | |
| 522 } | |
| 523 | |
| 524 void RtcpSender::BuildBye(Packet* packet) const { | |
| 525 size_t start_size = packet->size(); | |
| 526 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; | |
| 527 if (start_size + 8 > kMaxIpPacketSize) | |
| 528 return; | |
| 529 | |
| 530 packet->resize(start_size + 8); | |
| 531 | |
| 532 base::BigEndianWriter big_endian_writer( | |
| 533 reinterpret_cast<char*>(&((*packet)[start_size])), 8); | |
| 534 big_endian_writer.WriteU8(0x80 + 1); | |
| 535 big_endian_writer.WriteU8(kPacketTypeBye); | |
| 536 big_endian_writer.WriteU16(1); // Length. | |
| 537 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | |
| 538 } | |
| 539 | |
| 540 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, | 270 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, |
| 541 Packet* packet) const { | 271 Packet* packet) const { |
| 542 size_t start_size = packet->size(); | 272 size_t start_size = packet->size(); |
| 543 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 273 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
| 544 if (start_size + 20 > kMaxIpPacketSize) | 274 if (start_size + 20 > kMaxIpPacketSize) |
| 545 return; | 275 return; |
| 546 | 276 |
| 547 packet->resize(start_size + 20); | 277 packet->resize(start_size + 20); |
| 548 | 278 |
| 549 base::BigEndianWriter big_endian_writer( | 279 base::BigEndianWriter big_endian_writer( |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 << "Not enough buffer space."; | 650 << "Not enough buffer space."; |
| 921 | 651 |
| 922 VLOG(3) << "number of frames: " << *number_of_frames; | 652 VLOG(3) << "number of frames: " << *number_of_frames; |
| 923 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; | 653 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; |
| 924 VLOG(3) << "rtcp log size: " << *rtcp_log_size; | 654 VLOG(3) << "rtcp log size: " << *rtcp_log_size; |
| 925 return *number_of_frames > 0; | 655 return *number_of_frames > 0; |
| 926 } | 656 } |
| 927 | 657 |
| 928 } // namespace cast | 658 } // namespace cast |
| 929 } // namespace media | 659 } // namespace media |
| OLD | NEW |