Index: media/cast/transport/rtp_sender/rtp_sender.cc |
diff --git a/media/cast/transport/rtp_sender/rtp_sender.cc b/media/cast/transport/rtp_sender/rtp_sender.cc |
index 91b6298bac5d94e4b6e5d9f94255e4c20d402b36..b937396869b9b2b8f79041647020205695cbbeaf 100644 |
--- a/media/cast/transport/rtp_sender/rtp_sender.cc |
+++ b/media/cast/transport/rtp_sender/rtp_sender.cc |
@@ -13,6 +13,19 @@ namespace media { |
namespace cast { |
namespace transport { |
+namespace { |
+ |
+// If there is only one referecne to the packet then copy the |
+// reference and return. |
+// Otherwise return a deep copy of the packet. |
+PacketRef FastCopyPacket(const PacketRef& packet) { |
+ if (packet->HasOneRef()) |
+ return packet; |
+ return make_scoped_refptr(new base::RefCountedData<Packet>(packet->data)); |
+} |
+ |
+} // namespace |
+ |
RtpSender::RtpSender( |
base::TickClock* clock, |
const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner, |
@@ -73,29 +86,29 @@ void RtpSender::ResendPackets( |
// Set of packets that the receiver wants us to re-send. |
// If empty, we need to re-send all packets for this frame. |
const PacketIdSet& missing_packet_set = it->second; |
- bool success = false; |
- |
- for (uint16 packet_id = 0; ; packet_id++) { |
- // Get packet from storage. |
- success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend); |
- // Check that we got at least one packet. |
- DCHECK(packet_id != 0 || success) |
- << "Failed to resend frame " << static_cast<int>(frame_id); |
+ const SendPacketVector* stored_packets = storage_->GetFrame8(frame_id); |
+ if (!stored_packets) |
+ continue; |
- if (!success) break; |
+ for (SendPacketVector::const_iterator it = stored_packets->begin(); |
+ it != stored_packets->end(); ++it) { |
+ const PacketKey& packet_key = it->first; |
+ const uint16 packet_id = packet_key.second.second; |
+ // If the resend request doesn't include this packet then cancel |
+ // re-transmission already in queue. |
if (!missing_packet_set.empty() && |
missing_packet_set.find(packet_id) == missing_packet_set.end()) { |
- transport_->CancelSendingPacket(packets_to_resend.back().first); |
- packets_to_resend.pop_back(); |
+ transport_->CancelSendingPacket(it->first); |
} else { |
// Resend packet to the network. |
VLOG(3) << "Resend " << static_cast<int>(frame_id) << ":" |
<< packet_id; |
// Set a unique incremental sequence number for every packet. |
- PacketRef packet = packets_to_resend.back().second; |
- UpdateSequenceNumber(&packet->data); |
+ PacketRef packet_copy = FastCopyPacket(it->second); |
+ UpdateSequenceNumber(&packet_copy->data); |
+ packets_to_resend.push_back(std::make_pair(packet_key, packet_copy)); |
} |
} |
transport_->ResendPackets(packets_to_resend); |