| 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/pacing/paced_sender.h" | 5 #include "media/cast/net/pacing/paced_sender.h" |
| 6 | 6 |
| 7 #include "base/big_endian.h" | 7 #include "base/big_endian.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/debug/dump_without_crashing.h" | 9 #include "base/debug/dump_without_crashing.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 // enqueued in the pacer. This is used to detect bugs, reported as crash dumps. | 24 // enqueued in the pacer. This is used to detect bugs, reported as crash dumps. |
| 25 static const size_t kHugeQueueLengthSeconds = 10; | 25 static const size_t kHugeQueueLengthSeconds = 10; |
| 26 static const size_t kRidiculousNumberOfPackets = | 26 static const size_t kRidiculousNumberOfPackets = |
| 27 kHugeQueueLengthSeconds * (kMaxBurstSize * 1000 / kPacingIntervalMs); | 27 kHugeQueueLengthSeconds * (kMaxBurstSize * 1000 / kPacingIntervalMs); |
| 28 | 28 |
| 29 } // namespace | 29 } // namespace |
| 30 | 30 |
| 31 DedupInfo::DedupInfo() : last_byte_acked_for_audio(0) {} | 31 DedupInfo::DedupInfo() : last_byte_acked_for_audio(0) {} |
| 32 | 32 |
| 33 // static | 33 // static |
| 34 PacketKey PacedPacketSender::MakePacketKey(const base::TimeTicks& ticks, | 34 PacketKey PacedPacketSender::MakePacketKey(PacketKey::PacketType packet_type, |
| 35 uint32 frame_id, |
| 35 uint32 ssrc, | 36 uint32 ssrc, |
| 36 uint16 packet_id) { | 37 uint16 packet_id) { |
| 37 return std::make_pair(ticks, std::make_pair(ssrc, packet_id)); | 38 PacketKey key{packet_type, frame_id, ssrc, packet_id}; |
| 39 return key; |
| 38 } | 40 } |
| 39 | 41 |
| 40 PacedSender::PacketSendRecord::PacketSendRecord() | 42 PacedSender::PacketSendRecord::PacketSendRecord() |
| 41 : last_byte_sent(0), last_byte_sent_for_audio(0) {} | 43 : last_byte_sent(0), last_byte_sent_for_audio(0) {} |
| 42 | 44 |
| 43 PacedSender::PacedSender( | 45 PacedSender::PacedSender( |
| 44 size_t target_burst_size, | 46 size_t target_burst_size, |
| 45 size_t max_burst_size, | 47 size_t max_burst_size, |
| 46 base::TickClock* clock, | 48 base::TickClock* clock, |
| 47 std::vector<PacketEvent>* recent_packet_events, | 49 std::vector<PacketEvent>* recent_packet_events, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 PacketSendHistory::const_iterator it = send_history_.find(packet_key); | 120 PacketSendHistory::const_iterator it = send_history_.find(packet_key); |
| 119 | 121 |
| 120 // No history of previous transmission. It might be sent too long ago. | 122 // No history of previous transmission. It might be sent too long ago. |
| 121 if (it == send_history_.end()) | 123 if (it == send_history_.end()) |
| 122 return true; | 124 return true; |
| 123 | 125 |
| 124 // Suppose there is request to retransmit X and there is an audio | 126 // Suppose there is request to retransmit X and there is an audio |
| 125 // packet Y sent just before X. Reject retransmission of X if ACK for | 127 // packet Y sent just before X. Reject retransmission of X if ACK for |
| 126 // Y has not been received. | 128 // Y has not been received. |
| 127 // Only do this for video packets. | 129 // Only do this for video packets. |
| 128 if (packet_key.second.first == video_ssrc_) { | 130 if (packet_key.ssrc == video_ssrc_) { |
| 129 if (dedup_info.last_byte_acked_for_audio && | 131 if (dedup_info.last_byte_acked_for_audio && |
| 130 it->second.last_byte_sent_for_audio && | 132 it->second.last_byte_sent_for_audio && |
| 131 dedup_info.last_byte_acked_for_audio < | 133 dedup_info.last_byte_acked_for_audio < |
| 132 it->second.last_byte_sent_for_audio) { | 134 it->second.last_byte_sent_for_audio) { |
| 133 return false; | 135 return false; |
| 134 } | 136 } |
| 135 } | 137 } |
| 136 // Retransmission interval has to be greater than |resend_interval|. | 138 // Retransmission interval has to be greater than |resend_interval|. |
| 137 if (now - it->second.time < dedup_info.resend_interval) | 139 if (now - it->second.time < dedup_info.resend_interval) |
| 138 return false; | 140 return false; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 162 } | 164 } |
| 163 } | 165 } |
| 164 if (state_ == State_Unblocked) { | 166 if (state_ == State_Unblocked) { |
| 165 SendStoredPackets(); | 167 SendStoredPackets(); |
| 166 } | 168 } |
| 167 return true; | 169 return true; |
| 168 } | 170 } |
| 169 | 171 |
| 170 bool PacedSender::SendRtcpPacket(uint32 ssrc, PacketRef packet) { | 172 bool PacedSender::SendRtcpPacket(uint32 ssrc, PacketRef packet) { |
| 171 if (state_ == State_TransportBlocked) { | 173 if (state_ == State_TransportBlocked) { |
| 172 priority_packet_list_[ | 174 PacketKey key = |
| 173 PacedPacketSender::MakePacketKey(base::TimeTicks(), ssrc, 0)] = | 175 PacedPacketSender::MakePacketKey(PacketKey::RTCP, 0, ssrc, 0); |
| 174 make_pair(PacketType_RTCP, packet); | 176 priority_packet_list_[key] = make_pair(PacketType_RTCP, packet); |
| 175 } else { | 177 } else { |
| 176 // We pass the RTCP packets straight through. | 178 // We pass the RTCP packets straight through. |
| 177 if (!transport_->SendPacket( | 179 if (!transport_->SendPacket( |
| 178 packet, | 180 packet, |
| 179 base::Bind(&PacedSender::SendStoredPackets, | 181 base::Bind(&PacedSender::SendStoredPackets, |
| 180 weak_factory_.GetWeakPtr()))) { | 182 weak_factory_.GetWeakPtr()))) { |
| 181 state_ = State_TransportBlocked; | 183 state_ = State_TransportBlocked; |
| 182 } | 184 } |
| 183 } | 185 } |
| 184 return true; | 186 return true; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 197 PacketList::iterator i = list->begin(); | 199 PacketList::iterator i = list->begin(); |
| 198 *packet_type = i->second.first; | 200 *packet_type = i->second.first; |
| 199 *packet_key = i->first; | 201 *packet_key = i->first; |
| 200 PacketRef ret = i->second.second; | 202 PacketRef ret = i->second.second; |
| 201 list->erase(i); | 203 list->erase(i); |
| 202 return ret; | 204 return ret; |
| 203 } | 205 } |
| 204 | 206 |
| 205 bool PacedSender::IsHighPriority(const PacketKey& packet_key) const { | 207 bool PacedSender::IsHighPriority(const PacketKey& packet_key) const { |
| 206 return std::find(priority_ssrcs_.begin(), priority_ssrcs_.end(), | 208 return std::find(priority_ssrcs_.begin(), priority_ssrcs_.end(), |
| 207 packet_key.second.first) != priority_ssrcs_.end(); | 209 packet_key.ssrc) != priority_ssrcs_.end(); |
| 208 } | 210 } |
| 209 | 211 |
| 210 bool PacedSender::empty() const { | 212 bool PacedSender::empty() const { |
| 211 return packet_list_.empty() && priority_packet_list_.empty(); | 213 return packet_list_.empty() && priority_packet_list_.empty(); |
| 212 } | 214 } |
| 213 | 215 |
| 214 size_t PacedSender::size() const { | 216 size_t PacedSender::size() const { |
| 215 return packet_list_.size() + priority_packet_list_.size(); | 217 return packet_list_.size() + priority_packet_list_.size(); |
| 216 } | 218 } |
| 217 | 219 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 break; | 293 break; |
| 292 } | 294 } |
| 293 | 295 |
| 294 const bool socket_blocked = !transport_->SendPacket(packet, cb); | 296 const bool socket_blocked = !transport_->SendPacket(packet, cb); |
| 295 | 297 |
| 296 // Save the send record. | 298 // Save the send record. |
| 297 send_record.last_byte_sent = transport_->GetBytesSent(); | 299 send_record.last_byte_sent = transport_->GetBytesSent(); |
| 298 send_record.last_byte_sent_for_audio = GetLastByteSentForSsrc(audio_ssrc_); | 300 send_record.last_byte_sent_for_audio = GetLastByteSentForSsrc(audio_ssrc_); |
| 299 send_history_[packet_key] = send_record; | 301 send_history_[packet_key] = send_record; |
| 300 send_history_buffer_[packet_key] = send_record; | 302 send_history_buffer_[packet_key] = send_record; |
| 301 last_byte_sent_[packet_key.second.first] = send_record.last_byte_sent; | 303 last_byte_sent_[packet_key.ssrc] = send_record.last_byte_sent; |
| 302 | 304 |
| 303 if (socket_blocked) { | 305 if (socket_blocked) { |
| 304 state_ = State_TransportBlocked; | 306 state_ = State_TransportBlocked; |
| 305 return; | 307 return; |
| 306 } | 308 } |
| 307 current_burst_size_++; | 309 current_burst_size_++; |
| 308 } | 310 } |
| 309 | 311 |
| 310 // Keep ~0.5 seconds of data (1000 packets). | 312 // Keep ~0.5 seconds of data (1000 packets). |
| 311 if (send_history_buffer_.size() >= | 313 if (send_history_buffer_.size() >= |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 } | 348 } |
| 347 success &= reader.Skip(2); | 349 success &= reader.Skip(2); |
| 348 success &= reader.ReadU16(&event.packet_id); | 350 success &= reader.ReadU16(&event.packet_id); |
| 349 success &= reader.ReadU16(&event.max_packet_id); | 351 success &= reader.ReadU16(&event.max_packet_id); |
| 350 event.size = packet.size(); | 352 event.size = packet.size(); |
| 351 DCHECK(success); | 353 DCHECK(success); |
| 352 } | 354 } |
| 353 | 355 |
| 354 } // namespace cast | 356 } // namespace cast |
| 355 } // namespace media | 357 } // namespace media |
| OLD | NEW |