Home | History | Annotate | Download | only in pacing
      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.
      4 
      5 #ifndef MEDIA_CAST_NET_PACING_PACED_SENDER_H_
      6 #define MEDIA_CAST_NET_PACING_PACED_SENDER_H_
      7 
      8 #include <map>
      9 #include <vector>
     10 
     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"
     21 
     22 namespace media {
     23 namespace cast {
     24 
     25 // Meant to use as defaults for pacer construction.
     26 static const size_t kTargetBurstSize = 10;
     27 static const size_t kMaxBurstSize = 20;
     28 
     29 class LoggingImpl;
     30 
     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;
     41 
     42 // Information used to deduplicate retransmission packets.
     43 // There are two criteria for deduplication.
     44 //
     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
     51 //    information.
     52 //
     53 // 2. Using a time interval.
     54 //    Time between sending the same packet must be greater than
     55 //    |resend_interval|.
     56 struct DedupInfo {
     57   DedupInfo();
     58   base::TimeDelta resend_interval;
     59   int64 last_byte_acked_for_audio;
     60 };
     61 
     62 // We have this pure virtual class to enable mocking.
     63 class PacedPacketSender {
     64  public:
     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;
     70 
     71   virtual ~PacedPacketSender() {}
     72 
     73   static PacketKey MakePacketKey(const base::TimeTicks& ticks,
     74                                  uint32 ssrc,
     75                                  uint16 packet_id);
     76 };
     77 
     78 class PacedSender : public PacedPacketSender,
     79                     public base::NonThreadSafe,
     80                     public base::SupportsWeakPtr<PacedSender> {
     81  public:
     82   // The |external_transport| should only be used by the Cast receiver and for
     83   // testing.
     84   PacedSender(
     85       size_t target_burst_size,  // Should normally be kTargetBurstSize.
     86       size_t max_burst_size,     // Should normally be kMaxBurstSize.
     87       base::TickClock* clock,
     88       LoggingImpl* logging,
     89       PacketSender* external_transport,
     90       const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner);
     91 
     92   virtual ~PacedSender();
     93 
     94   // These must be called before non-RTCP packets are sent.
     95   void RegisterAudioSsrc(uint32 audio_ssrc);
     96   void RegisterVideoSsrc(uint32 video_ssrc);
     97 
     98   // Register SSRC that has a higher priority for sending. Multiple SSRCs can
     99   // be registered.
    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);
    103 
    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);
    108 
    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);
    112 
    113   // PacedPacketSender implementation.
    114   virtual bool SendPackets(const SendPacketVector& packets) OVERRIDE;
    115   virtual bool ResendPackets(const SendPacketVector& packets,
    116                              const DedupInfo& dedup_info) OVERRIDE;
    117   virtual bool SendRtcpPacket(uint32 ssrc, PacketRef packet) OVERRIDE;
    118   virtual void CancelSendingPacket(const PacketKey& packet_key) OVERRIDE;
    119 
    120  private:
    121   // Actually sends the packets to the transport.
    122   void SendStoredPackets();
    123   void LogPacketEvent(const Packet& packet, CastLoggingEvent event);
    124 
    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);
    132 
    133   enum PacketType {
    134     PacketType_RTCP,
    135     PacketType_Resend,
    136     PacketType_Normal
    137   };
    138   enum State {
    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.
    142     State_Unblocked,
    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
    150     // send more data.
    151     State_BurstFull
    152   };
    153 
    154   bool empty() const;
    155   size_t size() const;
    156 
    157   // Returns the next packet to send. RTCP packets have highest priority,
    158   // resend packets have second highest priority and then comes everything
    159   // else.
    160   PacketRef PopNextPacket(PacketType* packet_type,
    161                           PacketKey* packet_key);
    162 
    163   // Returns true if the packet should have a higher priority.
    164   bool IsHighPriority(const PacketKey& packet_key) const;
    165 
    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_;
    170   uint32 audio_ssrc_;
    171   uint32 video_ssrc_;
    172 
    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_;
    179 
    180   struct PacketSendRecord {
    181     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
    184                            // packet was sent.
    185     int64 last_byte_sent_for_audio;  // Number of bytes sent to network from
    186                                      // audio stream just before this packet.
    187   };
    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_;
    193 
    194   size_t target_burst_size_;
    195   size_t max_burst_size_;
    196 
    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_;
    205 
    206   State state_;
    207 
    208   bool has_reached_upper_bound_once_;
    209 
    210   // NOTE: Weak pointers must be invalidated before all other member variables.
    211   base::WeakPtrFactory<PacedSender> weak_factory_;
    212 
    213   DISALLOW_COPY_AND_ASSIGN(PacedSender);
    214 };
    215 
    216 }  // namespace cast
    217 }  // namespace media
    218 
    219 #endif  // MEDIA_CAST_NET_PACING_PACED_SENDER_H_
    220