OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 // Get an iterator pointing to the place in the buffer where the new packet | 93 // Get an iterator pointing to the place in the buffer where the new packet |
94 // should be inserted. The list is searched from the back, since the most | 94 // should be inserted. The list is searched from the back, since the most |
95 // likely case is that the new packet should be near the end of the list. | 95 // likely case is that the new packet should be near the end of the list. |
96 PacketList::reverse_iterator rit = std::find_if( | 96 PacketList::reverse_iterator rit = std::find_if( |
97 buffer_.rbegin(), buffer_.rend(), | 97 buffer_.rbegin(), buffer_.rend(), |
98 NewTimestampIsLarger(packet)); | 98 NewTimestampIsLarger(packet)); |
99 | 99 |
100 // The new packet is to be inserted to the right of |rit|. If it has the same | 100 // The new packet is to be inserted to the right of |rit|. If it has the same |
101 // timestamp as |rit|, which has a higher priority, do not insert the new | 101 // timestamp as |rit|, which has a higher priority, do not insert the new |
102 // packet to list. | 102 // packet to list. |
103 if (rit != buffer_.rend() && | 103 if (rit != buffer_.rend() && packet->timestamp == (*rit)->timestamp) { |
104 packet->header.timestamp == (*rit)->header.timestamp) { | |
105 delete packet; | 104 delete packet; |
106 return return_val; | 105 return return_val; |
107 } | 106 } |
108 | 107 |
109 // The new packet is to be inserted to the left of |it|. If it has the same | 108 // The new packet is to be inserted to the left of |it|. If it has the same |
110 // timestamp as |it|, which has a lower priority, replace |it| with the new | 109 // timestamp as |it|, which has a lower priority, replace |it| with the new |
111 // packet. | 110 // packet. |
112 PacketList::iterator it = rit.base(); | 111 PacketList::iterator it = rit.base(); |
113 if (it != buffer_.end() && | 112 if (it != buffer_.end() && packet->timestamp == (*it)->timestamp) { |
114 packet->header.timestamp == (*it)->header.timestamp) { | |
115 delete *it; | 113 delete *it; |
116 it = buffer_.erase(it); | 114 it = buffer_.erase(it); |
117 } | 115 } |
118 buffer_.insert(it, packet); // Insert the packet at that position. | 116 buffer_.insert(it, packet); // Insert the packet at that position. |
119 | 117 |
120 return return_val; | 118 return return_val; |
121 } | 119 } |
122 | 120 |
123 int PacketBuffer::InsertPacketList( | 121 int PacketBuffer::InsertPacketList( |
124 PacketList* packet_list, | 122 PacketList* packet_list, |
125 const DecoderDatabase& decoder_database, | 123 const DecoderDatabase& decoder_database, |
126 rtc::Optional<uint8_t>* current_rtp_payload_type, | 124 rtc::Optional<uint8_t>* current_rtp_payload_type, |
127 rtc::Optional<uint8_t>* current_cng_rtp_payload_type) { | 125 rtc::Optional<uint8_t>* current_cng_rtp_payload_type) { |
128 bool flushed = false; | 126 bool flushed = false; |
129 while (!packet_list->empty()) { | 127 while (!packet_list->empty()) { |
130 Packet* packet = packet_list->front(); | 128 Packet* packet = packet_list->front(); |
131 if (decoder_database.IsComfortNoise(packet->header.payloadType)) { | 129 if (decoder_database.IsComfortNoise(packet->payload_type)) { |
132 if (*current_cng_rtp_payload_type && | 130 if (*current_cng_rtp_payload_type && |
133 **current_cng_rtp_payload_type != packet->header.payloadType) { | 131 **current_cng_rtp_payload_type != packet->payload_type) { |
134 // New CNG payload type implies new codec type. | 132 // New CNG payload type implies new codec type. |
135 *current_rtp_payload_type = rtc::Optional<uint8_t>(); | 133 *current_rtp_payload_type = rtc::Optional<uint8_t>(); |
136 Flush(); | 134 Flush(); |
137 flushed = true; | 135 flushed = true; |
138 } | 136 } |
139 *current_cng_rtp_payload_type = | 137 *current_cng_rtp_payload_type = |
140 rtc::Optional<uint8_t>(packet->header.payloadType); | 138 rtc::Optional<uint8_t>(packet->payload_type); |
141 } else if (!decoder_database.IsDtmf(packet->header.payloadType)) { | 139 } else if (!decoder_database.IsDtmf(packet->payload_type)) { |
142 // This must be speech. | 140 // This must be speech. |
143 if ((*current_rtp_payload_type && | 141 if ((*current_rtp_payload_type && |
144 **current_rtp_payload_type != packet->header.payloadType) || | 142 **current_rtp_payload_type != packet->payload_type) || |
145 (*current_cng_rtp_payload_type && | 143 (*current_cng_rtp_payload_type && |
146 !EqualSampleRates(packet->header.payloadType, | 144 !EqualSampleRates(packet->payload_type, |
147 **current_cng_rtp_payload_type, | 145 **current_cng_rtp_payload_type, |
148 decoder_database))) { | 146 decoder_database))) { |
149 *current_cng_rtp_payload_type = rtc::Optional<uint8_t>(); | 147 *current_cng_rtp_payload_type = rtc::Optional<uint8_t>(); |
150 Flush(); | 148 Flush(); |
151 flushed = true; | 149 flushed = true; |
152 } | 150 } |
153 *current_rtp_payload_type = | 151 *current_rtp_payload_type = rtc::Optional<uint8_t>(packet->payload_type); |
154 rtc::Optional<uint8_t>(packet->header.payloadType); | |
155 } | 152 } |
156 int return_val = InsertPacket(packet); | 153 int return_val = InsertPacket(packet); |
157 packet_list->pop_front(); | 154 packet_list->pop_front(); |
158 if (return_val == kFlushed) { | 155 if (return_val == kFlushed) { |
159 // The buffer flushed, but this is not an error. We can still continue. | 156 // The buffer flushed, but this is not an error. We can still continue. |
160 flushed = true; | 157 flushed = true; |
161 } else if (return_val != kOK) { | 158 } else if (return_val != kOK) { |
162 // An error occurred. Delete remaining packets in list and return. | 159 // An error occurred. Delete remaining packets in list and return. |
163 DeleteAllPackets(packet_list); | 160 DeleteAllPackets(packet_list); |
164 return return_val; | 161 return return_val; |
165 } | 162 } |
166 } | 163 } |
167 return flushed ? kFlushed : kOK; | 164 return flushed ? kFlushed : kOK; |
168 } | 165 } |
169 | 166 |
170 int PacketBuffer::NextTimestamp(uint32_t* next_timestamp) const { | 167 int PacketBuffer::NextTimestamp(uint32_t* next_timestamp) const { |
171 if (Empty()) { | 168 if (Empty()) { |
172 return kBufferEmpty; | 169 return kBufferEmpty; |
173 } | 170 } |
174 if (!next_timestamp) { | 171 if (!next_timestamp) { |
175 return kInvalidPointer; | 172 return kInvalidPointer; |
176 } | 173 } |
177 *next_timestamp = buffer_.front()->header.timestamp; | 174 *next_timestamp = buffer_.front()->timestamp; |
178 return kOK; | 175 return kOK; |
179 } | 176 } |
180 | 177 |
181 int PacketBuffer::NextHigherTimestamp(uint32_t timestamp, | 178 int PacketBuffer::NextHigherTimestamp(uint32_t timestamp, |
182 uint32_t* next_timestamp) const { | 179 uint32_t* next_timestamp) const { |
183 if (Empty()) { | 180 if (Empty()) { |
184 return kBufferEmpty; | 181 return kBufferEmpty; |
185 } | 182 } |
186 if (!next_timestamp) { | 183 if (!next_timestamp) { |
187 return kInvalidPointer; | 184 return kInvalidPointer; |
188 } | 185 } |
189 PacketList::const_iterator it; | 186 PacketList::const_iterator it; |
190 for (it = buffer_.begin(); it != buffer_.end(); ++it) { | 187 for (it = buffer_.begin(); it != buffer_.end(); ++it) { |
191 if ((*it)->header.timestamp >= timestamp) { | 188 if ((*it)->timestamp >= timestamp) { |
192 // Found a packet matching the search. | 189 // Found a packet matching the search. |
193 *next_timestamp = (*it)->header.timestamp; | 190 *next_timestamp = (*it)->timestamp; |
194 return kOK; | 191 return kOK; |
195 } | 192 } |
196 } | 193 } |
197 return kNotFound; | 194 return kNotFound; |
198 } | 195 } |
199 | 196 |
200 const RTPHeader* PacketBuffer::NextRtpHeader() const { | 197 const Packet* PacketBuffer::PeekNextPacket() const { |
201 if (Empty()) { | 198 return buffer_.empty() ? nullptr : buffer_.front(); |
202 return NULL; | |
203 } | |
204 return const_cast<const RTPHeader*>(&(buffer_.front()->header)); | |
205 } | 199 } |
206 | 200 |
207 Packet* PacketBuffer::GetNextPacket(size_t* discard_count) { | 201 Packet* PacketBuffer::GetNextPacket(size_t* discard_count) { |
208 if (Empty()) { | 202 if (Empty()) { |
209 // Buffer is empty. | 203 // Buffer is empty. |
210 return NULL; | 204 return NULL; |
211 } | 205 } |
212 | 206 |
213 Packet* packet = buffer_.front(); | 207 Packet* packet = buffer_.front(); |
214 // Assert that the packet sanity checks in InsertPacket method works. | 208 // Assert that the packet sanity checks in InsertPacket method works. |
215 RTC_DCHECK(packet && !packet->empty()); | 209 RTC_DCHECK(packet && !packet->empty()); |
216 buffer_.pop_front(); | 210 buffer_.pop_front(); |
217 | 211 |
218 // Discard other packets with the same timestamp. These are duplicates or | 212 // Discard other packets with the same timestamp. These are duplicates or |
219 // redundant payloads that should not be used. | 213 // redundant payloads that should not be used. |
220 size_t discards = 0; | 214 size_t discards = 0; |
221 | 215 |
222 while (!Empty() && | 216 while (!Empty() && buffer_.front()->timestamp == packet->timestamp) { |
223 buffer_.front()->header.timestamp == packet->header.timestamp) { | |
224 if (DiscardNextPacket() != kOK) { | 217 if (DiscardNextPacket() != kOK) { |
225 assert(false); // Must be ok by design. | 218 assert(false); // Must be ok by design. |
226 } | 219 } |
227 ++discards; | 220 ++discards; |
228 } | 221 } |
229 // The way of inserting packet should not cause any packet discarding here. | 222 // The way of inserting packet should not cause any packet discarding here. |
230 // TODO(minyue): remove |discard_count|. | 223 // TODO(minyue): remove |discard_count|. |
231 assert(discards == 0); | 224 assert(discards == 0); |
232 if (discard_count) | 225 if (discard_count) |
233 *discard_count = discards; | 226 *discard_count = discards; |
234 | 227 |
235 return packet; | 228 return packet; |
236 } | 229 } |
237 | 230 |
238 int PacketBuffer::DiscardNextPacket() { | 231 int PacketBuffer::DiscardNextPacket() { |
239 if (Empty()) { | 232 if (Empty()) { |
240 return kBufferEmpty; | 233 return kBufferEmpty; |
241 } | 234 } |
242 // Assert that the packet sanity checks in InsertPacket method works. | 235 // Assert that the packet sanity checks in InsertPacket method works. |
243 RTC_DCHECK(buffer_.front()); | 236 RTC_DCHECK(buffer_.front()); |
244 RTC_DCHECK(!buffer_.front()->empty()); | 237 RTC_DCHECK(!buffer_.front()->empty()); |
245 DeleteFirstPacket(&buffer_); | 238 DeleteFirstPacket(&buffer_); |
246 return kOK; | 239 return kOK; |
247 } | 240 } |
248 | 241 |
249 int PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit, | 242 int PacketBuffer::DiscardOldPackets(uint32_t timestamp_limit, |
250 uint32_t horizon_samples) { | 243 uint32_t horizon_samples) { |
251 while (!Empty() && timestamp_limit != buffer_.front()->header.timestamp && | 244 while (!Empty() && timestamp_limit != buffer_.front()->timestamp && |
252 IsObsoleteTimestamp(buffer_.front()->header.timestamp, | 245 IsObsoleteTimestamp(buffer_.front()->timestamp, timestamp_limit, |
253 timestamp_limit, | |
254 horizon_samples)) { | 246 horizon_samples)) { |
255 if (DiscardNextPacket() != kOK) { | 247 if (DiscardNextPacket() != kOK) { |
256 assert(false); // Must be ok by design. | 248 assert(false); // Must be ok by design. |
257 } | 249 } |
258 } | 250 } |
259 return 0; | 251 return 0; |
260 } | 252 } |
261 | 253 |
262 int PacketBuffer::DiscardAllOldPackets(uint32_t timestamp_limit) { | 254 int PacketBuffer::DiscardAllOldPackets(uint32_t timestamp_limit) { |
263 return DiscardOldPackets(timestamp_limit, 0); | 255 return DiscardOldPackets(timestamp_limit, 0); |
264 } | 256 } |
265 | 257 |
266 void PacketBuffer::DiscardPacketsWithPayloadType(uint8_t payload_type) { | 258 void PacketBuffer::DiscardPacketsWithPayloadType(uint8_t payload_type) { |
267 for (auto it = buffer_.begin(); it != buffer_.end(); /* */) { | 259 for (auto it = buffer_.begin(); it != buffer_.end(); /* */) { |
268 Packet* packet = *it; | 260 Packet* packet = *it; |
269 if (packet->header.payloadType == payload_type) { | 261 if (packet->payload_type == payload_type) { |
270 delete packet; | 262 delete packet; |
271 it = buffer_.erase(it); | 263 it = buffer_.erase(it); |
272 } else { | 264 } else { |
273 ++it; | 265 ++it; |
274 } | 266 } |
275 } | 267 } |
276 } | 268 } |
277 | 269 |
278 size_t PacketBuffer::NumPacketsInBuffer() const { | 270 size_t PacketBuffer::NumPacketsInBuffer() const { |
279 return buffer_.size(); | 271 return buffer_.size(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 // Continue while the list is not empty. | 306 // Continue while the list is not empty. |
315 } | 307 } |
316 } | 308 } |
317 | 309 |
318 void PacketBuffer::BufferStat(int* num_packets, int* max_num_packets) const { | 310 void PacketBuffer::BufferStat(int* num_packets, int* max_num_packets) const { |
319 *num_packets = static_cast<int>(buffer_.size()); | 311 *num_packets = static_cast<int>(buffer_.size()); |
320 *max_num_packets = static_cast<int>(max_number_of_packets_); | 312 *max_num_packets = static_cast<int>(max_number_of_packets_); |
321 } | 313 } |
322 | 314 |
323 } // namespace webrtc | 315 } // namespace webrtc |
OLD | NEW |