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