| 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 |