Updating XTBs based on .GRDs from branch master
[chromium-blink-merge.git] / media / cast / net / rtp / rtp_sender.cc
blob2ecabcb44c799e550c231c52cb37e6b1aedf9dd5
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
3 // found in the LICENSE file.
5 #include "media/cast/net/rtp/rtp_sender.h"
7 #include "base/big_endian.h"
8 #include "base/logging.h"
9 #include "base/rand_util.h"
11 namespace media {
12 namespace cast {
14 namespace {
16 // If there is only one referecne to the packet then copy the
17 // reference and return.
18 // Otherwise return a deep copy of the packet.
19 PacketRef FastCopyPacket(const PacketRef& packet) {
20 if (packet->HasOneRef())
21 return packet;
22 return make_scoped_refptr(new base::RefCountedData<Packet>(packet->data));
25 } // namespace
27 RtpSender::RtpSender(
28 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
29 PacedSender* const transport)
30 : transport_(transport),
31 transport_task_runner_(transport_task_runner),
32 weak_factory_(this) {
33 // Randomly set sequence number start value.
34 config_.sequence_number = base::RandInt(0, 65535);
37 RtpSender::~RtpSender() {}
39 bool RtpSender::Initialize(const CastTransportRtpConfig& config) {
40 config_.ssrc = config.ssrc;
41 config_.payload_type = config.rtp_payload_type;
42 packetizer_.reset(new RtpPacketizer(transport_, &storage_, config_));
43 return true;
46 void RtpSender::SendFrame(const EncodedFrame& frame) {
47 DCHECK(packetizer_);
48 packetizer_->SendFrameAsPackets(frame);
49 LOG_IF(DFATAL, storage_.GetNumberOfStoredFrames() > kMaxUnackedFrames)
50 << "Possible bug: Frames are not being actively released from storage.";
53 void RtpSender::ResendPackets(
54 const MissingFramesAndPacketsMap& missing_frames_and_packets,
55 bool cancel_rtx_if_not_in_list, const DedupInfo& dedup_info) {
56 // Iterate over all frames in the list.
57 for (MissingFramesAndPacketsMap::const_iterator it =
58 missing_frames_and_packets.begin();
59 it != missing_frames_and_packets.end();
60 ++it) {
61 SendPacketVector packets_to_resend;
62 uint8 frame_id = it->first;
63 // Set of packets that the receiver wants us to re-send.
64 // If empty, we need to re-send all packets for this frame.
65 const PacketIdSet& missing_packet_set = it->second;
67 bool resend_all = missing_packet_set.find(kRtcpCastAllPacketsLost) !=
68 missing_packet_set.end();
69 bool resend_last = missing_packet_set.find(kRtcpCastLastPacket) !=
70 missing_packet_set.end();
72 const SendPacketVector* stored_packets = storage_.GetFrame8(frame_id);
73 if (!stored_packets)
74 continue;
76 for (SendPacketVector::const_iterator it = stored_packets->begin();
77 it != stored_packets->end(); ++it) {
78 const PacketKey& packet_key = it->first;
79 const uint16 packet_id = packet_key.second.second;
81 // Should we resend the packet?
82 bool resend = resend_all;
84 // Should we resend it because it's in the missing_packet_set?
85 if (!resend &&
86 missing_packet_set.find(packet_id) != missing_packet_set.end()) {
87 resend = true;
90 // If we were asked to resend the last packet, check if it's the
91 // last packet.
92 if (!resend && resend_last && (it + 1) == stored_packets->end()) {
93 resend = true;
96 if (resend) {
97 // Resend packet to the network.
98 VLOG(3) << "Resend " << static_cast<int>(frame_id) << ":"
99 << packet_id;
100 // Set a unique incremental sequence number for every packet.
101 PacketRef packet_copy = FastCopyPacket(it->second);
102 UpdateSequenceNumber(&packet_copy->data);
103 packets_to_resend.push_back(std::make_pair(packet_key, packet_copy));
104 } else if (cancel_rtx_if_not_in_list) {
105 transport_->CancelSendingPacket(it->first);
108 transport_->ResendPackets(packets_to_resend, dedup_info);
112 void RtpSender::CancelSendingFrames(const std::vector<uint32>& frame_ids) {
113 for (std::vector<uint32>::const_iterator i = frame_ids.begin();
114 i != frame_ids.end(); ++i) {
115 const SendPacketVector* stored_packets = storage_.GetFrame8(*i & 0xFF);
116 if (!stored_packets)
117 continue;
118 for (SendPacketVector::const_iterator j = stored_packets->begin();
119 j != stored_packets->end(); ++j) {
120 transport_->CancelSendingPacket(j->first);
122 storage_.ReleaseFrame(*i);
126 void RtpSender::ResendFrameForKickstart(uint32 frame_id,
127 base::TimeDelta dedupe_window) {
128 // Send the last packet of the encoded frame to kick start
129 // retransmission. This gives enough information to the receiver what
130 // packets and frames are missing.
131 MissingFramesAndPacketsMap missing_frames_and_packets;
132 PacketIdSet missing;
133 missing.insert(kRtcpCastLastPacket);
134 missing_frames_and_packets.insert(std::make_pair(frame_id, missing));
136 // Sending this extra packet is to kick-start the session. There is
137 // no need to optimize re-transmission for this case.
138 DedupInfo dedup_info;
139 dedup_info.resend_interval = dedupe_window;
140 ResendPackets(missing_frames_and_packets, false, dedup_info);
143 void RtpSender::UpdateSequenceNumber(Packet* packet) {
144 // TODO(miu): This is an abstraction violation. This needs to be a part of
145 // the overall packet (de)serialization consolidation.
146 static const int kByteOffsetToSequenceNumber = 2;
147 base::BigEndianWriter big_endian_writer(
148 reinterpret_cast<char*>((&packet->front()) + kByteOffsetToSequenceNumber),
149 sizeof(uint16));
150 big_endian_writer.WriteU16(packetizer_->NextSequenceNumber());
153 int64 RtpSender::GetLastByteSentForFrame(uint32 frame_id) {
154 const SendPacketVector* stored_packets = storage_.GetFrame8(frame_id & 0xFF);
155 if (!stored_packets)
156 return 0;
157 PacketKey last_packet_key = stored_packets->rbegin()->first;
158 return transport_->GetLastByteSentForPacket(last_packet_key);
161 } // namespace cast
162 } // namespace media