| 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/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> |
| 11 | 11 |
| 12 #include "base/big_endian.h" | 12 #include "base/big_endian.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "media/cast/cast_environment.h" | 14 #include "media/cast/cast_environment.h" |
| 15 #include "media/cast/rtcp/rtcp_defines.h" | 15 #include "media/cast/net/cast_transport_defines.h" |
| 16 #include "media/cast/rtcp/rtcp_utility.h" | 16 #include "media/cast/net/pacing/paced_sender.h" |
| 17 #include "media/cast/transport/cast_transport_defines.h" | 17 #include "media/cast/net/rtcp/rtcp_defines.h" |
| 18 #include "media/cast/transport/pacing/paced_sender.h" | 18 #include "media/cast/net/rtcp/rtcp_utility.h" |
| 19 | 19 |
| 20 namespace media { | 20 namespace media { |
| 21 namespace cast { | 21 namespace cast { |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 // Max delta is 4095 milliseconds because we need to be able to encode it in | 24 // Max delta is 4095 milliseconds because we need to be able to encode it in |
| 25 // 12 bits. | 25 // 12 bits. |
| 26 const int64 kMaxWireFormatTimeDeltaMs = INT64_C(0xfff); | 26 const int64 kMaxWireFormatTimeDeltaMs = INT64_C(0xfff); |
| 27 | 27 |
| 28 uint16 MergeEventTypeAndTimestampForWireFormat( | 28 uint16 MergeEventTypeAndTimestampForWireFormat( |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 int frame_count_; | 141 int frame_count_; |
| 142 int packet_count_; | 142 int packet_count_; |
| 143 int last_frame_id_; | 143 int last_frame_id_; |
| 144 int last_packet_id_; | 144 int last_packet_id_; |
| 145 bool contiguous_sequence_; | 145 bool contiguous_sequence_; |
| 146 }; | 146 }; |
| 147 } // namespace | 147 } // namespace |
| 148 | 148 |
| 149 // TODO(mikhal): This is only used by the receiver. Consider renaming. | 149 // TODO(mikhal): This is only used by the receiver. Consider renaming. |
| 150 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment, | 150 RtcpSender::RtcpSender(scoped_refptr<CastEnvironment> cast_environment, |
| 151 transport::PacedPacketSender* outgoing_transport, | 151 PacedPacketSender* outgoing_transport, |
| 152 uint32 sending_ssrc, | 152 uint32 sending_ssrc, |
| 153 const std::string& c_name) | 153 const std::string& c_name) |
| 154 : ssrc_(sending_ssrc), | 154 : ssrc_(sending_ssrc), |
| 155 c_name_(c_name), | 155 c_name_(c_name), |
| 156 transport_(outgoing_transport), | 156 transport_(outgoing_transport), |
| 157 cast_environment_(cast_environment) { | 157 cast_environment_(cast_environment) { |
| 158 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; | 158 DCHECK_LT(c_name_.length(), kRtcpCnameSize) << "Invalid config"; |
| 159 } | 159 } |
| 160 | 160 |
| 161 RtcpSender::~RtcpSender() {} | 161 RtcpSender::~RtcpSender() {} |
| 162 | 162 |
| 163 void RtcpSender::SendRtcpFromRtpReceiver( | 163 void RtcpSender::SendRtcpFromRtpReceiver( |
| 164 uint32 packet_type_flags, | 164 uint32 packet_type_flags, |
| 165 const transport::RtcpReportBlock* report_block, | 165 const RtcpReportBlock* report_block, |
| 166 const RtcpReceiverReferenceTimeReport* rrtr, | 166 const RtcpReceiverReferenceTimeReport* rrtr, |
| 167 const RtcpCastMessage* cast_message, | 167 const RtcpCastMessage* cast_message, |
| 168 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, | 168 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, |
| 169 base::TimeDelta target_delay) { | 169 base::TimeDelta target_delay) { |
| 170 if (packet_type_flags & transport::kRtcpSr || | 170 if (packet_type_flags & kRtcpSr || |
| 171 packet_type_flags & transport::kRtcpDlrr || | 171 packet_type_flags & kRtcpDlrr || |
| 172 packet_type_flags & transport::kRtcpSenderLog) { | 172 packet_type_flags & kRtcpSenderLog) { |
| 173 NOTREACHED() << "Invalid argument"; | 173 NOTREACHED() << "Invalid argument"; |
| 174 } | 174 } |
| 175 if (packet_type_flags & transport::kRtcpPli || | 175 if (packet_type_flags & kRtcpPli || |
| 176 packet_type_flags & transport::kRtcpRpsi || | 176 packet_type_flags & kRtcpRpsi || |
| 177 packet_type_flags & transport::kRtcpRemb || | 177 packet_type_flags & kRtcpRemb || |
| 178 packet_type_flags & transport::kRtcpNack) { | 178 packet_type_flags & kRtcpNack) { |
| 179 // Implement these for webrtc interop. | 179 // Implement these for webrtc interop. |
| 180 NOTIMPLEMENTED(); | 180 NOTIMPLEMENTED(); |
| 181 } | 181 } |
| 182 transport::PacketRef packet(new base::RefCountedData<Packet>); | 182 PacketRef packet(new base::RefCountedData<Packet>); |
| 183 packet->data.reserve(kMaxIpPacketSize); | 183 packet->data.reserve(kMaxIpPacketSize); |
| 184 | 184 |
| 185 if (packet_type_flags & transport::kRtcpRr) { | 185 if (packet_type_flags & kRtcpRr) { |
| 186 BuildRR(report_block, &packet->data); | 186 BuildRR(report_block, &packet->data); |
| 187 if (!c_name_.empty()) { | 187 if (!c_name_.empty()) { |
| 188 BuildSdec(&packet->data); | 188 BuildSdec(&packet->data); |
| 189 } | 189 } |
| 190 } | 190 } |
| 191 if (packet_type_flags & transport::kRtcpBye) { | 191 if (packet_type_flags & kRtcpBye) { |
| 192 BuildBye(&packet->data); | 192 BuildBye(&packet->data); |
| 193 } | 193 } |
| 194 if (packet_type_flags & transport::kRtcpRrtr) { | 194 if (packet_type_flags & kRtcpRrtr) { |
| 195 DCHECK(rrtr) << "Invalid argument"; | 195 DCHECK(rrtr) << "Invalid argument"; |
| 196 BuildRrtr(rrtr, &packet->data); | 196 BuildRrtr(rrtr, &packet->data); |
| 197 } | 197 } |
| 198 if (packet_type_flags & transport::kRtcpCast) { | 198 if (packet_type_flags & kRtcpCast) { |
| 199 DCHECK(cast_message) << "Invalid argument"; | 199 DCHECK(cast_message) << "Invalid argument"; |
| 200 BuildCast(cast_message, target_delay, &packet->data); | 200 BuildCast(cast_message, target_delay, &packet->data); |
| 201 } | 201 } |
| 202 if (packet_type_flags & transport::kRtcpReceiverLog) { | 202 if (packet_type_flags & kRtcpReceiverLog) { |
| 203 DCHECK(rtcp_events) << "Invalid argument"; | 203 DCHECK(rtcp_events) << "Invalid argument"; |
| 204 BuildReceiverLog(*rtcp_events, &packet->data); | 204 BuildReceiverLog(*rtcp_events, &packet->data); |
| 205 } | 205 } |
| 206 | 206 |
| 207 if (packet->data.empty()) | 207 if (packet->data.empty()) |
| 208 return; // Sanity don't send empty packets. | 208 return; // Sanity don't send empty packets. |
| 209 | 209 |
| 210 transport_->SendRtcpPacket(ssrc_, packet); | 210 transport_->SendRtcpPacket(ssrc_, packet); |
| 211 } | 211 } |
| 212 | 212 |
| 213 void RtcpSender::BuildRR(const transport::RtcpReportBlock* report_block, | 213 void RtcpSender::BuildRR(const RtcpReportBlock* report_block, |
| 214 Packet* packet) const { | 214 Packet* packet) const { |
| 215 size_t start_size = packet->size(); | 215 size_t start_size = packet->size(); |
| 216 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; | 216 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space"; |
| 217 if (start_size + 32 > kMaxIpPacketSize) | 217 if (start_size + 32 > kMaxIpPacketSize) |
| 218 return; | 218 return; |
| 219 | 219 |
| 220 uint16 number_of_rows = (report_block) ? 7 : 1; | 220 uint16 number_of_rows = (report_block) ? 7 : 1; |
| 221 packet->resize(start_size + 8); | 221 packet->resize(start_size + 8); |
| 222 | 222 |
| 223 base::BigEndianWriter big_endian_writer( | 223 base::BigEndianWriter big_endian_writer( |
| 224 reinterpret_cast<char*>(&((*packet)[start_size])), 8); | 224 reinterpret_cast<char*>(&((*packet)[start_size])), 8); |
| 225 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); | 225 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0)); |
| 226 big_endian_writer.WriteU8(transport::kPacketTypeReceiverReport); | 226 big_endian_writer.WriteU8(kPacketTypeReceiverReport); |
| 227 big_endian_writer.WriteU16(number_of_rows); | 227 big_endian_writer.WriteU16(number_of_rows); |
| 228 big_endian_writer.WriteU32(ssrc_); | 228 big_endian_writer.WriteU32(ssrc_); |
| 229 | 229 |
| 230 if (report_block) { | 230 if (report_block) { |
| 231 AddReportBlocks(*report_block, packet); // Adds 24 bytes. | 231 AddReportBlocks(*report_block, packet); // Adds 24 bytes. |
| 232 } | 232 } |
| 233 } | 233 } |
| 234 | 234 |
| 235 void RtcpSender::AddReportBlocks(const transport::RtcpReportBlock& report_block, | 235 void RtcpSender::AddReportBlocks(const RtcpReportBlock& report_block, |
| 236 Packet* packet) const { | 236 Packet* packet) const { |
| 237 size_t start_size = packet->size(); | 237 size_t start_size = packet->size(); |
| 238 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 238 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
| 239 if (start_size + 24 > kMaxIpPacketSize) | 239 if (start_size + 24 > kMaxIpPacketSize) |
| 240 return; | 240 return; |
| 241 | 241 |
| 242 packet->resize(start_size + 24); | 242 packet->resize(start_size + 24); |
| 243 | 243 |
| 244 base::BigEndianWriter big_endian_writer( | 244 base::BigEndianWriter big_endian_writer( |
| 245 reinterpret_cast<char*>(&((*packet)[start_size])), 24); | 245 reinterpret_cast<char*>(&((*packet)[start_size])), 24); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 269 if (start_size + 12 > kMaxIpPacketSize) | 269 if (start_size + 12 > kMaxIpPacketSize) |
| 270 return; | 270 return; |
| 271 | 271 |
| 272 // SDES Source Description. | 272 // SDES Source Description. |
| 273 packet->resize(start_size + 10); | 273 packet->resize(start_size + 10); |
| 274 | 274 |
| 275 base::BigEndianWriter big_endian_writer( | 275 base::BigEndianWriter big_endian_writer( |
| 276 reinterpret_cast<char*>(&((*packet)[start_size])), 10); | 276 reinterpret_cast<char*>(&((*packet)[start_size])), 10); |
| 277 // We always need to add one SDES CNAME. | 277 // We always need to add one SDES CNAME. |
| 278 big_endian_writer.WriteU8(0x80 + 1); | 278 big_endian_writer.WriteU8(0x80 + 1); |
| 279 big_endian_writer.WriteU8(transport::kPacketTypeSdes); | 279 big_endian_writer.WriteU8(kPacketTypeSdes); |
| 280 | 280 |
| 281 // Handle SDES length later on. | 281 // Handle SDES length later on. |
| 282 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; | 282 uint32 sdes_length_position = static_cast<uint32>(start_size) + 3; |
| 283 big_endian_writer.WriteU16(0); | 283 big_endian_writer.WriteU16(0); |
| 284 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 284 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 285 big_endian_writer.WriteU8(1); // CNAME = 1 | 285 big_endian_writer.WriteU8(1); // CNAME = 1 |
| 286 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); | 286 big_endian_writer.WriteU8(static_cast<uint8>(c_name_.length())); |
| 287 | 287 |
| 288 size_t sdes_length = 10 + c_name_.length(); | 288 size_t sdes_length = 10 + c_name_.length(); |
| 289 packet->insert( | 289 packet->insert( |
| (...skipping 22 matching lines...) Expand all Loading... |
| 312 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; | 312 DCHECK_LT(start_size + 12, kMaxIpPacketSize) << "Not enough buffer space"; |
| 313 if (start_size + 12 > kMaxIpPacketSize) | 313 if (start_size + 12 > kMaxIpPacketSize) |
| 314 return; | 314 return; |
| 315 | 315 |
| 316 packet->resize(start_size + 12); | 316 packet->resize(start_size + 12); |
| 317 | 317 |
| 318 base::BigEndianWriter big_endian_writer( | 318 base::BigEndianWriter big_endian_writer( |
| 319 reinterpret_cast<char*>(&((*packet)[start_size])), 12); | 319 reinterpret_cast<char*>(&((*packet)[start_size])), 12); |
| 320 uint8 FMT = 1; // Picture loss indicator. | 320 uint8 FMT = 1; // Picture loss indicator. |
| 321 big_endian_writer.WriteU8(0x80 + FMT); | 321 big_endian_writer.WriteU8(0x80 + FMT); |
| 322 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 322 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); |
| 323 big_endian_writer.WriteU16(2); // Used fixed length of 2. | 323 big_endian_writer.WriteU16(2); // Used fixed length of 2. |
| 324 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 324 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 325 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. | 325 big_endian_writer.WriteU32(remote_ssrc); // Add the remote SSRC. |
| 326 } | 326 } |
| 327 | 327 |
| 328 /* | 328 /* |
| 329 0 1 2 3 | 329 0 1 2 3 |
| 330 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 | 330 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 |
| 331 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 331 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 332 | PB |0| Payload Type| Native Rpsi bit string | | 332 | PB |0| Payload Type| Native Rpsi bit string | |
| 333 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 333 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 334 | defined per codec ... | Padding (0) | | 334 | defined per codec ... | Padding (0) | |
| 335 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 335 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 336 */ | 336 */ |
| 337 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { | 337 void RtcpSender::BuildRpsi(const RtcpRpsiMessage* rpsi, Packet* packet) const { |
| 338 size_t start_size = packet->size(); | 338 size_t start_size = packet->size(); |
| 339 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; | 339 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; |
| 340 if (start_size + 24 > kMaxIpPacketSize) | 340 if (start_size + 24 > kMaxIpPacketSize) |
| 341 return; | 341 return; |
| 342 | 342 |
| 343 packet->resize(start_size + 24); | 343 packet->resize(start_size + 24); |
| 344 | 344 |
| 345 base::BigEndianWriter big_endian_writer( | 345 base::BigEndianWriter big_endian_writer( |
| 346 reinterpret_cast<char*>(&((*packet)[start_size])), 24); | 346 reinterpret_cast<char*>(&((*packet)[start_size])), 24); |
| 347 uint8 FMT = 3; // Reference Picture Selection Indication. | 347 uint8 FMT = 3; // Reference Picture Selection Indication. |
| 348 big_endian_writer.WriteU8(0x80 + FMT); | 348 big_endian_writer.WriteU8(0x80 + FMT); |
| 349 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 349 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); |
| 350 | 350 |
| 351 // Calculate length. | 351 // Calculate length. |
| 352 uint32 bits_required = 7; | 352 uint32 bits_required = 7; |
| 353 uint8 bytes_required = 1; | 353 uint8 bytes_required = 1; |
| 354 while ((rpsi->picture_id >> bits_required) > 0) { | 354 while ((rpsi->picture_id >> bits_required) > 0) { |
| 355 bits_required += 7; | 355 bits_required += 7; |
| 356 bytes_required++; | 356 bytes_required++; |
| 357 } | 357 } |
| 358 uint8 size = 3; | 358 uint8 size = 3; |
| 359 if (bytes_required > 6) { | 359 if (bytes_required > 6) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 return; | 397 return; |
| 398 | 398 |
| 399 packet->resize(start_size + remb_size); | 399 packet->resize(start_size + remb_size); |
| 400 | 400 |
| 401 base::BigEndianWriter big_endian_writer( | 401 base::BigEndianWriter big_endian_writer( |
| 402 reinterpret_cast<char*>(&((*packet)[start_size])), remb_size); | 402 reinterpret_cast<char*>(&((*packet)[start_size])), remb_size); |
| 403 | 403 |
| 404 // Add application layer feedback. | 404 // Add application layer feedback. |
| 405 uint8 FMT = 15; | 405 uint8 FMT = 15; |
| 406 big_endian_writer.WriteU8(0x80 + FMT); | 406 big_endian_writer.WriteU8(0x80 + FMT); |
| 407 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 407 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); |
| 408 big_endian_writer.WriteU8(0); | 408 big_endian_writer.WriteU8(0); |
| 409 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); | 409 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size() + 4)); |
| 410 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 410 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 411 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. | 411 big_endian_writer.WriteU32(0); // Remote SSRC must be 0. |
| 412 big_endian_writer.WriteU32(kRemb); | 412 big_endian_writer.WriteU32(kRemb); |
| 413 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); | 413 big_endian_writer.WriteU8(static_cast<uint8>(remb->remb_ssrcs.size())); |
| 414 | 414 |
| 415 // 6 bit exponent and a 18 bit mantissa. | 415 // 6 bit exponent and a 18 bit mantissa. |
| 416 uint8 bitrate_exponent; | 416 uint8 bitrate_exponent; |
| 417 uint32 bitrate_mantissa; | 417 uint32 bitrate_mantissa; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 435 if (start_size + 16 > kMaxIpPacketSize) | 435 if (start_size + 16 > kMaxIpPacketSize) |
| 436 return; | 436 return; |
| 437 | 437 |
| 438 packet->resize(start_size + 16); | 438 packet->resize(start_size + 16); |
| 439 | 439 |
| 440 base::BigEndianWriter big_endian_writer( | 440 base::BigEndianWriter big_endian_writer( |
| 441 reinterpret_cast<char*>(&((*packet)[start_size])), 16); | 441 reinterpret_cast<char*>(&((*packet)[start_size])), 16); |
| 442 | 442 |
| 443 uint8 FMT = 1; | 443 uint8 FMT = 1; |
| 444 big_endian_writer.WriteU8(0x80 + FMT); | 444 big_endian_writer.WriteU8(0x80 + FMT); |
| 445 big_endian_writer.WriteU8(transport::kPacketTypeGenericRtpFeedback); | 445 big_endian_writer.WriteU8(kPacketTypeGenericRtpFeedback); |
| 446 big_endian_writer.WriteU8(0); | 446 big_endian_writer.WriteU8(0); |
| 447 size_t nack_size_pos = start_size + 3; | 447 size_t nack_size_pos = start_size + 3; |
| 448 big_endian_writer.WriteU8(3); | 448 big_endian_writer.WriteU8(3); |
| 449 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 449 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 450 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. | 450 big_endian_writer.WriteU32(nack->remote_ssrc); // Add the remote SSRC. |
| 451 | 451 |
| 452 // Build NACK bitmasks and write them to the Rtcp message. | 452 // Build NACK bitmasks and write them to the Rtcp message. |
| 453 // The nack list should be sorted and not contain duplicates. | 453 // The nack list should be sorted and not contain duplicates. |
| 454 size_t number_of_nack_fields = 0; | 454 size_t number_of_nack_fields = 0; |
| 455 size_t max_number_of_nack_fields = std::min<size_t>( | 455 size_t max_number_of_nack_fields = std::min<size_t>( |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 size_t start_size = packet->size(); | 491 size_t start_size = packet->size(); |
| 492 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; | 492 DCHECK_LT(start_size + 8, kMaxIpPacketSize) << "Not enough buffer space"; |
| 493 if (start_size + 8 > kMaxIpPacketSize) | 493 if (start_size + 8 > kMaxIpPacketSize) |
| 494 return; | 494 return; |
| 495 | 495 |
| 496 packet->resize(start_size + 8); | 496 packet->resize(start_size + 8); |
| 497 | 497 |
| 498 base::BigEndianWriter big_endian_writer( | 498 base::BigEndianWriter big_endian_writer( |
| 499 reinterpret_cast<char*>(&((*packet)[start_size])), 8); | 499 reinterpret_cast<char*>(&((*packet)[start_size])), 8); |
| 500 big_endian_writer.WriteU8(0x80 + 1); | 500 big_endian_writer.WriteU8(0x80 + 1); |
| 501 big_endian_writer.WriteU8(transport::kPacketTypeBye); | 501 big_endian_writer.WriteU8(kPacketTypeBye); |
| 502 big_endian_writer.WriteU16(1); // Length. | 502 big_endian_writer.WriteU16(1); // Length. |
| 503 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 503 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 504 } | 504 } |
| 505 | 505 |
| 506 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, | 506 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, |
| 507 Packet* packet) const { | 507 Packet* packet) const { |
| 508 size_t start_size = packet->size(); | 508 size_t start_size = packet->size(); |
| 509 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 509 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
| 510 if (start_size + 20 > kMaxIpPacketSize) | 510 if (start_size + 20 > kMaxIpPacketSize) |
| 511 return; | 511 return; |
| 512 | 512 |
| 513 packet->resize(start_size + 20); | 513 packet->resize(start_size + 20); |
| 514 | 514 |
| 515 base::BigEndianWriter big_endian_writer( | 515 base::BigEndianWriter big_endian_writer( |
| 516 reinterpret_cast<char*>(&((*packet)[start_size])), 20); | 516 reinterpret_cast<char*>(&((*packet)[start_size])), 20); |
| 517 | 517 |
| 518 big_endian_writer.WriteU8(0x80); | 518 big_endian_writer.WriteU8(0x80); |
| 519 big_endian_writer.WriteU8(transport::kPacketTypeXr); | 519 big_endian_writer.WriteU8(kPacketTypeXr); |
| 520 big_endian_writer.WriteU16(4); // Length. | 520 big_endian_writer.WriteU16(4); // Length. |
| 521 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 521 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 522 big_endian_writer.WriteU8(4); // Add block type. | 522 big_endian_writer.WriteU8(4); // Add block type. |
| 523 big_endian_writer.WriteU8(0); // Add reserved. | 523 big_endian_writer.WriteU8(0); // Add reserved. |
| 524 big_endian_writer.WriteU16(2); // Block length. | 524 big_endian_writer.WriteU16(2); // Block length. |
| 525 | 525 |
| 526 // Add the media (received RTP) SSRC. | 526 // Add the media (received RTP) SSRC. |
| 527 big_endian_writer.WriteU32(rrtr->ntp_seconds); | 527 big_endian_writer.WriteU32(rrtr->ntp_seconds); |
| 528 big_endian_writer.WriteU32(rrtr->ntp_fraction); | 528 big_endian_writer.WriteU32(rrtr->ntp_fraction); |
| 529 } | 529 } |
| 530 | 530 |
| 531 void RtcpSender::BuildCast(const RtcpCastMessage* cast, | 531 void RtcpSender::BuildCast(const RtcpCastMessage* cast, |
| 532 base::TimeDelta target_delay, | 532 base::TimeDelta target_delay, |
| 533 Packet* packet) const { | 533 Packet* packet) const { |
| 534 size_t start_size = packet->size(); | 534 size_t start_size = packet->size(); |
| 535 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; | 535 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; |
| 536 if (start_size + 20 > kMaxIpPacketSize) | 536 if (start_size + 20 > kMaxIpPacketSize) |
| 537 return; | 537 return; |
| 538 | 538 |
| 539 packet->resize(start_size + 20); | 539 packet->resize(start_size + 20); |
| 540 | 540 |
| 541 base::BigEndianWriter big_endian_writer( | 541 base::BigEndianWriter big_endian_writer( |
| 542 reinterpret_cast<char*>(&((*packet)[start_size])), 20); | 542 reinterpret_cast<char*>(&((*packet)[start_size])), 20); |
| 543 uint8 FMT = 15; // Application layer feedback. | 543 uint8 FMT = 15; // Application layer feedback. |
| 544 big_endian_writer.WriteU8(0x80 + FMT); | 544 big_endian_writer.WriteU8(0x80 + FMT); |
| 545 big_endian_writer.WriteU8(transport::kPacketTypePayloadSpecific); | 545 big_endian_writer.WriteU8(kPacketTypePayloadSpecific); |
| 546 big_endian_writer.WriteU8(0); | 546 big_endian_writer.WriteU8(0); |
| 547 size_t cast_size_pos = start_size + 3; // Save length position. | 547 size_t cast_size_pos = start_size + 3; // Save length position. |
| 548 big_endian_writer.WriteU8(4); | 548 big_endian_writer.WriteU8(4); |
| 549 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 549 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 550 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. | 550 big_endian_writer.WriteU32(cast->media_ssrc_); // Remote SSRC. |
| 551 big_endian_writer.WriteU32(kCast); | 551 big_endian_writer.WriteU32(kCast); |
| 552 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); | 552 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id_)); |
| 553 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. | 553 size_t cast_loss_field_pos = start_size + 17; // Save loss field position. |
| 554 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. | 554 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields. |
| 555 DCHECK_LE(target_delay.InMilliseconds(), | 555 DCHECK_LE(target_delay.InMilliseconds(), |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 &number_of_frames, | 636 &number_of_frames, |
| 637 &total_number_of_messages_to_send, | 637 &total_number_of_messages_to_send, |
| 638 &rtcp_log_size)) { | 638 &rtcp_log_size)) { |
| 639 return; | 639 return; |
| 640 } | 640 } |
| 641 packet->resize(packet_start_size + rtcp_log_size); | 641 packet->resize(packet_start_size + rtcp_log_size); |
| 642 | 642 |
| 643 base::BigEndianWriter big_endian_writer( | 643 base::BigEndianWriter big_endian_writer( |
| 644 reinterpret_cast<char*>(&((*packet)[packet_start_size])), rtcp_log_size); | 644 reinterpret_cast<char*>(&((*packet)[packet_start_size])), rtcp_log_size); |
| 645 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); | 645 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); |
| 646 big_endian_writer.WriteU8(transport::kPacketTypeApplicationDefined); | 646 big_endian_writer.WriteU8(kPacketTypeApplicationDefined); |
| 647 big_endian_writer.WriteU16(static_cast<uint16>( | 647 big_endian_writer.WriteU16(static_cast<uint16>( |
| 648 2 + 2 * number_of_frames + total_number_of_messages_to_send)); | 648 2 + 2 * number_of_frames + total_number_of_messages_to_send)); |
| 649 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. | 649 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC. |
| 650 big_endian_writer.WriteU32(kCast); | 650 big_endian_writer.WriteU32(kCast); |
| 651 | 651 |
| 652 while (!receiver_log_message.empty() && | 652 while (!receiver_log_message.empty() && |
| 653 total_number_of_messages_to_send > 0) { | 653 total_number_of_messages_to_send > 0) { |
| 654 RtcpReceiverFrameLogMessage& frame_log_messages( | 654 RtcpReceiverFrameLogMessage& frame_log_messages( |
| 655 receiver_log_message.front()); | 655 receiver_log_message.front()); |
| 656 | 656 |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 << "Not enough buffer space."; | 818 << "Not enough buffer space."; |
| 819 | 819 |
| 820 VLOG(3) << "number of frames: " << *number_of_frames; | 820 VLOG(3) << "number of frames: " << *number_of_frames; |
| 821 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; | 821 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; |
| 822 VLOG(3) << "rtcp log size: " << *rtcp_log_size; | 822 VLOG(3) << "rtcp log size: " << *rtcp_log_size; |
| 823 return *number_of_frames > 0; | 823 return *number_of_frames > 0; |
| 824 } | 824 } |
| 825 | 825 |
| 826 } // namespace cast | 826 } // namespace cast |
| 827 } // namespace media | 827 } // namespace media |
| OLD | NEW |