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 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 // If all packets of the frame is continuous, find the first packet of the | 261 // If all packets of the frame is continuous, find the first packet of the |
262 // frame and create an RtpFrameObject. | 262 // frame and create an RtpFrameObject. |
263 if (sequence_buffer_[index].frame_end) { | 263 if (sequence_buffer_[index].frame_end) { |
264 size_t frame_size = 0; | 264 size_t frame_size = 0; |
265 int max_nack_count = -1; | 265 int max_nack_count = -1; |
266 uint16_t start_seq_num = seq_num; | 266 uint16_t start_seq_num = seq_num; |
267 | 267 |
268 // Find the start index by searching backward until the packet with | 268 // Find the start index by searching backward until the packet with |
269 // the |frame_begin| flag is set. | 269 // the |frame_begin| flag is set. |
270 int start_index = index; | 270 int start_index = index; |
| 271 size_t tested_packets = 0; |
271 | 272 |
272 bool is_h264 = data_buffer_[start_index].codec == kVideoCodecH264; | 273 bool is_h264 = data_buffer_[start_index].codec == kVideoCodecH264; |
273 bool is_h264_keyframe = false; | 274 bool is_h264_keyframe = false; |
274 int64_t frame_timestamp = data_buffer_[start_index].timestamp; | 275 int64_t frame_timestamp = data_buffer_[start_index].timestamp; |
275 | 276 |
276 // Since packet at |data_buffer_[index]| is already part of the frame | 277 while (true) { |
277 // we will have at most |size_ - 1| packets left to check. | 278 ++tested_packets; |
278 for (size_t j = 0; j < size_ - 1; ++j) { | |
279 frame_size += data_buffer_[start_index].sizeBytes; | 279 frame_size += data_buffer_[start_index].sizeBytes; |
280 max_nack_count = | 280 max_nack_count = |
281 std::max(max_nack_count, data_buffer_[start_index].timesNacked); | 281 std::max(max_nack_count, data_buffer_[start_index].timesNacked); |
282 sequence_buffer_[start_index].frame_created = true; | 282 sequence_buffer_[start_index].frame_created = true; |
283 | 283 |
284 if (!is_h264 && sequence_buffer_[start_index].frame_begin) | 284 if (!is_h264 && sequence_buffer_[start_index].frame_begin) |
285 break; | 285 break; |
286 | 286 |
287 if (is_h264 && !is_h264_keyframe) { | 287 if (is_h264 && !is_h264_keyframe) { |
288 const RTPVideoHeaderH264& header = | 288 const RTPVideoHeaderH264& header = |
289 data_buffer_[start_index].video_header.codecHeader.H264; | 289 data_buffer_[start_index].video_header.codecHeader.H264; |
290 for (size_t i = 0; i < header.nalus_length; ++i) { | 290 for (size_t i = 0; i < header.nalus_length; ++i) { |
291 if (header.nalus[i].type == H264::NaluType::kIdr) { | 291 if (header.nalus[i].type == H264::NaluType::kIdr) { |
292 is_h264_keyframe = true; | 292 is_h264_keyframe = true; |
293 break; | 293 break; |
294 } | 294 } |
295 } | 295 } |
296 } | 296 } |
297 | 297 |
| 298 if (tested_packets == size_) |
| 299 break; |
| 300 |
298 start_index = start_index > 0 ? start_index - 1 : size_ - 1; | 301 start_index = start_index > 0 ? start_index - 1 : size_ - 1; |
299 | 302 |
300 // In the case of H264 we don't have a frame_begin bit (yes, | 303 // In the case of H264 we don't have a frame_begin bit (yes, |
301 // |frame_begin| might be set to true but that is a lie). So instead | 304 // |frame_begin| might be set to true but that is a lie). So instead |
302 // we traverese backwards as long as we have a previous packet and | 305 // we traverese backwards as long as we have a previous packet and |
303 // the timestamp of that packet is the same as this one. This may cause | 306 // the timestamp of that packet is the same as this one. This may cause |
304 // the PacketBuffer to hand out incomplete frames. | 307 // the PacketBuffer to hand out incomplete frames. |
305 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7106 | 308 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=7106 |
306 if (is_h264 && | 309 if (is_h264 && |
307 (!sequence_buffer_[start_index].used || | 310 (!sequence_buffer_[start_index].used || |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 } | 358 } |
356 } | 359 } |
357 | 360 |
358 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame, | 361 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame, |
359 uint8_t* destination) { | 362 uint8_t* destination) { |
360 rtc::CritScope lock(&crit_); | 363 rtc::CritScope lock(&crit_); |
361 | 364 |
362 size_t index = frame.first_seq_num() % size_; | 365 size_t index = frame.first_seq_num() % size_; |
363 size_t end = (frame.last_seq_num() + 1) % size_; | 366 size_t end = (frame.last_seq_num() + 1) % size_; |
364 uint16_t seq_num = frame.first_seq_num(); | 367 uint16_t seq_num = frame.first_seq_num(); |
365 while (index != end) { | 368 uint8_t* destination_end = destination + frame.size(); |
| 369 |
| 370 do { |
366 if (!sequence_buffer_[index].used || | 371 if (!sequence_buffer_[index].used || |
367 sequence_buffer_[index].seq_num != seq_num) { | 372 sequence_buffer_[index].seq_num != seq_num) { |
368 return false; | 373 return false; |
369 } | 374 } |
370 | 375 |
| 376 RTC_DCHECK_EQ(data_buffer_[index].seqNum, sequence_buffer_[index].seq_num); |
| 377 size_t length = data_buffer_[index].sizeBytes; |
| 378 if (destination + length > destination_end) { |
| 379 LOG(LS_WARNING) << "Frame (" << frame.picture_id << ":" |
| 380 << static_cast<int>(frame.spatial_layer) << ")" |
| 381 << " bitstream buffer is not large enough."; |
| 382 return false; |
| 383 } |
| 384 |
371 const uint8_t* source = data_buffer_[index].dataPtr; | 385 const uint8_t* source = data_buffer_[index].dataPtr; |
372 size_t length = data_buffer_[index].sizeBytes; | |
373 memcpy(destination, source, length); | 386 memcpy(destination, source, length); |
374 destination += length; | 387 destination += length; |
375 index = (index + 1) % size_; | 388 index = (index + 1) % size_; |
376 ++seq_num; | 389 ++seq_num; |
377 } | 390 } while (index != end); |
| 391 |
378 return true; | 392 return true; |
379 } | 393 } |
380 | 394 |
381 VCMPacket* PacketBuffer::GetPacket(uint16_t seq_num) { | 395 VCMPacket* PacketBuffer::GetPacket(uint16_t seq_num) { |
382 size_t index = seq_num % size_; | 396 size_t index = seq_num % size_; |
383 if (!sequence_buffer_[index].used || | 397 if (!sequence_buffer_[index].used || |
384 seq_num != sequence_buffer_[index].seq_num) { | 398 seq_num != sequence_buffer_[index].seq_num) { |
385 return nullptr; | 399 return nullptr; |
386 } | 400 } |
387 return &data_buffer_[index]; | 401 return &data_buffer_[index]; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 missing_packets_.insert(*newest_inserted_seq_num_); | 433 missing_packets_.insert(*newest_inserted_seq_num_); |
420 ++*newest_inserted_seq_num_; | 434 ++*newest_inserted_seq_num_; |
421 } | 435 } |
422 } else { | 436 } else { |
423 missing_packets_.erase(seq_num); | 437 missing_packets_.erase(seq_num); |
424 } | 438 } |
425 } | 439 } |
426 | 440 |
427 } // namespace video_coding | 441 } // namespace video_coding |
428 } // namespace webrtc | 442 } // namespace webrtc |
OLD | NEW |