OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/cast/transport/pacing/paced_sender.h" | 5 #include "media/cast/transport/pacing/paced_sender.h" |
6 | 6 |
7 #include "base/big_endian.h" | 7 #include "base/big_endian.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... | |
28 return is_audio ? media::cast::kAudioPacketRetransmitted | 28 return is_audio ? media::cast::kAudioPacketRetransmitted |
29 : media::cast::kVideoPacketRetransmitted; | 29 : media::cast::kVideoPacketRetransmitted; |
30 } else { | 30 } else { |
31 return is_audio ? media::cast::kAudioPacketSentToNetwork | 31 return is_audio ? media::cast::kAudioPacketSentToNetwork |
32 : media::cast::kVideoPacketSentToNetwork; | 32 : media::cast::kVideoPacketSentToNetwork; |
33 } | 33 } |
34 } | 34 } |
35 | 35 |
36 } // namespace | 36 } // namespace |
37 | 37 |
38 | |
39 PacketKey PacedPacketSender::MakePacketKey(const base::TimeTicks& ticks, | |
40 unsigned int ssrc, | |
41 uint16 packet_id) { | |
42 return std::make_pair(ticks, std::make_pair(ssrc, packet_id)); | |
43 } | |
44 | |
38 PacedSender::PacedSender( | 45 PacedSender::PacedSender( |
39 base::TickClock* clock, | 46 base::TickClock* clock, |
40 LoggingImpl* logging, | 47 LoggingImpl* logging, |
41 PacketSender* transport, | 48 PacketSender* transport, |
42 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) | 49 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) |
43 : clock_(clock), | 50 : clock_(clock), |
44 logging_(logging), | 51 logging_(logging), |
45 transport_(transport), | 52 transport_(transport), |
46 transport_task_runner_(transport_task_runner), | 53 transport_task_runner_(transport_task_runner), |
47 audio_ssrc_(0), | 54 audio_ssrc_(0), |
48 video_ssrc_(0), | 55 video_ssrc_(0), |
49 max_burst_size_(kTargetBurstSize), | 56 max_burst_size_(kTargetBurstSize), |
50 next_max_burst_size_(kTargetBurstSize), | 57 next_max_burst_size_(kTargetBurstSize), |
51 next_next_max_burst_size_(kTargetBurstSize), | 58 next_next_max_burst_size_(kTargetBurstSize), |
52 current_burst_size_(0), | 59 current_burst_size_(0), |
53 state_(State_Unblocked), | 60 state_(State_Unblocked), |
54 weak_factory_(this) { | 61 weak_factory_(this) { |
55 } | 62 } |
56 | 63 |
57 PacedSender::~PacedSender() {} | 64 PacedSender::~PacedSender() {} |
58 | 65 |
59 void PacedSender::RegisterAudioSsrc(uint32 audio_ssrc) { | 66 void PacedSender::RegisterAudioSsrc(uint32 audio_ssrc) { |
60 audio_ssrc_ = audio_ssrc; | 67 audio_ssrc_ = audio_ssrc; |
61 } | 68 } |
62 | 69 |
63 void PacedSender::RegisterVideoSsrc(uint32 video_ssrc) { | 70 void PacedSender::RegisterVideoSsrc(uint32 video_ssrc) { |
64 video_ssrc_ = video_ssrc; | 71 video_ssrc_ = video_ssrc; |
65 } | 72 } |
66 | 73 |
67 bool PacedSender::SendPackets(const PacketList& packets) { | 74 bool PacedSender::SendPackets(const SendPacketVector& packets) { |
68 if (packets.empty()) { | 75 if (packets.empty()) { |
69 return true; | 76 return true; |
70 } | 77 } |
71 packet_list_.insert(packet_list_.end(), packets.begin(), packets.end()); | 78 for (size_t i = 0; i < packets.size(); i++) { |
79 packet_list_[packets[i].first] = | |
80 make_pair(PacketType_Normal, packets[i].second); | |
81 } | |
72 if (state_ == State_Unblocked) { | 82 if (state_ == State_Unblocked) { |
73 SendStoredPackets(); | 83 SendStoredPackets(); |
74 } | 84 } |
75 return true; | 85 return true; |
76 } | 86 } |
77 | 87 |
78 bool PacedSender::ResendPackets(const PacketList& packets) { | 88 bool PacedSender::ResendPackets(const SendPacketVector& packets) { |
79 if (packets.empty()) { | 89 if (packets.empty()) { |
80 return true; | 90 return true; |
81 } | 91 } |
82 resend_packet_list_.insert(resend_packet_list_.end(), | 92 for (size_t i = 0; i < packets.size(); i++) { |
83 packets.begin(), | 93 packet_list_[packets[i].first] = |
84 packets.end()); | 94 make_pair(PacketType_Resend, packets[i].second); |
95 } | |
85 if (state_ == State_Unblocked) { | 96 if (state_ == State_Unblocked) { |
86 SendStoredPackets(); | 97 SendStoredPackets(); |
87 } | 98 } |
88 return true; | 99 return true; |
89 } | 100 } |
90 | 101 |
91 bool PacedSender::SendRtcpPacket(PacketRef packet) { | 102 bool PacedSender::SendRtcpPacket(unsigned int ssrc, PacketRef packet) { |
92 if (state_ == State_TransportBlocked) { | 103 if (state_ == State_TransportBlocked) { |
93 | 104 packet_list_[PacedPacketSender::MakePacketKey(base::TimeTicks(), ssrc, 0)] = |
94 rtcp_packet_list_.push_back(packet); | 105 make_pair(PacketType_RTCP, packet); |
95 } else { | 106 } else { |
96 // We pass the RTCP packets straight through. | 107 // We pass the RTCP packets straight through. |
97 if (!transport_->SendPacket( | 108 if (!transport_->SendPacket( |
98 packet, | 109 packet, |
99 base::Bind(&PacedSender::SendStoredPackets, | 110 base::Bind(&PacedSender::SendStoredPackets, |
100 weak_factory_.GetWeakPtr()))) { | 111 weak_factory_.GetWeakPtr()))) { |
101 state_ = State_TransportBlocked; | 112 state_ = State_TransportBlocked; |
102 } | 113 } |
103 | 114 |
104 } | 115 } |
105 return true; | 116 return true; |
106 } | 117 } |
107 | 118 |
108 PacketRef PacedSender::GetNextPacket(PacketType* packet_type) { | 119 PacketRef PacedSender::GetNextPacket(PacketType* packet_type) { |
109 PacketRef ret; | 120 std::map<PacketKey, std::pair<PacketType, PacketRef> >::iterator i; |
110 if (!rtcp_packet_list_.empty()) { | 121 i = packet_list_.begin(); |
111 ret = rtcp_packet_list_.front(); | 122 *packet_type = i->second.first; |
miu
2014/04/24 00:09:06
nit: Suggest DCHECK(i != packet_list_.end());
hubbe
2014/04/24 18:36:42
Done.
| |
112 rtcp_packet_list_.pop_front(); | 123 PacketRef ret = i->second.second; |
113 *packet_type = PacketType_RTCP; | 124 packet_list_.erase(i); |
114 } else if (!resend_packet_list_.empty()) { | |
115 ret = resend_packet_list_.front(); | |
116 resend_packet_list_.pop_front(); | |
117 *packet_type = PacketType_Resend; | |
118 } else if (!packet_list_.empty()) { | |
119 ret = packet_list_.front(); | |
120 packet_list_.pop_front(); | |
121 *packet_type = PacketType_Normal; | |
122 } else { | |
123 NOTREACHED(); | |
124 } | |
125 return ret; | 125 return ret; |
126 } | 126 } |
127 | 127 |
128 bool PacedSender::empty() const { | 128 bool PacedSender::empty() const { |
129 return rtcp_packet_list_.empty() && | 129 return packet_list_.empty(); |
130 resend_packet_list_.empty() && | |
131 packet_list_.empty(); | |
132 } | 130 } |
133 | 131 |
134 size_t PacedSender::size() const { | 132 size_t PacedSender::size() const { |
135 return rtcp_packet_list_.size() + | 133 return packet_list_.size(); |
136 resend_packet_list_.size() + | |
137 packet_list_.size(); | |
138 } | 134 } |
139 | 135 |
140 // This function can be called from three places: | 136 // This function can be called from three places: |
141 // 1. User called one of the Send* functions and we were in an unblocked state. | 137 // 1. User called one of the Send* functions and we were in an unblocked state. |
142 // 2. state_ == State_TransportBlocked and the transport is calling us to | 138 // 2. state_ == State_TransportBlocked and the transport is calling us to |
143 // let us know that it's ok to send again. | 139 // let us know that it's ok to send again. |
144 // 3. state_ == State_BurstFull and there are still packets to send. In this | 140 // 3. state_ == State_BurstFull and there are still packets to send. In this |
145 // case we called PostDelayedTask on this function to start a new burst. | 141 // case we called PostDelayedTask on this function to start a new burst. |
146 void PacedSender::SendStoredPackets() { | 142 void PacedSender::SendStoredPackets() { |
147 State previous_state = state_; | 143 State previous_state = state_; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 } | 232 } |
237 | 233 |
238 CastLoggingEvent event = GetLoggingEvent(is_audio, retransmit); | 234 CastLoggingEvent event = GetLoggingEvent(is_audio, retransmit); |
239 | 235 |
240 logging_->InsertSinglePacketEvent(clock_->NowTicks(), event, packet); | 236 logging_->InsertSinglePacketEvent(clock_->NowTicks(), event, packet); |
241 } | 237 } |
242 | 238 |
243 } // namespace transport | 239 } // namespace transport |
244 } // namespace cast | 240 } // namespace cast |
245 } // namespace media | 241 } // namespace media |
OLD | NEW |