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 #ifndef MEDIA_CAST_NET_PACING_PACED_SENDER_H_
6 #define MEDIA_CAST_NET_PACING_PACED_SENDER_H_
11 #include "base/basictypes.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/threading/non_thread_safe.h"
16 #include "base/time/default_tick_clock.h"
17 #include "base/time/tick_clock.h"
18 #include "base/time/time.h"
19 #include "media/cast/logging/logging_defines.h"
20 #include "media/cast/net/cast_transport_config.h"
25 // Meant to use as defaults for pacer construction.
26 static const size_t kTargetBurstSize
= 10;
27 static const size_t kMaxBurstSize
= 20;
31 // Use std::pair for free comparison operators.
32 // { capture_time, ssrc, packet_id }
33 // The PacketKey is designed to meet two criteria:
34 // 1. When we re-send the same packet again, we can use the packet key
35 // to identify it so that we can de-duplicate packets in the queue.
36 // 2. The sort order of the PacketKey determines the order that packets
37 // are sent out. Using the capture_time as the first member basically
38 // means that older packets are sent first.
39 typedef std::pair
<base::TimeTicks
, std::pair
<uint32
, uint16
> > PacketKey
;
40 typedef std::vector
<std::pair
<PacketKey
, PacketRef
> > SendPacketVector
;
42 // Information used to deduplicate retransmission packets.
43 // There are two criteria for deduplication.
45 // 1. Using another muxed stream.
46 // Suppose there are multiple streams muxed and sent via the same
47 // socket. When there is a retransmission request for packet X, we
48 // will reject the retransmission if there is a packet sent from
49 // another stream just before X but not acked. Typically audio stream
50 // is used for this purpose. |last_byte_acked_for_audio| provides this
53 // 2. Using a time interval.
54 // Time between sending the same packet must be greater than
58 base::TimeDelta resend_interval
;
59 int64 last_byte_acked_for_audio
;
62 // We have this pure virtual class to enable mocking.
63 class PacedPacketSender
{
65 virtual bool SendPackets(const SendPacketVector
& packets
) = 0;
66 virtual bool ResendPackets(const SendPacketVector
& packets
,
67 const DedupInfo
& dedup_info
) = 0;
68 virtual bool SendRtcpPacket(uint32 ssrc
, PacketRef packet
) = 0;
69 virtual void CancelSendingPacket(const PacketKey
& packet_key
) = 0;
71 virtual ~PacedPacketSender() {}
73 static PacketKey
MakePacketKey(const base::TimeTicks
& ticks
,
78 class PacedSender
: public PacedPacketSender
,
79 public base::NonThreadSafe
,
80 public base::SupportsWeakPtr
<PacedSender
> {
82 // The |external_transport| should only be used by the Cast receiver and for
85 size_t target_burst_size
, // Should normally be kTargetBurstSize.
86 size_t max_burst_size
, // Should normally be kMaxBurstSize.
87 base::TickClock
* clock
,
89 PacketSender
* external_transport
,
90 const scoped_refptr
<base::SingleThreadTaskRunner
>& transport_task_runner
);
94 // These must be called before non-RTCP packets are sent.
95 void RegisterAudioSsrc(uint32 audio_ssrc
);
96 void RegisterVideoSsrc(uint32 video_ssrc
);
98 // Register SSRC that has a higher priority for sending. Multiple SSRCs can
100 // Note that it is not expected to register many SSRCs with this method.
101 // Because IsHigherPriority() is determined in linear time.
102 void RegisterPrioritySsrc(uint32 ssrc
);
104 // Returns the total number of bytes sent to the socket when the specified
105 // packet was just sent.
106 // Returns 0 if the packet cannot be found or not yet sent.
107 int64
GetLastByteSentForPacket(const PacketKey
& packet_key
);
109 // Returns the total number of bytes sent to the socket when the last payload
110 // identified by SSRC is just sent.
111 int64
GetLastByteSentForSsrc(uint32 ssrc
);
113 // PacedPacketSender implementation.
114 bool SendPackets(const SendPacketVector
& packets
) final
;
115 bool ResendPackets(const SendPacketVector
& packets
,
116 const DedupInfo
& dedup_info
) final
;
117 bool SendRtcpPacket(uint32 ssrc
, PacketRef packet
) final
;
118 void CancelSendingPacket(const PacketKey
& packet_key
) final
;
121 // Actually sends the packets to the transport.
122 void SendStoredPackets();
123 void LogPacketEvent(const Packet
& packet
, CastLoggingEvent event
);
125 // Returns true if retransmission for packet indexed by |packet_key| is
126 // accepted. |dedup_info| contains information to help deduplicate
127 // retransmission. |now| is the current time to save on fetching it from the
128 // clock multiple times.
129 bool ShouldResend(const PacketKey
& packet_key
,
130 const DedupInfo
& dedup_info
,
131 const base::TimeTicks
& now
);
139 // In an unblocked state, we can send more packets.
140 // We have to check the current time against |burst_end_| to see if we are
141 // appending to the current burst or if we can start a new one.
143 // In this state, we are waiting for a callback from the udp transport.
144 // This happens when the OS-level buffer is full. Once we receive the
145 // callback, we go to State_Unblocked and see if we can write more packets
146 // to the current burst. (Or the next burst if enough time has passed.)
147 State_TransportBlocked
,
148 // Once we've written enough packets for a time slice, we go into this
149 // state and PostDelayTask a call to ourselves to wake up when we can
157 // Returns the next packet to send. RTCP packets have highest priority,
158 // resend packets have second highest priority and then comes everything
160 PacketRef
PopNextPacket(PacketType
* packet_type
,
161 PacketKey
* packet_key
);
163 // Returns true if the packet should have a higher priority.
164 bool IsHighPriority(const PacketKey
& packet_key
) const;
166 base::TickClock
* const clock_
; // Not owned by this class.
167 LoggingImpl
* const logging_
; // Not owned by this class.
168 PacketSender
* transport_
; // Not owned by this class.
169 scoped_refptr
<base::SingleThreadTaskRunner
> transport_task_runner_
;
173 // Set of SSRCs that have higher priority. This is a vector instead of a
174 // set because there's only very few in it (most likely 1).
175 std::vector
<uint32
> priority_ssrcs_
;
176 typedef std::map
<PacketKey
, std::pair
<PacketType
, PacketRef
> > PacketList
;
177 PacketList packet_list_
;
178 PacketList priority_packet_list_
;
180 struct PacketSendRecord
{
182 base::TimeTicks time
; // Time when the packet was sent.
183 int64 last_byte_sent
; // Number of bytes sent to network just after this
185 int64 last_byte_sent_for_audio
; // Number of bytes sent to network from
186 // audio stream just before this packet.
188 typedef std::map
<PacketKey
, PacketSendRecord
> PacketSendHistory
;
189 PacketSendHistory send_history_
;
190 PacketSendHistory send_history_buffer_
;
191 // Records the last byte sent for payload with a specific SSRC.
192 std::map
<uint32
, int64
> last_byte_sent_
;
194 size_t target_burst_size_
;
195 size_t max_burst_size_
;
197 // Maximum burst size for the next three bursts.
198 size_t current_max_burst_size_
;
199 size_t next_max_burst_size_
;
200 size_t next_next_max_burst_size_
;
201 // Number of packets already sent in the current burst.
202 size_t current_burst_size_
;
203 // This is when the current burst ends.
204 base::TimeTicks burst_end_
;
208 bool has_reached_upper_bound_once_
;
210 // NOTE: Weak pointers must be invalidated before all other member variables.
211 base::WeakPtrFactory
<PacedSender
> weak_factory_
;
213 DISALLOW_COPY_AND_ASSIGN(PacedSender
);
219 #endif // MEDIA_CAST_NET_PACING_PACED_SENDER_H_