Home | History | Annotate | Download | only in pacing
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef MEDIA_CAST_TRANSPORT_PACING_PACED_SENDER_H_
      6 #define MEDIA_CAST_TRANSPORT_PACING_PACED_SENDER_H_
      7 
      8 #include <list>
      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/transport/cast_transport_config.h"
     20 #include "media/cast/transport/transport/udp_transport.h"
     21 
     22 namespace media {
     23 namespace cast {
     24 
     25 class LoggingImpl;
     26 
     27 namespace transport {
     28 
     29 // Use std::pair for free comparison operators.
     30 // { capture_time, ssrc, packet_id }
     31 // The PacketKey is designed to meet two criteria:
     32 // 1. When we re-send the same packet again, we can use the packet key
     33 //    to identify it so that we can de-duplicate packets in the queue.
     34 // 2. The sort order of the PacketKey determines the order that packets
     35 //    are sent out. Using the capture_time as the first member basically
     36 //    means that older packets are sent first.
     37 typedef std::pair<base::TimeTicks, std::pair<uint32, uint16> > PacketKey;
     38 typedef std::vector<std::pair<PacketKey, PacketRef> > SendPacketVector;
     39 
     40 // We have this pure virtual class to enable mocking.
     41 class PacedPacketSender {
     42  public:
     43   virtual bool SendPackets(const SendPacketVector& packets) = 0;
     44   virtual bool ResendPackets(const SendPacketVector& packets,
     45                              base::TimeDelta dedupe_window) = 0;
     46   virtual bool SendRtcpPacket(uint32 ssrc, PacketRef packet) = 0;
     47   virtual void CancelSendingPacket(const PacketKey& packet_key) = 0;
     48 
     49   virtual ~PacedPacketSender() {}
     50 
     51   static PacketKey MakePacketKey(const base::TimeTicks& ticks,
     52                                  uint32 ssrc,
     53                                  uint16 packet_id);
     54 };
     55 
     56 class PacedSender : public PacedPacketSender,
     57                     public base::NonThreadSafe,
     58                     public base::SupportsWeakPtr<PacedSender> {
     59  public:
     60   // The |external_transport| should only be used by the Cast receiver and for
     61   // testing.
     62   PacedSender(
     63       base::TickClock* clock,
     64       LoggingImpl* logging,
     65       PacketSender* external_transport,
     66       const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner);
     67 
     68   virtual ~PacedSender();
     69 
     70   // These must be called before non-RTCP packets are sent.
     71   void RegisterAudioSsrc(uint32 audio_ssrc);
     72   void RegisterVideoSsrc(uint32 video_ssrc);
     73 
     74   // PacedPacketSender implementation.
     75   virtual bool SendPackets(const SendPacketVector& packets) OVERRIDE;
     76   virtual bool ResendPackets(const SendPacketVector& packets,
     77                              base::TimeDelta dedupe_window) OVERRIDE;
     78   virtual bool SendRtcpPacket(uint32 ssrc, PacketRef packet) OVERRIDE;
     79   virtual void CancelSendingPacket(const PacketKey& packet_key) OVERRIDE;
     80 
     81  private:
     82   // Actually sends the packets to the transport.
     83   void SendStoredPackets();
     84   void LogPacketEvent(const Packet& packet, CastLoggingEvent event);
     85 
     86   enum PacketType {
     87     PacketType_RTCP,
     88     PacketType_Resend,
     89     PacketType_Normal
     90   };
     91   enum State {
     92     // In an unblocked state, we can send more packets.
     93     // We have to check the current time against |burst_end_| to see if we are
     94     // appending to the current burst or if we can start a new one.
     95     State_Unblocked,
     96     // In this state, we are waiting for a callback from the udp transport.
     97     // This happens when the OS-level buffer is full. Once we receive the
     98     // callback, we go to State_Unblocked and see if we can write more packets
     99     // to the current burst. (Or the next burst if enough time has passed.)
    100     State_TransportBlocked,
    101     // Once we've written enough packets for a time slice, we go into this
    102     // state and PostDelayTask a call to ourselves to wake up when we can
    103     // send more data.
    104     State_BurstFull
    105   };
    106 
    107   bool empty() const;
    108   size_t size() const;
    109 
    110   // Returns the next packet to send. RTCP packets have highest priority,
    111   // resend packets have second highest priority and then comes everything
    112   // else.
    113   PacketRef GetNextPacket(PacketType* packet_type,
    114                           PacketKey* packet_key);
    115 
    116   base::TickClock* const clock_;  // Not owned by this class.
    117   LoggingImpl* const logging_;    // Not owned by this class.
    118   PacketSender* transport_;       // Not owned by this class.
    119   scoped_refptr<base::SingleThreadTaskRunner> transport_task_runner_;
    120   uint32 audio_ssrc_;
    121   uint32 video_ssrc_;
    122   std::map<PacketKey, std::pair<PacketType, PacketRef> > packet_list_;
    123   std::map<PacketKey, base::TimeTicks> sent_time_;
    124   std::map<PacketKey, base::TimeTicks> sent_time_buffer_;
    125 
    126   // Maximum burst size for the next three bursts.
    127   size_t max_burst_size_;
    128   size_t next_max_burst_size_;
    129   size_t next_next_max_burst_size_;
    130   // Number of packets already sent in the current burst.
    131   size_t current_burst_size_;
    132   // This is when the current burst ends.
    133   base::TimeTicks burst_end_;
    134 
    135   State state_;
    136 
    137   // NOTE: Weak pointers must be invalidated before all other member variables.
    138   base::WeakPtrFactory<PacedSender> weak_factory_;
    139 
    140   DISALLOW_COPY_AND_ASSIGN(PacedSender);
    141 };
    142 
    143 }  // namespace transport
    144 }  // namespace cast
    145 }  // namespace media
    146 
    147 #endif  // MEDIA_CAST_TRANSPORT_PACING_PACED_SENDER_H_
    148