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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 // If all packets of the frame is continuous, find the first packet of the | 244 // If all packets of the frame is continuous, find the first packet of the |
245 // frame and create an RtpFrameObject. | 245 // frame and create an RtpFrameObject. |
246 if (sequence_buffer_[index].frame_end) { | 246 if (sequence_buffer_[index].frame_end) { |
247 size_t frame_size = 0; | 247 size_t frame_size = 0; |
248 int max_nack_count = -1; | 248 int max_nack_count = -1; |
249 uint16_t start_seq_num = seq_num; | 249 uint16_t start_seq_num = seq_num; |
250 | 250 |
251 // Find the start index by searching backward until the packet with | 251 // Find the start index by searching backward until the packet with |
252 // the |frame_begin| flag is set. | 252 // the |frame_begin| flag is set. |
253 int start_index = index; | 253 int start_index = index; |
254 size_t tested_packets = 0; | |
254 | 255 |
255 bool is_h264 = data_buffer_[start_index].codec == kVideoCodecH264; | 256 bool is_h264 = data_buffer_[start_index].codec == kVideoCodecH264; |
256 bool is_h264_keyframe = false; | 257 bool is_h264_keyframe = false; |
257 int64_t frame_timestamp = data_buffer_[start_index].timestamp; | 258 int64_t frame_timestamp = data_buffer_[start_index].timestamp; |
258 | 259 |
259 // Since packet at |data_buffer_[index]| is already part of the frame | 260 while (true) { |
260 // we will have at most |size_ - 1| packets left to check. | 261 ++tested_packets; |
stefan-webrtc
2017/08/01 11:24:17
Was this comment not correct? Looks like we have c
philipel
2017/08/01 11:51:23
It was semi-correct. In this version |start_seq_nu
| |
261 for (size_t j = 0; j < size_ - 1; ++j) { | |
262 frame_size += data_buffer_[start_index].sizeBytes; | 262 frame_size += data_buffer_[start_index].sizeBytes; |
263 max_nack_count = | 263 max_nack_count = |
264 std::max(max_nack_count, data_buffer_[start_index].timesNacked); | 264 std::max(max_nack_count, data_buffer_[start_index].timesNacked); |
265 sequence_buffer_[start_index].frame_created = true; | 265 sequence_buffer_[start_index].frame_created = true; |
266 | 266 |
267 if (!is_h264 && sequence_buffer_[start_index].frame_begin) | 267 if (!is_h264 && sequence_buffer_[start_index].frame_begin) |
268 break; | 268 break; |
269 | 269 |
270 if (is_h264 && !is_h264_keyframe) { | 270 if (is_h264 && !is_h264_keyframe) { |
271 const RTPVideoHeaderH264& header = | 271 const RTPVideoHeaderH264& header = |
272 data_buffer_[start_index].video_header.codecHeader.H264; | 272 data_buffer_[start_index].video_header.codecHeader.H264; |
273 for (size_t i = 0; i < header.nalus_length; ++i) { | 273 for (size_t i = 0; i < header.nalus_length; ++i) { |
274 if (header.nalus[i].type == H264::NaluType::kIdr) { | 274 if (header.nalus[i].type == H264::NaluType::kIdr) { |
275 is_h264_keyframe = true; | 275 is_h264_keyframe = true; |
276 break; | 276 break; |
277 } | 277 } |
278 } | 278 } |
279 } | 279 } |
280 | 280 |
281 if (tested_packets == size_) | |
282 break; | |
283 | |
281 start_index = start_index > 0 ? start_index - 1 : size_ - 1; | 284 start_index = start_index > 0 ? start_index - 1 : size_ - 1; |
282 | 285 |
283 // In the case of H264 we don't have a frame_begin bit (yes, | 286 // In the case of H264 we don't have a frame_begin bit (yes, |
284 // |frame_begin| might be set to true but that is a lie). So instead | 287 // |frame_begin| might be set to true but that is a lie). So instead |
285 // we traverese backwards as long as we have a previous packet and | 288 // we traverese backwards as long as we have a previous packet and |
286 // the timestamp of that packet is the same as this one. This may cause | 289 // the timestamp of that packet is the same as this one. This may cause |
287 // the PacketBuffer to hand out incomplete frames. | 290 // the PacketBuffer to hand out incomplete frames. |
288 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7106 | 291 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7106 |
289 if (is_h264 && | 292 if (is_h264 && |
290 (!sequence_buffer_[start_index].used || | 293 (!sequence_buffer_[start_index].used || |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 } | 341 } |
339 } | 342 } |
340 | 343 |
341 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame, | 344 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame, |
342 uint8_t* destination) { | 345 uint8_t* destination) { |
343 rtc::CritScope lock(&crit_); | 346 rtc::CritScope lock(&crit_); |
344 | 347 |
345 size_t index = frame.first_seq_num() % size_; | 348 size_t index = frame.first_seq_num() % size_; |
346 size_t end = (frame.last_seq_num() + 1) % size_; | 349 size_t end = (frame.last_seq_num() + 1) % size_; |
347 uint16_t seq_num = frame.first_seq_num(); | 350 uint16_t seq_num = frame.first_seq_num(); |
348 while (index != end) { | 351 uint8_t* destination_end = destination + frame.size(); |
352 | |
353 do { | |
349 if (!sequence_buffer_[index].used || | 354 if (!sequence_buffer_[index].used || |
350 sequence_buffer_[index].seq_num != seq_num) { | 355 sequence_buffer_[index].seq_num != seq_num || |
356 data_buffer_[index].seqNum != seq_num) { | |
stefan-webrtc
2017/08/01 11:24:17
What does this mean? That the frame doesn't have a
philipel
2017/08/01 11:51:23
It should not happen, no. I'll change it to a DCHE
stefan-webrtc
2017/08/01 12:06:22
Is it safe to CHECK, or is it possible to trigger
philipel
2017/08/01 13:00:05
It should not be possible to have the sequence_buf
stefan-webrtc
2017/08/01 15:14:52
My question was if it should be a CHECK instead. B
| |
351 return false; | 357 return false; |
352 } | 358 } |
353 | 359 |
360 size_t length = data_buffer_[index].sizeBytes; | |
361 if (destination + length > destination_end) | |
362 return false; | |
stefan-webrtc
2017/08/01 11:24:17
Should we log that the frame is too large for the
philipel
2017/08/01 11:51:23
This check is not really related to the bug at han
stefan-webrtc
2017/08/01 12:06:22
Right, but it means that the frame is too large. W
philipel
2017/08/01 13:00:05
Added warning if this happens.
| |
363 | |
354 const uint8_t* source = data_buffer_[index].dataPtr; | 364 const uint8_t* source = data_buffer_[index].dataPtr; |
355 size_t length = data_buffer_[index].sizeBytes; | |
356 memcpy(destination, source, length); | 365 memcpy(destination, source, length); |
357 destination += length; | 366 destination += length; |
358 index = (index + 1) % size_; | 367 index = (index + 1) % size_; |
359 ++seq_num; | 368 ++seq_num; |
360 } | 369 } while (index != end); |
370 | |
361 return true; | 371 return true; |
362 } | 372 } |
363 | 373 |
364 VCMPacket* PacketBuffer::GetPacket(uint16_t seq_num) { | 374 VCMPacket* PacketBuffer::GetPacket(uint16_t seq_num) { |
365 size_t index = seq_num % size_; | 375 size_t index = seq_num % size_; |
366 if (!sequence_buffer_[index].used || | 376 if (!sequence_buffer_[index].used || |
367 seq_num != sequence_buffer_[index].seq_num) { | 377 seq_num != sequence_buffer_[index].seq_num) { |
368 return nullptr; | 378 return nullptr; |
369 } | 379 } |
370 return &data_buffer_[index]; | 380 return &data_buffer_[index]; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 missing_packets_.insert(*newest_inserted_seq_num_); | 412 missing_packets_.insert(*newest_inserted_seq_num_); |
403 ++*newest_inserted_seq_num_; | 413 ++*newest_inserted_seq_num_; |
404 } | 414 } |
405 } else { | 415 } else { |
406 missing_packets_.erase(seq_num); | 416 missing_packets_.erase(seq_num); |
407 } | 417 } |
408 } | 418 } |
409 | 419 |
410 } // namespace video_coding | 420 } // namespace video_coding |
411 } // namespace webrtc | 421 } // namespace webrtc |
OLD | NEW |