| 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_builder.h" | 5 #include "media/cast/net/rtcp/rtcp_builder.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/logging.h" | 12 #include "base/logging.h" |
| 13 #include "media/cast/net/rtcp/rtcp_utility.h" | 13 #include "media/cast/net/rtcp/rtcp_utility.h" |
| 14 | 14 |
| 15 namespace media { | 15 namespace media { |
| 16 namespace cast { | 16 namespace cast { |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // Max delta is 4095 milliseconds because we need to be able to encode it in | 19 // Max delta is 4095 milliseconds because we need to be able to encode it in |
| 20 // 12 bits. | 20 // 12 bits. |
| 21 const int64 kMaxWireFormatTimeDeltaMs = INT64_C(0xfff); | 21 const int64_t kMaxWireFormatTimeDeltaMs = INT64_C(0xfff); |
| 22 | 22 |
| 23 uint16 MergeEventTypeAndTimestampForWireFormat( | 23 uint16_t MergeEventTypeAndTimestampForWireFormat( |
| 24 const CastLoggingEvent& event, | 24 const CastLoggingEvent& event, |
| 25 const base::TimeDelta& time_delta) { | 25 const base::TimeDelta& time_delta) { |
| 26 int64 time_delta_ms = time_delta.InMilliseconds(); | 26 int64_t time_delta_ms = time_delta.InMilliseconds(); |
| 27 | 27 |
| 28 DCHECK_GE(time_delta_ms, 0); | 28 DCHECK_GE(time_delta_ms, 0); |
| 29 DCHECK_LE(time_delta_ms, kMaxWireFormatTimeDeltaMs); | 29 DCHECK_LE(time_delta_ms, kMaxWireFormatTimeDeltaMs); |
| 30 | 30 |
| 31 uint16 time_delta_12_bits = | 31 uint16_t time_delta_12_bits = |
| 32 static_cast<uint16>(time_delta_ms & kMaxWireFormatTimeDeltaMs); | 32 static_cast<uint16_t>(time_delta_ms & kMaxWireFormatTimeDeltaMs); |
| 33 | 33 |
| 34 uint16 event_type_4_bits = ConvertEventTypeToWireFormat(event); | 34 uint16_t event_type_4_bits = ConvertEventTypeToWireFormat(event); |
| 35 DCHECK(event_type_4_bits); | 35 DCHECK(event_type_4_bits); |
| 36 DCHECK(~(event_type_4_bits & 0xfff0)); | 36 DCHECK(~(event_type_4_bits & 0xfff0)); |
| 37 return (event_type_4_bits << 12) | time_delta_12_bits; | 37 return (event_type_4_bits << 12) | time_delta_12_bits; |
| 38 } | 38 } |
| 39 | 39 |
| 40 bool EventTimestampLessThan(const RtcpReceiverEventLogMessage& lhs, | 40 bool EventTimestampLessThan(const RtcpReceiverEventLogMessage& lhs, |
| 41 const RtcpReceiverEventLogMessage& rhs) { | 41 const RtcpReceiverEventLogMessage& rhs) { |
| 42 return lhs.event_timestamp < rhs.event_timestamp; | 42 return lhs.event_timestamp < rhs.event_timestamp; |
| 43 } | 43 } |
| 44 | 44 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 private: | 107 private: |
| 108 std::ostringstream stream_; | 108 std::ostringstream stream_; |
| 109 int frame_count_; | 109 int frame_count_; |
| 110 int packet_count_; | 110 int packet_count_; |
| 111 int last_frame_id_; | 111 int last_frame_id_; |
| 112 int last_packet_id_; | 112 int last_packet_id_; |
| 113 bool contiguous_sequence_; | 113 bool contiguous_sequence_; |
| 114 }; | 114 }; |
| 115 } // namespace | 115 } // namespace |
| 116 | 116 |
| 117 RtcpBuilder::RtcpBuilder(uint32 sending_ssrc) | 117 RtcpBuilder::RtcpBuilder(uint32_t sending_ssrc) |
| 118 : writer_(NULL, 0), | 118 : writer_(NULL, 0), ssrc_(sending_ssrc), ptr_of_length_(NULL) {} |
| 119 ssrc_(sending_ssrc), | |
| 120 ptr_of_length_(NULL) { | |
| 121 } | |
| 122 | 119 |
| 123 RtcpBuilder::~RtcpBuilder() {} | 120 RtcpBuilder::~RtcpBuilder() {} |
| 124 | 121 |
| 125 void RtcpBuilder::PatchLengthField() { | 122 void RtcpBuilder::PatchLengthField() { |
| 126 if (ptr_of_length_) { | 123 if (ptr_of_length_) { |
| 127 // Back-patch the packet length. The client must have taken | 124 // Back-patch the packet length. The client must have taken |
| 128 // care of proper padding to 32-bit words. | 125 // care of proper padding to 32-bit words. |
| 129 int this_packet_length = (writer_.ptr() - ptr_of_length_ - 2); | 126 int this_packet_length = (writer_.ptr() - ptr_of_length_ - 2); |
| 130 DCHECK_EQ(0, this_packet_length % 4) | 127 DCHECK_EQ(0, this_packet_length % 4) |
| 131 << "Packets must be a multiple of 32 bits long"; | 128 << "Packets must be a multiple of 32 bits long"; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 writer_.WriteU32(rrtr->ntp_fraction); | 227 writer_.WriteU32(rrtr->ntp_fraction); |
| 231 } | 228 } |
| 232 | 229 |
| 233 void RtcpBuilder::AddCast(const RtcpCastMessage* cast, | 230 void RtcpBuilder::AddCast(const RtcpCastMessage* cast, |
| 234 base::TimeDelta target_delay) { | 231 base::TimeDelta target_delay) { |
| 235 // See RTC 4585 Section 6.4 for application specific feedback messages. | 232 // See RTC 4585 Section 6.4 for application specific feedback messages. |
| 236 AddRtcpHeader(kPacketTypePayloadSpecific, 15); | 233 AddRtcpHeader(kPacketTypePayloadSpecific, 15); |
| 237 writer_.WriteU32(ssrc_); // Add our own SSRC. | 234 writer_.WriteU32(ssrc_); // Add our own SSRC. |
| 238 writer_.WriteU32(cast->media_ssrc); // Remote SSRC. | 235 writer_.WriteU32(cast->media_ssrc); // Remote SSRC. |
| 239 writer_.WriteU32(kCast); | 236 writer_.WriteU32(kCast); |
| 240 writer_.WriteU8(static_cast<uint8>(cast->ack_frame_id)); | 237 writer_.WriteU8(static_cast<uint8_t>(cast->ack_frame_id)); |
| 241 uint8* cast_loss_field_pos = reinterpret_cast<uint8*>(writer_.ptr()); | 238 uint8_t* cast_loss_field_pos = reinterpret_cast<uint8_t*>(writer_.ptr()); |
| 242 writer_.WriteU8(0); // Overwritten with number_of_loss_fields. | 239 writer_.WriteU8(0); // Overwritten with number_of_loss_fields. |
| 243 DCHECK_LE(target_delay.InMilliseconds(), | 240 DCHECK_LE(target_delay.InMilliseconds(), |
| 244 std::numeric_limits<uint16_t>::max()); | 241 std::numeric_limits<uint16_t>::max()); |
| 245 writer_.WriteU16(target_delay.InMilliseconds()); | 242 writer_.WriteU16(target_delay.InMilliseconds()); |
| 246 | 243 |
| 247 size_t number_of_loss_fields = 0; | 244 size_t number_of_loss_fields = 0; |
| 248 size_t max_number_of_loss_fields = std::min<size_t>( | 245 size_t max_number_of_loss_fields = std::min<size_t>( |
| 249 kRtcpMaxCastLossFields, writer_.remaining() / 4); | 246 kRtcpMaxCastLossFields, writer_.remaining() / 4); |
| 250 | 247 |
| 251 MissingFramesAndPacketsMap::const_iterator frame_it = | 248 MissingFramesAndPacketsMap::const_iterator frame_it = |
| 252 cast->missing_frames_and_packets.begin(); | 249 cast->missing_frames_and_packets.begin(); |
| 253 | 250 |
| 254 NackStringBuilder nack_string_builder; | 251 NackStringBuilder nack_string_builder; |
| 255 for (; frame_it != cast->missing_frames_and_packets.end() && | 252 for (; frame_it != cast->missing_frames_and_packets.end() && |
| 256 number_of_loss_fields < max_number_of_loss_fields; | 253 number_of_loss_fields < max_number_of_loss_fields; |
| 257 ++frame_it) { | 254 ++frame_it) { |
| 258 nack_string_builder.PushFrame(frame_it->first); | 255 nack_string_builder.PushFrame(frame_it->first); |
| 259 // Iterate through all frames with missing packets. | 256 // Iterate through all frames with missing packets. |
| 260 if (frame_it->second.empty()) { | 257 if (frame_it->second.empty()) { |
| 261 // Special case all packets in a frame is missing. | 258 // Special case all packets in a frame is missing. |
| 262 writer_.WriteU8(static_cast<uint8>(frame_it->first)); | 259 writer_.WriteU8(static_cast<uint8_t>(frame_it->first)); |
| 263 writer_.WriteU16(kRtcpCastAllPacketsLost); | 260 writer_.WriteU16(kRtcpCastAllPacketsLost); |
| 264 writer_.WriteU8(0); | 261 writer_.WriteU8(0); |
| 265 nack_string_builder.PushPacket(kRtcpCastAllPacketsLost); | 262 nack_string_builder.PushPacket(kRtcpCastAllPacketsLost); |
| 266 ++number_of_loss_fields; | 263 ++number_of_loss_fields; |
| 267 } else { | 264 } else { |
| 268 PacketIdSet::const_iterator packet_it = frame_it->second.begin(); | 265 PacketIdSet::const_iterator packet_it = frame_it->second.begin(); |
| 269 while (packet_it != frame_it->second.end()) { | 266 while (packet_it != frame_it->second.end()) { |
| 270 uint16 packet_id = *packet_it; | 267 uint16_t packet_id = *packet_it; |
| 271 // Write frame and packet id to buffer before calculating bitmask. | 268 // Write frame and packet id to buffer before calculating bitmask. |
| 272 writer_.WriteU8(static_cast<uint8>(frame_it->first)); | 269 writer_.WriteU8(static_cast<uint8_t>(frame_it->first)); |
| 273 writer_.WriteU16(packet_id); | 270 writer_.WriteU16(packet_id); |
| 274 nack_string_builder.PushPacket(packet_id); | 271 nack_string_builder.PushPacket(packet_id); |
| 275 | 272 |
| 276 uint8 bitmask = 0; | 273 uint8_t bitmask = 0; |
| 277 ++packet_it; | 274 ++packet_it; |
| 278 while (packet_it != frame_it->second.end()) { | 275 while (packet_it != frame_it->second.end()) { |
| 279 int shift = static_cast<uint8>(*packet_it - packet_id) - 1; | 276 int shift = static_cast<uint8_t>(*packet_it - packet_id) - 1; |
| 280 if (shift >= 0 && shift <= 7) { | 277 if (shift >= 0 && shift <= 7) { |
| 281 nack_string_builder.PushPacket(*packet_it); | 278 nack_string_builder.PushPacket(*packet_it); |
| 282 bitmask |= (1 << shift); | 279 bitmask |= (1 << shift); |
| 283 ++packet_it; | 280 ++packet_it; |
| 284 } else { | 281 } else { |
| 285 break; | 282 break; |
| 286 } | 283 } |
| 287 } | 284 } |
| 288 writer_.WriteU8(bitmask); | 285 writer_.WriteU8(bitmask); |
| 289 ++number_of_loss_fields; | 286 ++number_of_loss_fields; |
| 290 } | 287 } |
| 291 } | 288 } |
| 292 } | 289 } |
| 293 VLOG_IF(1, !nack_string_builder.Empty()) | 290 VLOG_IF(1, !nack_string_builder.Empty()) |
| 294 << "SSRC: " << cast->media_ssrc | 291 << "SSRC: " << cast->media_ssrc |
| 295 << ", ACK: " << cast->ack_frame_id | 292 << ", ACK: " << cast->ack_frame_id |
| 296 << ", NACK: " << nack_string_builder.GetString(); | 293 << ", NACK: " << nack_string_builder.GetString(); |
| 297 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields); | 294 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields); |
| 298 *cast_loss_field_pos = static_cast<uint8>(number_of_loss_fields); | 295 *cast_loss_field_pos = static_cast<uint8_t>(number_of_loss_fields); |
| 299 } | 296 } |
| 300 | 297 |
| 301 void RtcpBuilder::AddSR(const RtcpSenderInfo& sender_info) { | 298 void RtcpBuilder::AddSR(const RtcpSenderInfo& sender_info) { |
| 302 AddRtcpHeader(kPacketTypeSenderReport, 0); | 299 AddRtcpHeader(kPacketTypeSenderReport, 0); |
| 303 writer_.WriteU32(ssrc_); | 300 writer_.WriteU32(ssrc_); |
| 304 writer_.WriteU32(sender_info.ntp_seconds); | 301 writer_.WriteU32(sender_info.ntp_seconds); |
| 305 writer_.WriteU32(sender_info.ntp_fraction); | 302 writer_.WriteU32(sender_info.ntp_fraction); |
| 306 writer_.WriteU32(sender_info.rtp_timestamp); | 303 writer_.WriteU32(sender_info.rtp_timestamp); |
| 307 writer_.WriteU32(sender_info.send_packet_count); | 304 writer_.WriteU32(sender_info.send_packet_count); |
| 308 writer_.WriteU32(static_cast<uint32>(sender_info.send_octet_count)); | 305 writer_.WriteU32(static_cast<uint32_t>(sender_info.send_octet_count)); |
| 309 } | 306 } |
| 310 | 307 |
| 311 /* | 308 /* |
| 312 0 1 2 3 | 309 0 1 2 3 |
| 313 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 | 310 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 |
| 314 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 311 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 315 |V=2|P|reserved | PT=XR=207 | length | | 312 |V=2|P|reserved | PT=XR=207 | length | |
| 316 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 313 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 317 | SSRC | | 314 | SSRC | |
| 318 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 315 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 writer_.WriteU32(frame_log_messages.rtp_timestamp_); | 357 writer_.WriteU32(frame_log_messages.rtp_timestamp_); |
| 361 size_t messages_in_frame = frame_log_messages.event_log_messages_.size(); | 358 size_t messages_in_frame = frame_log_messages.event_log_messages_.size(); |
| 362 if (messages_in_frame > total_number_of_messages_to_send) { | 359 if (messages_in_frame > total_number_of_messages_to_send) { |
| 363 // We are running out of space. | 360 // We are running out of space. |
| 364 messages_in_frame = total_number_of_messages_to_send; | 361 messages_in_frame = total_number_of_messages_to_send; |
| 365 } | 362 } |
| 366 // Keep track of how many messages we have left to send. | 363 // Keep track of how many messages we have left to send. |
| 367 total_number_of_messages_to_send -= messages_in_frame; | 364 total_number_of_messages_to_send -= messages_in_frame; |
| 368 | 365 |
| 369 // On the wire format is number of messages - 1. | 366 // On the wire format is number of messages - 1. |
| 370 writer_.WriteU8(static_cast<uint8>(messages_in_frame - 1)); | 367 writer_.WriteU8(static_cast<uint8_t>(messages_in_frame - 1)); |
| 371 | 368 |
| 372 base::TimeTicks event_timestamp_base = | 369 base::TimeTicks event_timestamp_base = |
| 373 frame_log_messages.event_log_messages_.front().event_timestamp; | 370 frame_log_messages.event_log_messages_.front().event_timestamp; |
| 374 uint32 base_timestamp_ms = | 371 uint32_t base_timestamp_ms = |
| 375 (event_timestamp_base - base::TimeTicks()).InMilliseconds(); | 372 (event_timestamp_base - base::TimeTicks()).InMilliseconds(); |
| 376 writer_.WriteU8(static_cast<uint8>(base_timestamp_ms >> 16)); | 373 writer_.WriteU8(static_cast<uint8_t>(base_timestamp_ms >> 16)); |
| 377 writer_.WriteU8(static_cast<uint8>(base_timestamp_ms >> 8)); | 374 writer_.WriteU8(static_cast<uint8_t>(base_timestamp_ms >> 8)); |
| 378 writer_.WriteU8(static_cast<uint8>(base_timestamp_ms)); | 375 writer_.WriteU8(static_cast<uint8_t>(base_timestamp_ms)); |
| 379 | 376 |
| 380 while (!frame_log_messages.event_log_messages_.empty() && | 377 while (!frame_log_messages.event_log_messages_.empty() && |
| 381 messages_in_frame > 0) { | 378 messages_in_frame > 0) { |
| 382 const RtcpReceiverEventLogMessage& event_message = | 379 const RtcpReceiverEventLogMessage& event_message = |
| 383 frame_log_messages.event_log_messages_.front(); | 380 frame_log_messages.event_log_messages_.front(); |
| 384 uint16 event_type_and_timestamp_delta = | 381 uint16_t event_type_and_timestamp_delta = |
| 385 MergeEventTypeAndTimestampForWireFormat( | 382 MergeEventTypeAndTimestampForWireFormat( |
| 386 event_message.type, | 383 event_message.type, |
| 387 event_message.event_timestamp - event_timestamp_base); | 384 event_message.event_timestamp - event_timestamp_base); |
| 388 switch (event_message.type) { | 385 switch (event_message.type) { |
| 389 case FRAME_ACK_SENT: | 386 case FRAME_ACK_SENT: |
| 390 case FRAME_PLAYOUT: | 387 case FRAME_PLAYOUT: |
| 391 case FRAME_DECODED: | 388 case FRAME_DECODED: |
| 392 writer_.WriteU16( | 389 writer_.WriteU16(static_cast<uint16_t>( |
| 393 static_cast<uint16>(event_message.delay_delta.InMilliseconds())); | 390 event_message.delay_delta.InMilliseconds())); |
| 394 writer_.WriteU16(event_type_and_timestamp_delta); | 391 writer_.WriteU16(event_type_and_timestamp_delta); |
| 395 break; | 392 break; |
| 396 case PACKET_RECEIVED: | 393 case PACKET_RECEIVED: |
| 397 writer_.WriteU16(event_message.packet_id); | 394 writer_.WriteU16(event_message.packet_id); |
| 398 writer_.WriteU16(event_type_and_timestamp_delta); | 395 writer_.WriteU16(event_type_and_timestamp_delta); |
| 399 break; | 396 break; |
| 400 default: | 397 default: |
| 401 NOTREACHED(); | 398 NOTREACHED(); |
| 402 } | 399 } |
| 403 messages_in_frame--; | 400 messages_in_frame--; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 receiver_log_message->push_front(frame_log); | 477 receiver_log_message->push_front(frame_log); |
| 481 } | 478 } |
| 482 | 479 |
| 483 VLOG(3) << "number of frames: " << number_of_frames; | 480 VLOG(3) << "number of frames: " << number_of_frames; |
| 484 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; | 481 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; |
| 485 return number_of_frames > 0; | 482 return number_of_frames > 0; |
| 486 } | 483 } |
| 487 | 484 |
| 488 } // namespace cast | 485 } // namespace cast |
| 489 } // namespace media | 486 } // namespace media |
| OLD | NEW |