| 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 |
| 11 #include "webrtc/modules/video_coding/packet_buffer.h" | 11 #include "webrtc/modules/video_coding/packet_buffer.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <limits> | 14 #include <limits> |
| 15 | 15 |
| 16 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
| 17 #include "webrtc/base/logging.h" |
| 17 #include "webrtc/modules/video_coding/frame_object.h" | 18 #include "webrtc/modules/video_coding/frame_object.h" |
| 18 | 19 |
| 19 namespace webrtc { | 20 namespace webrtc { |
| 20 namespace video_coding { | 21 namespace video_coding { |
| 21 | 22 |
| 22 PacketBuffer::PacketBuffer(size_t start_buffer_size, | 23 PacketBuffer::PacketBuffer(size_t start_buffer_size, |
| 23 size_t max_buffer_size, | 24 size_t max_buffer_size, |
| 24 OnCompleteFrameCallback* frame_callback) | 25 OnCompleteFrameCallback* frame_callback) |
| 25 : size_(start_buffer_size), | 26 : size_(start_buffer_size), |
| 26 max_size_(max_buffer_size), | 27 max_size_(max_buffer_size), |
| 27 first_seq_num_(0), | 28 first_seq_num_(0), |
| 28 last_seq_num_(0), | 29 last_seq_num_(0), |
| 29 first_packet_received_(false), | 30 first_packet_received_(false), |
| 30 data_buffer_(start_buffer_size), | 31 data_buffer_(start_buffer_size), |
| 31 sequence_buffer_(start_buffer_size), | 32 sequence_buffer_(start_buffer_size), |
| 32 frame_callback_(frame_callback), | 33 frame_callback_(frame_callback), |
| 33 last_picture_id_(-1), | 34 last_picture_id_(-1), |
| 34 last_unwrap_(-1) { | 35 last_unwrap_(-1), |
| 36 current_ss_idx_(0) { |
| 35 RTC_DCHECK_LE(start_buffer_size, max_buffer_size); | 37 RTC_DCHECK_LE(start_buffer_size, max_buffer_size); |
| 36 // Buffer size must always be a power of 2. | 38 // Buffer size must always be a power of 2. |
| 37 RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0); | 39 RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0); |
| 38 RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0); | 40 RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0); |
| 39 } | 41 } |
| 40 | 42 |
| 41 bool PacketBuffer::InsertPacket(const VCMPacket& packet) { | 43 bool PacketBuffer::InsertPacket(const VCMPacket& packet) { |
| 42 rtc::CritScope lock(&crit_); | 44 rtc::CritScope lock(&crit_); |
| 43 uint16_t seq_num = packet.seqNum; | 45 uint16_t seq_num = packet.seqNum; |
| 44 size_t index = seq_num % size_; | 46 size_t index = seq_num % size_; |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 switch (codec_type) { | 211 switch (codec_type) { |
| 210 case kVideoCodecULPFEC: | 212 case kVideoCodecULPFEC: |
| 211 case kVideoCodecRED: | 213 case kVideoCodecRED: |
| 212 case kVideoCodecUnknown: | 214 case kVideoCodecUnknown: |
| 213 RTC_NOTREACHED(); | 215 RTC_NOTREACHED(); |
| 214 break; | 216 break; |
| 215 case kVideoCodecVP8: | 217 case kVideoCodecVP8: |
| 216 ManageFrameVp8(std::move(frame)); | 218 ManageFrameVp8(std::move(frame)); |
| 217 break; | 219 break; |
| 218 case kVideoCodecVP9: | 220 case kVideoCodecVP9: |
| 219 // TODO(philipel): ManageFrameVp9(std::move(frame)); | 221 ManageFrameVp9(std::move(frame)); |
| 220 break; | 222 break; |
| 221 case kVideoCodecH264: | 223 case kVideoCodecH264: |
| 222 case kVideoCodecI420: | 224 case kVideoCodecI420: |
| 223 case kVideoCodecGeneric: | 225 case kVideoCodecGeneric: |
| 224 ManageFrameGeneric(std::move(frame)); | 226 ManageFrameGeneric(std::move(frame)); |
| 225 break; | 227 break; |
| 226 } | 228 } |
| 227 } | 229 } |
| 228 | 230 |
| 229 void PacketBuffer::RetryStashedFrames() { | 231 void PacketBuffer::RetryStashedFrames() { |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 frame->picture_id = codec_header.pictureId % kPicIdLength; | 311 frame->picture_id = codec_header.pictureId % kPicIdLength; |
| 310 | 312 |
| 311 if (last_unwrap_ == -1) | 313 if (last_unwrap_ == -1) |
| 312 last_unwrap_ = codec_header.pictureId; | 314 last_unwrap_ = codec_header.pictureId; |
| 313 | 315 |
| 314 if (last_picture_id_ == -1) | 316 if (last_picture_id_ == -1) |
| 315 last_picture_id_ = frame->picture_id; | 317 last_picture_id_ = frame->picture_id; |
| 316 | 318 |
| 317 // Find if there has been a gap in fully received frames and save the picture | 319 // Find if there has been a gap in fully received frames and save the picture |
| 318 // id of those frames in |not_yet_received_frames_|. | 320 // id of those frames in |not_yet_received_frames_|. |
| 319 if (AheadOf<uint8_t, kPicIdLength>(frame->picture_id, last_picture_id_)) { | 321 if (AheadOf<uint16_t, kPicIdLength>(frame->picture_id, last_picture_id_)) { |
| 320 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); | 322 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); |
| 321 while (last_picture_id_ != frame->picture_id) { | 323 while (last_picture_id_ != frame->picture_id) { |
| 322 not_yet_received_frames_.insert(last_picture_id_); | 324 not_yet_received_frames_.insert(last_picture_id_); |
| 323 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); | 325 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); |
| 324 } | 326 } |
| 325 } | 327 } |
| 326 | 328 |
| 327 // Clean up info for base layers that are too old. | 329 // Clean up info for base layers that are too old. |
| 328 uint8_t old_tl0_pic_idx = codec_header.tl0PicIdx - kMaxLayerInfo; | 330 uint8_t old_tl0_pic_idx = codec_header.tl0PicIdx - kMaxLayerInfo; |
| 329 auto clean_layer_info_to = layer_info_.lower_bound(old_tl0_pic_idx); | 331 auto clean_layer_info_to = layer_info_.lower_bound(old_tl0_pic_idx); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 // Find all references for this frame. | 381 // Find all references for this frame. |
| 380 frame->num_references = 0; | 382 frame->num_references = 0; |
| 381 for (uint8_t layer = 0; layer <= codec_header.temporalIdx; ++layer) { | 383 for (uint8_t layer = 0; layer <= codec_header.temporalIdx; ++layer) { |
| 382 RTC_DCHECK_NE(-1, layer_info_it->second[layer]); | 384 RTC_DCHECK_NE(-1, layer_info_it->second[layer]); |
| 383 | 385 |
| 384 // If we have not yet received a frame between this frame and the referenced | 386 // If we have not yet received a frame between this frame and the referenced |
| 385 // frame then we have to wait for that frame to be completed first. | 387 // frame then we have to wait for that frame to be completed first. |
| 386 auto not_received_frame_it = | 388 auto not_received_frame_it = |
| 387 not_yet_received_frames_.upper_bound(layer_info_it->second[layer]); | 389 not_yet_received_frames_.upper_bound(layer_info_it->second[layer]); |
| 388 if (not_received_frame_it != not_yet_received_frames_.end() && | 390 if (not_received_frame_it != not_yet_received_frames_.end() && |
| 389 AheadOf<uint8_t, kPicIdLength>(frame->picture_id, | 391 AheadOf<uint16_t, kPicIdLength>(frame->picture_id, |
| 390 *not_received_frame_it)) { | 392 *not_received_frame_it)) { |
| 391 stashed_frames_.emplace(std::move(frame)); | 393 stashed_frames_.emplace(std::move(frame)); |
| 392 return; | 394 return; |
| 393 } | 395 } |
| 394 | 396 |
| 395 ++frame->num_references; | 397 ++frame->num_references; |
| 396 frame->references[layer] = layer_info_it->second[layer]; | 398 frame->references[layer] = layer_info_it->second[layer]; |
| 397 } | 399 } |
| 398 | 400 |
| 399 CompletedFrameVp8(std::move(frame)); | 401 CompletedFrameVp8(std::move(frame)); |
| 400 } | 402 } |
| 401 | 403 |
| 402 void PacketBuffer::CompletedFrameVp8(std::unique_ptr<RtpFrameObject> frame) { | 404 void PacketBuffer::CompletedFrameVp8(std::unique_ptr<RtpFrameObject> frame) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 418 // update. | 420 // update. |
| 419 break; | 421 break; |
| 420 } | 422 } |
| 421 | 423 |
| 422 layer_info_it->second[codec_header.temporalIdx] = frame->picture_id; | 424 layer_info_it->second[codec_header.temporalIdx] = frame->picture_id; |
| 423 ++tl0_pic_idx; | 425 ++tl0_pic_idx; |
| 424 layer_info_it = layer_info_.find(tl0_pic_idx); | 426 layer_info_it = layer_info_.find(tl0_pic_idx); |
| 425 } | 427 } |
| 426 not_yet_received_frames_.erase(frame->picture_id); | 428 not_yet_received_frames_.erase(frame->picture_id); |
| 427 | 429 |
| 428 for (size_t r = 0; r < frame->num_references; ++r) | 430 for (size_t i = 0; i < frame->num_references; ++i) |
| 429 frame->references[r] = UnwrapPictureId(frame->references[r]); | 431 frame->references[i] = UnwrapPictureId(frame->references[i]); |
| 430 frame->picture_id = UnwrapPictureId(frame->picture_id); | 432 frame->picture_id = UnwrapPictureId(frame->picture_id); |
| 431 | 433 |
| 432 frame_callback_->OnCompleteFrame(std::move(frame)); | 434 frame_callback_->OnCompleteFrame(std::move(frame)); |
| 433 RetryStashedFrames(); | 435 RetryStashedFrames(); |
| 434 } | 436 } |
| 435 | 437 |
| 438 void PacketBuffer::ManageFrameVp9(std::unique_ptr<RtpFrameObject> frame) { |
| 439 size_t index = frame->first_seq_num() % size_; |
| 440 const VCMPacket& packet = data_buffer_[index]; |
| 441 const RTPVideoHeaderVP9& codec_header = |
| 442 packet.codecSpecificHeader.codecHeader.VP9; |
| 443 |
| 444 if (codec_header.picture_id == kNoPictureId) { |
| 445 ManageFrameGeneric(std::move(frame)); |
| 446 return; |
| 447 } |
| 448 |
| 449 frame->spatial_layer = codec_header.spatial_idx; |
| 450 frame->inter_layer_predicted = codec_header.inter_layer_predicted; |
| 451 frame->picture_id = codec_header.picture_id % kPicIdLength; |
| 452 |
| 453 if (last_unwrap_ == -1) |
| 454 last_unwrap_ = codec_header.picture_id; |
| 455 |
| 456 if (last_picture_id_ == -1) |
| 457 last_picture_id_ = frame->picture_id; |
| 458 |
| 459 if (codec_header.flexible_mode) { |
| 460 frame->num_references = codec_header.num_ref_pics; |
| 461 for (size_t i = 0; i < frame->num_references; ++i) { |
| 462 frame->references[i] = |
| 463 Subtract<1 << 16>(frame->picture_id, codec_header.pid_diff[i]); |
| 464 } |
| 465 |
| 466 CompletedFrameVp9(std::move(frame)); |
| 467 return; |
| 468 } |
| 469 |
| 470 if (codec_header.ss_data_available) { |
| 471 // Scalability structures can only be sent with tl0 frames. |
| 472 if (codec_header.temporal_idx != 0) { |
| 473 LOG(LS_WARNING) << "Received scalability structure on a non base layer" |
| 474 " frame. Scalability structure ignored."; |
| 475 } else { |
| 476 current_ss_idx_ = Add<kMaxGofSaved>(current_ss_idx_, 1); |
| 477 scalability_structures_[current_ss_idx_] = codec_header.gof; |
| 478 scalability_structures_[current_ss_idx_].pid_start = frame->picture_id; |
| 479 |
| 480 auto pid_and_gof = std::make_pair( |
| 481 frame->picture_id, &scalability_structures_[current_ss_idx_]); |
| 482 gof_info_.insert(std::make_pair(codec_header.tl0_pic_idx, pid_and_gof)); |
| 483 } |
| 484 } |
| 485 |
| 486 // Clean up info for base layers that are too old. |
| 487 uint8_t old_tl0_pic_idx = codec_header.tl0_pic_idx - kMaxGofSaved; |
| 488 auto clean_gof_info_to = gof_info_.lower_bound(old_tl0_pic_idx); |
| 489 gof_info_.erase(gof_info_.begin(), clean_gof_info_to); |
| 490 |
| 491 if (packet.frameType == kVideoFrameKey) { |
| 492 // When using GOF all keyframes must include the scalability structure. |
| 493 if (!codec_header.ss_data_available) |
| 494 LOG(LS_WARNING) << "Received keyframe without scalability structure"; |
| 495 |
| 496 frame->num_references = 0; |
| 497 GofInfoVP9* gof = gof_info_.find(codec_header.tl0_pic_idx)->second.second; |
| 498 FrameReceivedVp9(frame->picture_id, *gof); |
| 499 CompletedFrameVp9(std::move(frame)); |
| 500 return; |
| 501 } |
| 502 |
| 503 auto gof_info_it = gof_info_.find( |
| 504 (codec_header.temporal_idx == 0 && !codec_header.ss_data_available) |
| 505 ? codec_header.tl0_pic_idx - 1 |
| 506 : codec_header.tl0_pic_idx); |
| 507 |
| 508 // Gof info for this frame is not available yet, stash this frame. |
| 509 if (gof_info_it == gof_info_.end()) { |
| 510 stashed_frames_.emplace(std::move(frame)); |
| 511 return; |
| 512 } |
| 513 |
| 514 GofInfoVP9* gof = gof_info_it->second.second; |
| 515 uint16_t picture_id_tl0 = gof_info_it->second.first; |
| 516 |
| 517 FrameReceivedVp9(frame->picture_id, *gof); |
| 518 |
| 519 // Make sure we don't miss any frame that could potentially have the |
| 520 // up switch flag set. |
| 521 if (MissingRequiredFrameVp9(frame->picture_id, *gof)) { |
| 522 stashed_frames_.emplace(std::move(frame)); |
| 523 return; |
| 524 } |
| 525 |
| 526 if (codec_header.temporal_up_switch) { |
| 527 auto pid_tidx = |
| 528 std::make_pair(frame->picture_id, codec_header.temporal_idx); |
| 529 up_switch_.insert(pid_tidx); |
| 530 } |
| 531 |
| 532 // If this is a base layer frame that contains a scalability structure |
| 533 // then gof info has already been inserted earlier, so we only want to |
| 534 // insert if we haven't done so already. |
| 535 if (codec_header.temporal_idx == 0 && !codec_header.ss_data_available) { |
| 536 auto pid_and_gof = std::make_pair(frame->picture_id, gof); |
| 537 gof_info_.insert(std::make_pair(codec_header.tl0_pic_idx, pid_and_gof)); |
| 538 } |
| 539 |
| 540 // Clean out old info about up switch frames. |
| 541 uint16_t old_picture_id = Subtract<kPicIdLength>(last_picture_id_, 50); |
| 542 auto up_switch_erase_to = up_switch_.lower_bound(old_picture_id); |
| 543 up_switch_.erase(up_switch_.begin(), up_switch_erase_to); |
| 544 |
| 545 RTC_DCHECK( |
| 546 (AheadOrAt<uint16_t, kPicIdLength>(frame->picture_id, picture_id_tl0))); |
| 547 |
| 548 size_t diff = |
| 549 ForwardDiff<uint16_t, kPicIdLength>(gof->pid_start, frame->picture_id); |
| 550 size_t gof_idx = diff % gof->num_frames_in_gof; |
| 551 |
| 552 // Populate references according to the scalability structure. |
| 553 frame->num_references = gof->num_ref_pics[gof_idx]; |
| 554 for (size_t i = 0; i < frame->num_references; ++i) { |
| 555 frame->references[i] = |
| 556 Subtract<kPicIdLength>(frame->picture_id, gof->pid_diff[gof_idx][i]); |
| 557 |
| 558 // If this is a reference to a frame earlier than the last up switch point, |
| 559 // then ignore this reference. |
| 560 if (UpSwitchInIntervalVp9(frame->picture_id, codec_header.temporal_idx, |
| 561 frame->references[i])) { |
| 562 --frame->num_references; |
| 563 } |
| 564 } |
| 565 |
| 566 CompletedFrameVp9(std::move(frame)); |
| 567 } |
| 568 |
| 569 bool PacketBuffer::MissingRequiredFrameVp9(uint16_t picture_id, |
| 570 const GofInfoVP9& gof) { |
| 571 size_t diff = ForwardDiff<uint16_t, kPicIdLength>(gof.pid_start, picture_id); |
| 572 size_t gof_idx = diff % gof.num_frames_in_gof; |
| 573 size_t temporal_idx = gof.temporal_idx[gof_idx]; |
| 574 |
| 575 // For every reference this frame has, check if there is a frame missing in |
| 576 // the interval (|ref_pid|, |picture_id|) in any of the lower temporal |
| 577 // layers. If so, we are missing a required frame. |
| 578 uint8_t num_references = gof.num_ref_pics[gof_idx]; |
| 579 for (size_t i = 0; i < num_references; ++i) { |
| 580 uint16_t ref_pid = |
| 581 Subtract<kPicIdLength>(picture_id, gof.pid_diff[gof_idx][i]); |
| 582 for (size_t l = 0; l < temporal_idx; ++l) { |
| 583 auto missing_frame_it = missing_frames_for_layer_[l].lower_bound(ref_pid); |
| 584 if (missing_frame_it != missing_frames_for_layer_[l].end() && |
| 585 AheadOf<uint16_t, kPicIdLength>(picture_id, *missing_frame_it)) { |
| 586 return true; |
| 587 } |
| 588 } |
| 589 } |
| 590 return false; |
| 591 } |
| 592 |
| 593 void PacketBuffer::FrameReceivedVp9(uint16_t picture_id, |
| 594 const GofInfoVP9& gof) { |
| 595 RTC_DCHECK_NE(-1, last_picture_id_); |
| 596 |
| 597 // If there is a gap, find which temporal layer the missing frames |
| 598 // belong to and add the frame as missing for that temporal layer. |
| 599 // Otherwise, remove this frame from the set of missing frames. |
| 600 if (AheadOf<uint16_t, kPicIdLength>(picture_id, last_picture_id_)) { |
| 601 size_t diff = |
| 602 ForwardDiff<uint16_t, kPicIdLength>(gof.pid_start, last_picture_id_); |
| 603 size_t gof_idx = diff % gof.num_frames_in_gof; |
| 604 |
| 605 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); |
| 606 while (last_picture_id_ != picture_id) { |
| 607 ++gof_idx; |
| 608 RTC_DCHECK_NE(0ul, gof_idx % gof.num_frames_in_gof); |
| 609 size_t temporal_idx = gof.temporal_idx[gof_idx]; |
| 610 missing_frames_for_layer_[temporal_idx].insert(last_picture_id_); |
| 611 last_picture_id_ = Add<kPicIdLength>(last_picture_id_, 1); |
| 612 } |
| 613 } else { |
| 614 size_t diff = |
| 615 ForwardDiff<uint16_t, kPicIdLength>(gof.pid_start, picture_id); |
| 616 size_t gof_idx = diff % gof.num_frames_in_gof; |
| 617 size_t temporal_idx = gof.temporal_idx[gof_idx]; |
| 618 missing_frames_for_layer_[temporal_idx].erase(picture_id); |
| 619 } |
| 620 } |
| 621 |
| 622 bool PacketBuffer::UpSwitchInIntervalVp9(uint16_t picture_id, |
| 623 uint8_t temporal_idx, |
| 624 uint16_t pid_ref) { |
| 625 for (auto up_switch_it = up_switch_.upper_bound(pid_ref); |
| 626 up_switch_it != up_switch_.end() && |
| 627 AheadOf<uint16_t, kPicIdLength>(picture_id, up_switch_it->first); |
| 628 ++up_switch_it) { |
| 629 if (up_switch_it->second < temporal_idx) |
| 630 return true; |
| 631 } |
| 632 |
| 633 return false; |
| 634 } |
| 635 |
| 636 void PacketBuffer::CompletedFrameVp9(std::unique_ptr<RtpFrameObject> frame) { |
| 637 for (size_t i = 0; i < frame->num_references; ++i) |
| 638 frame->references[i] = UnwrapPictureId(frame->references[i]); |
| 639 frame->picture_id = UnwrapPictureId(frame->picture_id); |
| 640 |
| 641 frame_callback_->OnCompleteFrame(std::move(frame)); |
| 642 RetryStashedFrames(); |
| 643 } |
| 644 |
| 436 uint16_t PacketBuffer::UnwrapPictureId(uint16_t picture_id) { | 645 uint16_t PacketBuffer::UnwrapPictureId(uint16_t picture_id) { |
| 437 if (last_unwrap_ == -1) | 646 RTC_DCHECK_NE(-1, last_unwrap_); |
| 438 last_unwrap_ = picture_id; | |
| 439 | 647 |
| 440 uint16_t unwrap_truncated = last_unwrap_ % kPicIdLength; | 648 uint16_t unwrap_truncated = last_unwrap_ % kPicIdLength; |
| 441 uint16_t diff = MinDiff<uint8_t, kPicIdLength>(unwrap_truncated, picture_id); | 649 uint16_t diff = MinDiff<uint16_t, kPicIdLength>(unwrap_truncated, picture_id); |
| 442 | 650 |
| 443 if (AheadOf<uint8_t, kPicIdLength>(picture_id, unwrap_truncated)) | 651 if (AheadOf<uint16_t, kPicIdLength>(picture_id, unwrap_truncated)) |
| 444 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff); | 652 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff); |
| 445 else | 653 else |
| 446 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff); | 654 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff); |
| 447 | 655 |
| 448 return last_unwrap_; | 656 return last_unwrap_; |
| 449 } | 657 } |
| 450 | 658 |
| 451 void PacketBuffer::Flush() { | 659 void PacketBuffer::Flush() { |
| 452 rtc::CritScope lock(&crit_); | 660 rtc::CritScope lock(&crit_); |
| 453 for (size_t i = 0; i < size_; ++i) | 661 for (size_t i = 0; i < size_; ++i) |
| 454 sequence_buffer_[i].used = false; | 662 sequence_buffer_[i].used = false; |
| 455 | 663 |
| 456 last_seq_num_gop_.clear(); | 664 last_seq_num_gop_.clear(); |
| 457 while (!stashed_frames_.empty()) | 665 while (!stashed_frames_.empty()) |
| 458 stashed_frames_.pop(); | 666 stashed_frames_.pop(); |
| 459 not_yet_received_frames_.clear(); | 667 not_yet_received_frames_.clear(); |
| 460 | 668 |
| 461 first_packet_received_ = false; | 669 first_packet_received_ = false; |
| 462 } | 670 } |
| 463 | 671 |
| 464 } // namespace video_coding | 672 } // namespace video_coding |
| 465 } // namespace webrtc | 673 } // namespace webrtc |
| OLD | NEW |