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

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

Issue 2480293002: New jitter buffer experiment. (Closed)
Patch Set: Nit fix. Created 4 years, 1 month 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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 } 364 }
365 365
366 void RtpFrameReferenceFinder::ManageFrameVp9( 366 void RtpFrameReferenceFinder::ManageFrameVp9(
367 std::unique_ptr<RtpFrameObject> frame) { 367 std::unique_ptr<RtpFrameObject> frame) {
368 rtc::Optional<RTPVideoTypeHeader> rtp_codec_header = frame->GetCodecHeader(); 368 rtc::Optional<RTPVideoTypeHeader> rtp_codec_header = frame->GetCodecHeader();
369 if (!rtp_codec_header) 369 if (!rtp_codec_header)
370 return; 370 return;
371 371
372 const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9; 372 const RTPVideoHeaderVP9& codec_header = rtp_codec_header->VP9;
373 373
374 bool old_frame = Vp9PidTl0Fix(*frame, &rtp_codec_header->VP9.picture_id,
375 &rtp_codec_header->VP9.tl0_pic_idx);
376 if (old_frame)
377 return;
378
374 if (codec_header.picture_id == kNoPictureId || 379 if (codec_header.picture_id == kNoPictureId ||
375 codec_header.temporal_idx == kNoTemporalIdx) { 380 codec_header.temporal_idx == kNoTemporalIdx) {
376 ManageFrameGeneric(std::move(frame), codec_header.picture_id); 381 ManageFrameGeneric(std::move(frame), codec_header.picture_id);
377 return; 382 return;
378 } 383 }
379 384
380 frame->spatial_layer = codec_header.spatial_idx; 385 frame->spatial_layer = codec_header.spatial_idx;
381 frame->inter_layer_predicted = codec_header.inter_layer_predicted; 386 frame->inter_layer_predicted = codec_header.inter_layer_predicted;
382 frame->picture_id = codec_header.picture_id % kPicIdLength; 387 frame->picture_id = codec_header.picture_id % kPicIdLength;
383 388
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 uint16_t diff = MinDiff<uint16_t, kPicIdLength>(unwrap_truncated, picture_id); 583 uint16_t diff = MinDiff<uint16_t, kPicIdLength>(unwrap_truncated, picture_id);
579 584
580 if (AheadOf<uint16_t, kPicIdLength>(picture_id, unwrap_truncated)) 585 if (AheadOf<uint16_t, kPicIdLength>(picture_id, unwrap_truncated))
581 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff); 586 last_unwrap_ = Add<1 << 16>(last_unwrap_, diff);
582 else 587 else
583 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff); 588 last_unwrap_ = Subtract<1 << 16>(last_unwrap_, diff);
584 589
585 return last_unwrap_; 590 return last_unwrap_;
586 } 591 }
587 592
593 bool RtpFrameReferenceFinder::Vp9PidTl0Fix(const RtpFrameObject& frame,
594 int16_t* picture_id,
595 int16_t* tl0_pic_idx) {
596 const int kTl0PicIdLength = 256;
597 const uint8_t kMaxPidDiff = 128;
598
599 // We are currently receiving VP9 without PID, nothing to fix.
600 if (*picture_id == kNoPictureId)
601 return false;
602
603 // If |vp9_fix_jump_timestamp_| != -1 then a jump has occurred recently.
604 if (vp9_fix_jump_timestamp_ != -1) {
605 // If this frame has a timestamp older than |vp9_fix_jump_timestamp_| then
606 // this frame is old (more previous than the frame where we detected the
607 // jump) and should be dropped.
608 if (AheadOf<uint32_t>(vp9_fix_jump_timestamp_, frame.timestamp))
609 return true;
610
611 // After 60 seconds, reset |vp9_fix_jump_timestamp_| in order to not
612 // discard old frames when the timestamp wraps.
613 int diff_ms =
614 ForwardDiff<uint32_t>(vp9_fix_jump_timestamp_, frame.timestamp) / 90;
615 if (diff_ms > 60 * 1000)
616 vp9_fix_jump_timestamp_ = -1;
617 }
618
619 // Update |vp9_fix_last_timestamp_| with the most recent timestamp.
620 if (vp9_fix_last_timestamp_ == -1)
621 vp9_fix_last_timestamp_ = frame.timestamp;
622 if (AheadOf<uint32_t>(frame.timestamp, vp9_fix_last_timestamp_))
623 vp9_fix_last_timestamp_ = frame.timestamp;
624
625 uint16_t fixed_pid = Add<kPicIdLength>(*picture_id, vp9_fix_pid_offset_);
626 if (vp9_fix_last_picture_id_ == -1)
627 vp9_fix_last_picture_id_ = *picture_id;
628
629 int16_t fixed_tl0 = kNoTl0PicIdx;
630 if (*tl0_pic_idx != kNoTl0PicIdx) {
631 fixed_tl0 = Add<kTl0PicIdLength>(*tl0_pic_idx, vp9_fix_tl0_pic_idx_offset_);
632 // Update |vp9_fix_last_tl0_pic_idx_| with the most recent tl0 pic index.
633 if (vp9_fix_last_tl0_pic_idx_ == -1)
634 vp9_fix_last_tl0_pic_idx_ = *tl0_pic_idx;
635 if (AheadOf<uint8_t>(fixed_tl0, vp9_fix_last_tl0_pic_idx_))
636 vp9_fix_last_tl0_pic_idx_ = fixed_tl0;
637 }
638
639 bool has_jumped = DetectVp9PicIdJump(fixed_pid, fixed_tl0, frame.timestamp);
640 if (!has_jumped)
641 has_jumped = DetectVp9Tl0PicIdxJump(fixed_tl0, frame.timestamp);
642
643 if (has_jumped) {
644 // First we calculate the offset to get to the previous picture id, and then
645 // we add kMaxPid to avoid accidently referencing any previous
646 // frames that was inserted into the FrameBuffer.
647 vp9_fix_pid_offset_ = ForwardDiff<uint16_t, kPicIdLength>(
648 *picture_id, vp9_fix_last_picture_id_);
649 vp9_fix_pid_offset_ += kMaxPidDiff;
650
651 fixed_pid = Add<kPicIdLength>(*picture_id, vp9_fix_pid_offset_);
652 vp9_fix_last_picture_id_ = fixed_pid;
653 vp9_fix_jump_timestamp_ = frame.timestamp;
654 gof_info_.clear();
655
656 vp9_fix_tl0_pic_idx_offset_ =
657 ForwardDiff<uint8_t>(*tl0_pic_idx, vp9_fix_last_tl0_pic_idx_);
658 vp9_fix_tl0_pic_idx_offset_ += kMaxGofSaved;
659 fixed_tl0 = Add<kTl0PicIdLength>(*tl0_pic_idx, vp9_fix_tl0_pic_idx_offset_);
660 vp9_fix_last_tl0_pic_idx_ = fixed_tl0;
661 }
662
663 // Update |vp9_fix_last_picture_id_| with the most recent picture id.
664 if (AheadOf<uint16_t, kPicIdLength>(fixed_pid, vp9_fix_last_picture_id_))
665 vp9_fix_last_picture_id_ = fixed_pid;
666
667 *picture_id = fixed_pid;
668 *tl0_pic_idx = fixed_tl0;
669
670 return false;
671 }
672
673 bool RtpFrameReferenceFinder::DetectVp9PicIdJump(int fixed_pid,
674 int fixed_tl0,
675 uint32_t timestamp) const {
676 // Test if there has been a jump backwards in the picture id.
677 if (AheadOrAt<uint32_t>(timestamp, vp9_fix_last_timestamp_) &&
678 AheadOf<uint16_t, kPicIdLength>(vp9_fix_last_picture_id_, fixed_pid)) {
679 return true;
680 }
681
682 // Test if we have jumped forward too much. The reason we have to do this
683 // is because the FrameBuffer holds history of old frames and inserting
684 // frames with a much advanced picture id can result in the frame buffer
685 // holding more than half of the interval of picture ids.
686 if (AheadOrAt<uint32_t>(timestamp, vp9_fix_last_timestamp_) &&
687 ForwardDiff<uint16_t, kPicIdLength>(vp9_fix_last_picture_id_, fixed_pid) >
688 128) {
689 return true;
690 }
691
692 // Special case where the picture id jump forward but not by much and the
693 // tl0 jumps to the id of an already saved gof for that id. In order to
694 // detect this we check if the picture id span over the length of the GOF.
695 if (fixed_tl0 != kNoTl0PicIdx) {
696 auto info_it = gof_info_.find(fixed_tl0);
697 if (info_it != gof_info_.end()) {
698 int last_pid_gof_idx_0 =
699 Subtract<kPicIdLength>(info_it->second.last_picture_id,
700 info_it->second.last_picture_id %
701 info_it->second.gof->num_frames_in_gof);
702 int pif_gof_end = Add<kPicIdLength>(
703 last_pid_gof_idx_0, info_it->second.gof->num_frames_in_gof);
704 if (AheadOf<uint16_t, kPicIdLength>(fixed_pid, pif_gof_end))
705 return true;
706 }
707 }
708
709 return false;
710 }
711
712 bool RtpFrameReferenceFinder::DetectVp9Tl0PicIdxJump(int fixed_tl0,
713 uint32_t timestamp) const {
714 if (fixed_tl0 != kNoTl0PicIdx) {
715 // Test if there has been a jump backwards in tl0 pic index.
716 if (AheadOrAt<uint32_t>(timestamp, vp9_fix_last_timestamp_) &&
717 AheadOf<uint8_t>(vp9_fix_last_tl0_pic_idx_, fixed_tl0)) {
718 return true;
719 }
720
721 // Test if there has been a jump forward. If the jump forward results
722 // in the tl0 pic index for this frame to be considered smaller than the
723 // smallest item in |gof_info_| then we have jumped forward far enough to
724 // wrap.
725 if (!gof_info_.empty() &&
726 AheadOf<uint8_t>(gof_info_.begin()->first, fixed_tl0)) {
727 return true;
728 }
729 }
730 return false;
731 }
732
588 } // namespace video_coding 733 } // namespace video_coding
589 } // namespace webrtc 734 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698