| 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::kMaxIpPacketSize - start_size; | 71 size_t remaining_space = media::cast::kIpPacketSize - 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::kMaxIpPacketSize, | 117 DCHECK_GE(media::cast::kIpPacketSize, |
| 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(kMaxIpPacketSize); | 162 packet.reserve(kIpPacketSize); |
| 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, kMaxIpPacketSize) << "Not enough buffer space"; | 193 DCHECK_LT(start_size + 32, kIpPacketSize) << "Not enough buffer space"; |
| 194 if (start_size + 32 > kMaxIpPacketSize) return; | 194 if (start_size + 32 > kIpPacketSize) 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(transport::kPacketTypeReceiverReport); | 201 big_endian_writer.WriteU8(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, kMaxIpPacketSize) << "Not enough buffer space"; | 213 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; |
| 214 if (start_size + 24 > kMaxIpPacketSize) return; | 214 if (start_size + 24 > kIpPacketSize) 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(), kMaxIpPacketSize) | 240 DCHECK_LT(start_size + 12 + c_name_.length(), kIpPacketSize) |
| 241 << "Not enough buffer space"; | 241 << "Not enough buffer space"; |
| 242 if (start_size + 12 > kMaxIpPacketSize) return; | 242 if (start_size + 12 > kIpPacketSize) 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(transport::kPacketTypeSdes); | 250 big_endian_writer.WriteU8(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, kMaxIpPacketSize) << "Not enough buffer space"; | 284 DCHECK_LT(start_size + 12, kIpPacketSize) << "Not enough buffer space"; |
| 285 if (start_size + 12 > kMaxIpPacketSize) return; | 285 if (start_size + 12 > kIpPacketSize) 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(transport::kPacketTypePayloadSpecific); | 292 big_endian_writer.WriteU8(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, kMaxIpPacketSize) << "Not enough buffer space"; | 310 DCHECK_LT(start_size + 24, kIpPacketSize) << "Not enough buffer space"; |
| 311 if (start_size + 24 > kMaxIpPacketSize) return; | 311 if (start_size + 24 > kIpPacketSize) 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(transport::kPacketTypePayloadSpecific); | 318 big_endian_writer.WriteU8(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, kMaxIpPacketSize) | 364 DCHECK_LT(start_size + remb_size, kIpPacketSize) |
| 365 << "Not enough buffer space"; | 365 << "Not enough buffer space"; |
| 366 if (start_size + remb_size > kMaxIpPacketSize) return; | 366 if (start_size + remb_size > kIpPacketSize) 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(transport::kPacketTypePayloadSpecific); | 375 big_endian_writer.WriteU8(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, kMaxIpPacketSize) << "Not enough buffer space"; | 407 DCHECK_LT(start_size + 16, kIpPacketSize) << "Not enough buffer space"; |
| 408 if (start_size + 16 > kMaxIpPacketSize) return; | 408 if (start_size + 16 > kIpPacketSize) 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(transport::kPacketTypeGenericRtpFeedback); | 416 big_endian_writer.WriteU8(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 (kMaxIpPacketSize - packet->size()) / 4); | 427 (kIpPacketSize - 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, kMaxIpPacketSize) << "Not enough buffer space"; | 446 DCHECK_LT(start_size + 4, kIpPacketSize) << "Not enough buffer space"; |
| 447 if (start_size + 4 > kMaxIpPacketSize) return; | 447 if (start_size + 4 > kIpPacketSize) 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, kMaxIpPacketSize) << "Not enough buffer space"; | 461 DCHECK_LT(start_size + 8, kIpPacketSize) << "Not enough buffer space"; |
| 462 if (start_size + 8 > kMaxIpPacketSize) return; | 462 if (start_size + 8 > kIpPacketSize) 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(transport::kPacketTypeBye); | 468 big_endian_writer.WriteU8(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, kMaxIpPacketSize) << "Not enough buffer space"; | 476 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; |
| 477 if (start_size + 20 > kMaxIpPacketSize) return; | 477 if (start_size + 20 > kIpPacketSize) 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(transport::kPacketTypeXr); | 484 big_endian_writer.WriteU8(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, kMaxIpPacketSize) << "Not enough buffer space"; | 499 DCHECK_LT(start_size + 20, kIpPacketSize) << "Not enough buffer space"; |
| 500 if (start_size + 20 > kMaxIpPacketSize) return; | 500 if (start_size + 20 > kIpPacketSize) 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(transport::kPacketTypePayloadSpecific); | 507 big_endian_writer.WriteU8(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 (kMaxIpPacketSize - packet->size()) / 4); | 522 (kIpPacketSize - 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(transport::kPacketTypeApplicationDefined); | 594 big_endian_writer.WriteU8(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 |