Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: webrtc/modules/video_coding/rtp_frame_reference_finder.cc

Issue 2969043002: Remove temporary VP9 pid/tl0 jump fix. (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 391
392 UnwrapPictureIds(frame); 392 UnwrapPictureIds(frame);
393 } 393 }
394 394
395 RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp9( 395 RtpFrameReferenceFinder::FrameDecision RtpFrameReferenceFinder::ManageFrameVp9(
396 RtpFrameObject* frame) { 396 RtpFrameObject* frame) {
397 rtc::Optional<RTPVideoTypeHeader> rtp_codec_header = frame->GetCodecHeader(); 397 rtc::Optional<RTPVideoTypeHeader> rtp_codec_header = frame->GetCodecHeader();
398 RTC_DCHECK(rtp_codec_header); 398 RTC_DCHECK(rtp_codec_header);
399 const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9; 399 const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9;
400 400
401 bool old_frame = Vp9PidTl0Fix(*frame, &rtp_codec_header->VP9.picture_id,
402 &rtp_codec_header->VP9.tl0_pic_idx);
403 if (old_frame)
404 return kDrop;
405
406 if (codec_header.picture_id == kNoPictureId || 401 if (codec_header.picture_id == kNoPictureId ||
407 codec_header.temporal_idx == kNoTemporalIdx) { 402 codec_header.temporal_idx == kNoTemporalIdx) {
408 return ManageFrameGeneric(std::move(frame), codec_header.picture_id); 403 return ManageFrameGeneric(std::move(frame), codec_header.picture_id);
409 } 404 }
410 405
411 frame->spatial_layer = codec_header.spatial_idx; 406 frame->spatial_layer = codec_header.spatial_idx;
412 frame->inter_layer_predicted = codec_header.inter_layer_predicted; 407 frame->inter_layer_predicted = codec_header.inter_layer_predicted;
413 frame->picture_id = codec_header.picture_id % kPicIdLength; 408 frame->picture_id = codec_header.picture_id % kPicIdLength;
414 409
415 if (last_unwrap_ == -1) 410 if (last_unwrap_ == -1)
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 uint16_t diff = MinDiff<uint16_t, kPicIdLength>(unwrap_truncated, picture_id); 597 uint16_t diff = MinDiff<uint16_t, kPicIdLength>(unwrap_truncated, picture_id);
603 598
604 if (AheadOf<uint16_t, kPicIdLength>(picture_id, unwrap_truncated)) 599 if (AheadOf<uint16_t, kPicIdLength>(picture_id, unwrap_truncated))
605 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff); 600 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff);
606 else 601 else
607 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff); 602 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff);
608 603
609 return last_unwrap_; 604 return last_unwrap_;
610 } 605 }
611 606
612 bool RtpFrameReferenceFinder::Vp9PidTl0Fix(const RtpFrameObject& frame,
613 int16_t* picture_id,
614 int16_t* tl0_pic_idx) {
615 const int kTl0PicIdLength = 256;
616 const uint8_t kMaxPidDiff = 128;
617
618 // We are currently receiving VP9 without PID, nothing to fix.
619 if (*picture_id == kNoPictureId)
620 return false;
621
622 // If |vp9_fix_jump_timestamp_| != -1 then a jump has occurred recently.
623 if (vp9_fix_jump_timestamp_ != -1) {
624 // If this frame has a timestamp older than |vp9_fix_jump_timestamp_| then
625 // this frame is old (more previous than the frame where we detected the
626 // jump) and should be dropped.
627 if (AheadOf<uint32_t>(vp9_fix_jump_timestamp_, frame.timestamp))
628 return true;
629
630 // After 60 seconds, reset |vp9_fix_jump_timestamp_| in order to not
631 // discard old frames when the timestamp wraps.
632 int diff_ms =
633 ForwardDiff<uint32_t>(vp9_fix_jump_timestamp_, frame.timestamp) / 90;
634 if (diff_ms > 60 * 1000)
635 vp9_fix_jump_timestamp_ = -1;
636 }
637
638 // Update |vp9_fix_last_timestamp_| with the most recent timestamp.
639 if (vp9_fix_last_timestamp_ == -1)
640 vp9_fix_last_timestamp_ = frame.timestamp;
641 if (AheadOf<uint32_t>(frame.timestamp, vp9_fix_last_timestamp_))
642 vp9_fix_last_timestamp_ = frame.timestamp;
643
644 uint16_t fixed_pid = Add<kPicIdLength>(*picture_id, vp9_fix_pid_offset_);
645 if (vp9_fix_last_picture_id_ == -1)
646 vp9_fix_last_picture_id_ = *picture_id;
647
648 int16_t fixed_tl0 = kNoTl0PicIdx;
649 if (*tl0_pic_idx != kNoTl0PicIdx) {
650 fixed_tl0 = Add<kTl0PicIdLength>(*tl0_pic_idx, vp9_fix_tl0_pic_idx_offset_);
651 // Update |vp9_fix_last_tl0_pic_idx_| with the most recent tl0 pic index.
652 if (vp9_fix_last_tl0_pic_idx_ == -1)
653 vp9_fix_last_tl0_pic_idx_ = *tl0_pic_idx;
654 if (AheadOf<uint8_t>(fixed_tl0, vp9_fix_last_tl0_pic_idx_))
655 vp9_fix_last_tl0_pic_idx_ = fixed_tl0;
656 }
657
658 bool has_jumped = DetectVp9PicIdJump(fixed_pid, fixed_tl0, frame.timestamp);
659 if (!has_jumped)
660 has_jumped = DetectVp9Tl0PicIdxJump(fixed_tl0, frame.timestamp);
661
662 if (has_jumped) {
663 // First we calculate the offset to get to the previous picture id, and then
664 // we add kMaxPid to avoid accidently referencing any previous
665 // frames that was inserted into the FrameBuffer.
666 vp9_fix_pid_offset_ = ForwardDiff<uint16_t, kPicIdLength>(
667 *picture_id, vp9_fix_last_picture_id_);
668 vp9_fix_pid_offset_ += kMaxPidDiff;
669
670 fixed_pid = Add<kPicIdLength>(*picture_id, vp9_fix_pid_offset_);
671 vp9_fix_last_picture_id_ = fixed_pid;
672 vp9_fix_jump_timestamp_ = frame.timestamp;
673 gof_info_.clear();
674
675 if (fixed_tl0 != kNoTl0PicIdx) {
676 vp9_fix_tl0_pic_idx_offset_ =
677 ForwardDiff<uint8_t>(*tl0_pic_idx, vp9_fix_last_tl0_pic_idx_);
678 vp9_fix_tl0_pic_idx_offset_ += kMaxGofSaved;
679 fixed_tl0 =
680 Add<kTl0PicIdLength>(*tl0_pic_idx, vp9_fix_tl0_pic_idx_offset_);
681 vp9_fix_last_tl0_pic_idx_ = fixed_tl0;
682 }
683 }
684
685 // Update |vp9_fix_last_picture_id_| with the most recent picture id.
686 if (AheadOf<uint16_t, kPicIdLength>(fixed_pid, vp9_fix_last_picture_id_))
687 vp9_fix_last_picture_id_ = fixed_pid;
688
689 *picture_id = fixed_pid;
690 *tl0_pic_idx = fixed_tl0;
691
692 return false;
693 }
694
695 bool RtpFrameReferenceFinder::DetectVp9PicIdJump(int fixed_pid,
696 int fixed_tl0,
697 uint32_t timestamp) const {
698 // Test if there has been a jump backwards in the picture id.
699 if (AheadOrAt<uint32_t>(timestamp, vp9_fix_last_timestamp_) &&
700 AheadOf<uint16_t, kPicIdLength>(vp9_fix_last_picture_id_, fixed_pid)) {
701 return true;
702 }
703
704 // Test if we have jumped forward too much. The reason we have to do this
705 // is because the FrameBuffer holds history of old frames and inserting
706 // frames with a much advanced picture id can result in the frame buffer
707 // holding more than half of the interval of picture ids.
708 if (AheadOrAt<uint32_t>(timestamp, vp9_fix_last_timestamp_) &&
709 ForwardDiff<uint16_t, kPicIdLength>(vp9_fix_last_picture_id_, fixed_pid) >
710 128) {
711 return true;
712 }
713
714 // Special case where the picture id jump forward but not by much and the
715 // tl0 jumps to the id of an already saved gof for that id. In order to
716 // detect this we check if the picture id span over the length of the GOF.
717 if (fixed_tl0 != kNoTl0PicIdx) {
718 auto info_it = gof_info_.find(fixed_tl0);
719 if (info_it != gof_info_.end()) {
720 int last_pid_gof_idx_0 =
721 Subtract<kPicIdLength>(info_it->second.last_picture_id,
722 info_it->second.last_picture_id %
723 info_it->second.gof->num_frames_in_gof);
724 int pif_gof_end = Add<kPicIdLength>(
725 last_pid_gof_idx_0, info_it->second.gof->num_frames_in_gof);
726 if (AheadOf<uint16_t, kPicIdLength>(fixed_pid, pif_gof_end))
727 return true;
728 }
729 }
730
731 return false;
732 }
733
734 bool RtpFrameReferenceFinder::DetectVp9Tl0PicIdxJump(int fixed_tl0,
735 uint32_t timestamp) const {
736 if (fixed_tl0 != kNoTl0PicIdx) {
737 // Test if there has been a jump backwards in tl0 pic index.
738 if (AheadOrAt<uint32_t>(timestamp, vp9_fix_last_timestamp_) &&
739 AheadOf<uint8_t>(vp9_fix_last_tl0_pic_idx_, fixed_tl0)) {
740 return true;
741 }
742
743 // Test if there has been a jump forward. If the jump forward results
744 // in the tl0 pic index for this frame to be considered smaller than the
745 // smallest item in |gof_info_| then we have jumped forward far enough to
746 // wrap.
747 if (!gof_info_.empty() &&
748 AheadOf<uint8_t>(gof_info_.begin()->first, fixed_tl0)) {
749 return true;
750 }
751 }
752 return false;
753 }
754
755 } // namespace video_coding 607 } // namespace video_coding
756 } // namespace webrtc 608 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698