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/transport/rtp_sender/rtp_sender.h" | 5 #include "media/cast/transport/rtp_sender/rtp_sender.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "media/cast/transport/cast_transport_defines.h" | 9 #include "media/cast/transport/cast_transport_defines.h" |
10 #include "media/cast/transport/pacing/paced_sender.h" | 10 #include "media/cast/transport/pacing/paced_sender.h" |
11 | 11 |
12 namespace media { | 12 namespace media { |
13 namespace cast { | 13 namespace cast { |
14 namespace transport { | 14 namespace transport { |
15 | 15 |
| 16 namespace { |
| 17 |
| 18 // If there is only one referecne to the packet then copy the |
| 19 // reference and return. |
| 20 // Otherwise return a deep copy of the packet. |
| 21 PacketRef FastCopyPacket(const PacketRef& packet) { |
| 22 if (packet->HasOneRef()) |
| 23 return packet; |
| 24 return make_scoped_refptr(new base::RefCountedData<Packet>(packet->data)); |
| 25 } |
| 26 |
| 27 } // namespace |
| 28 |
16 RtpSender::RtpSender( | 29 RtpSender::RtpSender( |
17 base::TickClock* clock, | 30 base::TickClock* clock, |
18 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner, | 31 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner, |
19 PacedSender* const transport) | 32 PacedSender* const transport) |
20 : clock_(clock), | 33 : clock_(clock), |
21 transport_(transport), | 34 transport_(transport), |
22 transport_task_runner_(transport_task_runner), | 35 transport_task_runner_(transport_task_runner), |
23 weak_factory_(this) { | 36 weak_factory_(this) { |
24 // Randomly set sequence number start value. | 37 // Randomly set sequence number start value. |
25 config_.sequence_number = base::RandInt(0, 65535); | 38 config_.sequence_number = base::RandInt(0, 65535); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 // Iterate over all frames in the list. | 79 // Iterate over all frames in the list. |
67 for (MissingFramesAndPacketsMap::const_iterator it = | 80 for (MissingFramesAndPacketsMap::const_iterator it = |
68 missing_frames_and_packets.begin(); | 81 missing_frames_and_packets.begin(); |
69 it != missing_frames_and_packets.end(); | 82 it != missing_frames_and_packets.end(); |
70 ++it) { | 83 ++it) { |
71 SendPacketVector packets_to_resend; | 84 SendPacketVector packets_to_resend; |
72 uint8 frame_id = it->first; | 85 uint8 frame_id = it->first; |
73 // Set of packets that the receiver wants us to re-send. | 86 // Set of packets that the receiver wants us to re-send. |
74 // If empty, we need to re-send all packets for this frame. | 87 // If empty, we need to re-send all packets for this frame. |
75 const PacketIdSet& missing_packet_set = it->second; | 88 const PacketIdSet& missing_packet_set = it->second; |
76 bool success = false; | |
77 | 89 |
78 for (uint16 packet_id = 0; ; packet_id++) { | 90 const SendPacketVector* stored_packets = storage_->GetFrame8(frame_id); |
79 // Get packet from storage. | 91 if (!stored_packets) |
80 success = storage_->GetPacket(frame_id, packet_id, &packets_to_resend); | 92 continue; |
81 | 93 |
82 // Check that we got at least one packet. | 94 for (SendPacketVector::const_iterator it = stored_packets->begin(); |
83 DCHECK(packet_id != 0 || success) | 95 it != stored_packets->end(); ++it) { |
84 << "Failed to resend frame " << static_cast<int>(frame_id); | 96 const PacketKey& packet_key = it->first; |
| 97 const uint16 packet_id = packet_key.second.second; |
85 | 98 |
86 if (!success) break; | 99 // If the resend request doesn't include this packet then cancel |
87 | 100 // re-transmission already in queue. |
88 if (!missing_packet_set.empty() && | 101 if (!missing_packet_set.empty() && |
89 missing_packet_set.find(packet_id) == missing_packet_set.end()) { | 102 missing_packet_set.find(packet_id) == missing_packet_set.end()) { |
90 transport_->CancelSendingPacket(packets_to_resend.back().first); | 103 transport_->CancelSendingPacket(it->first); |
91 packets_to_resend.pop_back(); | |
92 } else { | 104 } else { |
93 // Resend packet to the network. | 105 // Resend packet to the network. |
94 VLOG(3) << "Resend " << static_cast<int>(frame_id) << ":" | 106 VLOG(3) << "Resend " << static_cast<int>(frame_id) << ":" |
95 << packet_id; | 107 << packet_id; |
96 // Set a unique incremental sequence number for every packet. | 108 // Set a unique incremental sequence number for every packet. |
97 PacketRef packet = packets_to_resend.back().second; | 109 PacketRef packet_copy = FastCopyPacket(it->second); |
98 UpdateSequenceNumber(&packet->data); | 110 UpdateSequenceNumber(&packet_copy->data); |
| 111 packets_to_resend.push_back(std::make_pair(packet_key, packet_copy)); |
99 } | 112 } |
100 } | 113 } |
101 transport_->ResendPackets(packets_to_resend); | 114 transport_->ResendPackets(packets_to_resend); |
102 } | 115 } |
103 } | 116 } |
104 | 117 |
105 void RtpSender::UpdateSequenceNumber(Packet* packet) { | 118 void RtpSender::UpdateSequenceNumber(Packet* packet) { |
106 uint16 new_sequence_number = packetizer_->NextSequenceNumber(); | 119 uint16 new_sequence_number = packetizer_->NextSequenceNumber(); |
107 int index = 2; | 120 int index = 2; |
108 (*packet)[index] = (static_cast<uint8>(new_sequence_number)); | 121 (*packet)[index] = (static_cast<uint8>(new_sequence_number)); |
109 (*packet)[index + 1] = (static_cast<uint8>(new_sequence_number >> 8)); | 122 (*packet)[index + 1] = (static_cast<uint8>(new_sequence_number >> 8)); |
110 } | 123 } |
111 | 124 |
112 } // namespace transport | 125 } // namespace transport |
113 } // namespace cast | 126 } // namespace cast |
114 } // namespace media | 127 } // namespace media |
OLD | NEW |