OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 } | 190 } |
191 if (sequence_buffer_[prev_index].continuous) | 191 if (sequence_buffer_[prev_index].continuous) |
192 return true; | 192 return true; |
193 | 193 |
194 return false; | 194 return false; |
195 } | 195 } |
196 | 196 |
197 std::vector<std::unique_ptr<RtpFrameObject>> PacketBuffer::FindFrames( | 197 std::vector<std::unique_ptr<RtpFrameObject>> PacketBuffer::FindFrames( |
198 uint16_t seq_num) { | 198 uint16_t seq_num) { |
199 std::vector<std::unique_ptr<RtpFrameObject>> found_frames; | 199 std::vector<std::unique_ptr<RtpFrameObject>> found_frames; |
200 size_t packets_tested = 0; | 200 for (size_t i = 0; i < size_ && PotentialNewFrame(seq_num); ++i) { |
201 while (packets_tested < size_ && PotentialNewFrame(seq_num)) { | |
202 size_t index = seq_num % size_; | 201 size_t index = seq_num % size_; |
203 sequence_buffer_[index].continuous = true; | 202 sequence_buffer_[index].continuous = true; |
204 | 203 |
205 // If all packets of the frame is continuous, find the first packet of the | 204 // If all packets of the frame is continuous, find the first packet of the |
206 // frame and create an RtpFrameObject. | 205 // frame and create an RtpFrameObject. |
207 if (sequence_buffer_[index].frame_end) { | 206 if (sequence_buffer_[index].frame_end) { |
208 size_t frame_size = 0; | 207 size_t frame_size = 0; |
209 int max_nack_count = -1; | 208 int max_nack_count = -1; |
210 uint16_t start_seq_num = seq_num; | 209 uint16_t start_seq_num = seq_num; |
211 | 210 |
212 // Find the start index by searching backward until the packet with | 211 // Find the start index by searching backward until the packet with |
213 // the |frame_begin| flag is set. | 212 // the |frame_begin| flag is set. |
214 int start_index = index; | 213 int start_index = index; |
215 | 214 |
216 bool is_h264 = data_buffer_[start_index].codec == kVideoCodecH264; | 215 bool is_h264 = data_buffer_[start_index].codec == kVideoCodecH264; |
217 int64_t frame_timestamp = data_buffer_[start_index].timestamp; | 216 int64_t frame_timestamp = data_buffer_[start_index].timestamp; |
218 while (true) { | 217 |
| 218 // Since packet at |data_buffer_[index]| is already part of the frame |
| 219 // we will have at most |size_ - 1| packets left to check. |
| 220 for (size_t j = 0; j < size_ - 1; ++j) { |
219 frame_size += data_buffer_[start_index].sizeBytes; | 221 frame_size += data_buffer_[start_index].sizeBytes; |
220 max_nack_count = | 222 max_nack_count = |
221 std::max(max_nack_count, data_buffer_[start_index].timesNacked); | 223 std::max(max_nack_count, data_buffer_[start_index].timesNacked); |
222 sequence_buffer_[start_index].frame_created = true; | 224 sequence_buffer_[start_index].frame_created = true; |
223 | 225 |
224 if (!is_h264 && sequence_buffer_[start_index].frame_begin) | 226 if (!is_h264 && sequence_buffer_[start_index].frame_begin) |
225 break; | 227 break; |
226 | 228 |
227 start_index = start_index > 0 ? start_index - 1 : size_ - 1; | 229 start_index = start_index > 0 ? start_index - 1 : size_ - 1; |
228 | 230 |
229 // In the case of H264 we don't have a frame_begin bit (yes, | 231 // In the case of H264 we don't have a frame_begin bit (yes, |
230 // |frame_begin| might be set to true but that is a lie). So instead | 232 // |frame_begin| might be set to true but that is a lie). So instead |
231 // we traverese backwards as long as we have a previous packet and | 233 // we traverese backwards as long as we have a previous packet and |
232 // the timestamp of that packet is the same as this one. This may cause | 234 // the timestamp of that packet is the same as this one. This may cause |
233 // the PacketBuffer to hand out incomplete frames. | 235 // the PacketBuffer to hand out incomplete frames. |
234 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7106 | 236 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7106 |
235 // | 237 if (is_h264 && |
236 // Since we ignore the |frame_begin| flag of the inserted packets | |
237 // we check that |start_index != static_cast<int>(index)| to make sure | |
238 // that we don't get stuck in a loop if the packet buffer is filled | |
239 // with packets of the same timestamp. | |
240 if (is_h264 && start_index != static_cast<int>(index) && | |
241 (!sequence_buffer_[start_index].used || | 238 (!sequence_buffer_[start_index].used || |
242 data_buffer_[start_index].timestamp != frame_timestamp)) { | 239 data_buffer_[start_index].timestamp != frame_timestamp)) { |
243 break; | 240 break; |
244 } | 241 } |
245 | 242 |
246 --start_seq_num; | 243 --start_seq_num; |
247 } | 244 } |
248 | 245 |
249 found_frames.emplace_back( | 246 found_frames.emplace_back( |
250 new RtpFrameObject(this, start_seq_num, seq_num, frame_size, | 247 new RtpFrameObject(this, start_seq_num, seq_num, frame_size, |
251 max_nack_count, clock_->TimeInMilliseconds())); | 248 max_nack_count, clock_->TimeInMilliseconds())); |
252 } | 249 } |
253 ++seq_num; | 250 ++seq_num; |
254 ++packets_tested; | |
255 } | 251 } |
256 return found_frames; | 252 return found_frames; |
257 } | 253 } |
258 | 254 |
259 void PacketBuffer::ReturnFrame(RtpFrameObject* frame) { | 255 void PacketBuffer::ReturnFrame(RtpFrameObject* frame) { |
260 rtc::CritScope lock(&crit_); | 256 rtc::CritScope lock(&crit_); |
261 size_t index = frame->first_seq_num() % size_; | 257 size_t index = frame->first_seq_num() % size_; |
262 size_t end = (frame->last_seq_num() + 1) % size_; | 258 size_t end = (frame->last_seq_num() + 1) % size_; |
263 uint16_t seq_num = frame->first_seq_num(); | 259 uint16_t seq_num = frame->first_seq_num(); |
264 while (index != end) { | 260 while (index != end) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 int PacketBuffer::Release() const { | 308 int PacketBuffer::Release() const { |
313 int count = rtc::AtomicOps::Decrement(&ref_count_); | 309 int count = rtc::AtomicOps::Decrement(&ref_count_); |
314 if (!count) { | 310 if (!count) { |
315 delete this; | 311 delete this; |
316 } | 312 } |
317 return count; | 313 return count; |
318 } | 314 } |
319 | 315 |
320 } // namespace video_coding | 316 } // namespace video_coding |
321 } // namespace webrtc | 317 } // namespace webrtc |
OLD | NEW |